From edd5bbc65ebbb49cab45ece5aa996d727ae7dacb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Sep 2021 12:25:52 +0200 Subject: [PATCH] - split off the extended sprite flags into their own word. Some code overwrites the cstat field entirely (thanks Duke, for being sloppy with this...!) Also moving the mapped flag in there from the global bit array. --- source/build/include/buildtypes.h | 12 ++++++++---- source/build/src/clip.cpp | 4 ++-- source/build/src/engine.cpp | 2 +- source/build/src/polymost.cpp | 4 ++-- source/core/automap.cpp | 5 +---- source/core/automap.h | 1 - source/core/rendering/scene/hw_drawinfo.cpp | 2 +- source/core/rendering/scene/hw_sprites.cpp | 2 +- source/core/savegamehelp.cpp | 1 + source/games/blood/src/actor.cpp | 4 ++-- source/games/blood/src/animatesprite.cpp | 4 ++-- source/games/blood/src/callback.cpp | 2 +- source/games/blood/src/nnexts.cpp | 7 ++++--- source/games/blood/src/player.cpp | 2 +- source/games/duke/src/actors.cpp | 9 +++++---- source/games/duke/src/spawn.cpp | 6 +++--- source/games/sw/src/draw.cpp | 2 +- 17 files changed, 36 insertions(+), 33 deletions(-) diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index e26ffa868fd..7fa6d6ec2b5 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -185,10 +185,13 @@ enum CSTAT_SPRITE_RESERVED5 = 1u<<14u, // used by Duke 3D (Polymer), Shadow Warrior, Blood CSTAT_SPRITE_INVISIBLE = 1u<<15u, +}; - // Raze extensions, using the higher bits to avoid conflitcs with the reserved and undocumented bits above. - CSTAT_SPRITE_MDLROTATE = 1u<<16u, // Only for tsprites: rotate if this is a model or voxel. - CSTAT_SPRITE_NOFIND = 1u<<17u, // Invisible to neartag and hitscan +enum +{ + CSTAT2_SPRITE_MDLROTATE = 1, // Only for tsprites: rotate if this is a model or voxel. + CSTAT2_SPRITE_NOFIND = 2, // Invisible to neartag and hitscan + CSTAT2_SPRITE_MAPPED = 4, // sprite was mapped for automap }; enum @@ -245,7 +248,7 @@ struct spritetype }; vec3_t opos; }; - uint32_t cstat; + uint16_t cstat; int16_t picnum; int8_t shade; uint8_t pal, clipdist, blend; @@ -268,6 +271,7 @@ struct spritetype int16_t detail; int time; int16_t wall; + uint16_t cstat2; int8_t wdist; diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 663acdd3d8d..165f7122c28 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -1081,7 +1081,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum, const int32_t cstat = sprite[j].cstat; int32_t daz, daz2; - if (cstat & CSTAT_SPRITE_NOFIND) continue; + if (sprite[j].cstat2 & CSTAT2_SPRITE_NOFIND) continue; if (cstat&dasprclipmask) { int32_t clipyou = 0; @@ -1417,7 +1417,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32 auto const spr = (uspriteptr_t)&sprite[z]; uint32_t const cstat = spr->cstat; - if (cstat & CSTAT_SPRITE_NOFIND) + if (spr->cstat2 & CSTAT2_SPRITE_NOFIND) continue; #ifdef USE_OPENGL diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index c7bda86987c..56ef8bfa542 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -1149,7 +1149,7 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, { auto const spr = (uspriteptr_t)&sprite[z]; - if (spr->cstat & CSTAT_SPRITE_NOFIND) + if (spr->cstat2 & CSTAT2_SPRITE_NOFIND) continue; if (blacklist_sprite_func && blacklist_sprite_func(z)) continue; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 8dfa4dc5912..7ce1cb48688 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -3253,7 +3253,7 @@ void polymost_drawsprite(int32_t snum) } if ((unsigned)spritenum < MAXSPRITES) - show2dsprite.Set(spritenum); + sprite[spritenum].cstat2 |= CSTAT2_SPRITE_MAPPED; _drawsprite_return: ; @@ -3807,7 +3807,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate) if ((tspr->cstat & 48) == 32) return 0; - if ((tspr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate) + if ((tspr->cstat2 & CSTAT2_SPRITE_MDLROTATE) || rotate) { int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16); tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common. diff --git a/source/core/automap.cpp b/source/core/automap.cpp index b28645f9a36..56cf355ebf8 100644 --- a/source/core/automap.cpp +++ b/source/core/automap.cpp @@ -61,7 +61,6 @@ bool automapping; bool gFullMap; FixedBitArray show2dsector; FixedBitArray show2dwall; -FixedBitArray show2dsprite; static int x_min_bound = INT_MAX, y_min_bound, x_max_bound, y_max_bound; CVAR(Color, am_twosidedcolor, 0xaaaaaa, CVAR_ARCHIVE) @@ -269,7 +268,6 @@ void SerializeAutomap(FSerializer& arc) // Only store what's needed. Unfortunately for sprites it is not that easy .SerializeMemory("mappedsectors", show2dsector.Storage(), (numsectors + 7) / 8) .SerializeMemory("mappedwalls", show2dwall.Storage(), (numwalls + 7) / 8) - .SerializeMemory("mappedsprites", show2dsprite.Storage(), MAXSPRITES / 8) .EndObject(); } } @@ -285,7 +283,6 @@ void ClearAutomap() { show2dsector.Zero(); show2dwall.Zero(); - show2dsprite.Zero(); x_min_bound = INT_MAX; } @@ -623,7 +620,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang) vertices.Resize(4); for (auto sn : floorsprites) { - if (!gFullMap && !show2dsprite[sn]) continue; + if (!gFullMap && !(sprite[sn].cstat2 & CSTAT2_SPRITE_MAPPED)) continue; auto spr = &sprite[sn]; vec2_t pp[4]; GetFlatSpritePosition(spr, spr->pos.vec2, pp, true); diff --git a/source/core/automap.h b/source/core/automap.h index 14c10e0b12f..ad8731440c3 100644 --- a/source/core/automap.h +++ b/source/core/automap.h @@ -12,7 +12,6 @@ extern bool automapping; extern bool gFullMap; extern FixedBitArray show2dsector; extern FixedBitArray show2dwall; -extern FixedBitArray show2dsprite; void SerializeAutomap(FSerializer& arc); void ClearAutomap(); diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 7e84bbde952..848e6fa0823 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -282,7 +282,7 @@ void HWDrawInfo::DispatchSprites() continue; if ((unsigned)spritenum < MAXSPRITES) - show2dsprite.Set(spritenum); + sprite[spritenum].cstat2 |= CSTAT2_SPRITE_MAPPED; setgotpic(tilenum); diff --git a/source/core/rendering/scene/hw_sprites.cpp b/source/core/rendering/scene/hw_sprites.cpp index a29c9f16f50..d9223194e97 100644 --- a/source/core/rendering/scene/hw_sprites.cpp +++ b/source/core/rendering/scene/hw_sprites.cpp @@ -459,7 +459,7 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, se voxel = vox; auto ang = spr->ang + sprext->angoff; - if ((spr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate) + if ((spr->cstat2 & CSTAT2_SPRITE_MDLROTATE) || rotate) { int myclock = (PlayClock << 3) + MulScale(4 << 3, (int)di->Viewpoint.TicFrac, 16); ang = (ang + myclock) & 2047; diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index c3fa929fbba..bbeca499960 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -465,6 +465,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, spritetype &c, spritet ("extra", c.extra, def->extra) ("detail", c.detail, def->detail) ("time", c.time, def->time) + ("cstat2", c.cstat2, def->cstat2) .EndObject(); } return arc; diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index f0f5caabfef..4c46c366fbf 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -6525,7 +6525,7 @@ DBloodActor* actSpawnThing(int nSector, int x, int y, int z, int nThingType) pSprite->pal = pThingInfo->pal; if (pThingInfo->xrepeat) pSprite->xrepeat = pThingInfo->xrepeat; if (pThingInfo->yrepeat) pSprite->yrepeat = pThingInfo->yrepeat; - show2dsprite.Set(actor->GetIndex()); + pSprite->cstat2 |= CSTAT2_SPRITE_MAPPED; switch (nThingType) { case kThingVoodooHead: @@ -6741,7 +6741,7 @@ DBloodActor* actFireMissile(DBloodActor* actor, int a2, int a3, int a4, int a5, } auto spawned = actSpawnSprite(pSprite->sectnum, x, y, z, 5, 1); spritetype* pMissile = &spawned->s(); - show2dsprite.Set(spawned->GetIndex()); + pMissile->cstat2 |= CSTAT2_SPRITE_MAPPED; pMissile->type = nType; pMissile->shade = pMissileInfo->shade; pMissile->pal = 0; diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 61227ae76a2..c6fff9c1507 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -660,7 +660,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int int const nVoxel = tiletovox[pTSprite->picnum]; if (nVoxel != -1 && (picanm[nRootTile].extra & 7) == 7) - pTSprite->cstat |= CSTAT_SPRITE_MDLROTATE; // per-sprite rotation setting. + pTSprite->cstat2 |= CSTAT2_SPRITE_MDLROTATE; // per-sprite rotation setting. } if ((pTSprite->cstat&48) != 48 && hw_models && !(spriteext[nSprite].flags&SPREXT_NOTMD)) @@ -675,7 +675,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int pTSprite->xoffset += tileLeftOffset(nAnimTile); if ((picanm[nRootTile].extra&7) == 7) - pTSprite->cstat |= CSTAT_SPRITE_MDLROTATE; // per-sprite rotation setting. + pTSprite->cstat2 |= CSTAT2_SPRITE_MDLROTATE; // per-sprite rotation setting. } } diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index c51b0d11b88..b4e8b4d7897 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -608,7 +608,7 @@ void sub_76A08(DBloodActor *actor, spritetype *pSprite2, PLAYER *pPlayer) // ??? ChangeActorSect(actor, pSprite2->sectnum); sfxPlay3DSound(pSprite2, 201, -1, 0); actor->xvel = actor->yvel = actor->zvel = 0; - viewBackupSpriteLoc(actor->GetIndex(), pSprite); + viewBackupSpriteLoc(actor); if (pPlayer) { playerResetInertia(pPlayer); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index c44c127a325..f91840bbd18 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -1267,10 +1267,10 @@ void nnExtProcessSuperSprites() pXSightSpr->isTriggered) continue; // don't process locked or triggered sprites // sprite is drawn for one of players - if ((pXSightSpr->unused3 & kTriggerSpriteScreen) && show2dsprite[gSightSpritesList[i]->GetIndex()]) + if ((pXSightSpr->unused3 & kTriggerSpriteScreen) && (gSightSpritesList[i]->s().cstat2 & CSTAT2_SPRITE_MAPPED)) { trTriggerSprite(gSightSpritesList[i], kCmdSpriteSight); - show2dsprite.Clear(gSightSpritesList[i]->GetIndex()); + gSightSpritesList[i]->s().cstat2 &= ~CSTAT2_SPRITE_MAPPED; continue; } @@ -2847,7 +2847,7 @@ void usePropertiesChanger(DBloodActor* sourceactor, short objType, int objIndex, // set new cstat if ((pSource->flags & kModernTypeFlag1)) pSprite->cstat |= pXSource->data4; // relative - else pSprite->cstat = pXSource->data4; // absolute + else pSprite->cstat = pXSource->data4 & 0xffff; // absolute // and handle exceptions if ((old & 0x1000) && !(pSprite->cstat & 0x1000)) pSprite->cstat |= 0x1000; //kSpritePushable @@ -9088,6 +9088,7 @@ void callbackUniMissileBurst(DBloodActor* actor, int) // 22 pBurst->shade = pSprite->shade; pBurst->picnum = pSprite->picnum; + pBurst->cstat = pSprite->cstat; if ((pBurst->cstat & CSTAT_SPRITE_BLOCK)) { diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index dd102dbbdc9..757426f4a5f 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -672,7 +672,7 @@ void playerStart(int nPlayer, int bNewLevel) playerResetPosture(pPlayer); seqSpawn(pDudeInfo->seqStartID, actor, -1); if (pPlayer == gMe) - show2dsprite.Set(actor->GetIndex()); + actor->s().cstat2 |= CSTAT2_SPRITE_MAPPED; int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z -= bottom - pSprite->z; diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index b5b5f87fd54..d05c9b6d149 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -1009,7 +1009,8 @@ void movemasterswitch(DDukeActor *actor, int spectype1, int spectype2) // This originally depended on undefined behavior as the deleted sprite was still used for the sound // with no checking if it got reused in the mean time. spri->picnum = 0; // give it a picnum without any behavior attached, just in case - spri->cstat |= CSTAT_SPRITE_INVISIBLE|CSTAT_SPRITE_NOFIND; + spri->cstat |= CSTAT_SPRITE_INVISIBLE; + spri->cstat2 |= CSTAT2_SPRITE_NOFIND; changeactorstat(actor, STAT_REMOVED); } } @@ -4955,10 +4956,10 @@ void getglobalz(DDukeActor* actor) zr = 4; else zr = 127; - auto cc = s->cstat; - s->cstat |= CSTAT_SPRITE_NOFIND; // don't clip against self. getzrange cannot detect this because it only receives a coordinate. + auto cc = s->cstat2; + s->cstat2 |= CSTAT2_SPRITE_NOFIND; // don't clip against self. getzrange cannot detect this because it only receives a coordinate. getzrange_ex(s->x, s->y, s->z - (FOURSLEIGHT), s->sectnum, &actor->ceilingz, hz, &actor->floorz, lz, zr, CLIPMASK0); - s->cstat = cc; + s->cstat2 = cc; if( lz.type == kHitSprite && (lz.actor->s->cstat&48) == 0 ) { diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index c6ffa77e189..c9909c8378f 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -119,8 +119,8 @@ DDukeActor* EGS(short whatsect, int s_x, int s_y, int s_z, short s_pn, signed ch s->hitag = 0; } - if (show2dsector[s->sectnum]) show2dsprite.Set(i); - else show2dsprite.Clear(i); + if (show2dsector[s->sectnum]) act->s->cstat2 |= CSTAT2_SPRITE_MAPPED; + else act->s->cstat2 &= ~CSTAT2_SPRITE_MAPPED; spriteext[i] = {}; spritesmooth[i] = {}; @@ -995,7 +995,7 @@ void spawneffector(DDukeActor* actor) if (!found) { sp->picnum = 0; - sp->cstat = CSTAT_SPRITE_NOFIND; + sp->cstat2 = CSTAT2_SPRITE_NOFIND; changeactorsect(actor, STAT_REMOVED); Printf("Found lonely Sector Effector (lotag 0) at (%d,%d)\n", sp->x, sp->y); return; diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index 9e2a74bc0b8..7b9e450fff4 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -1736,7 +1736,7 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang, goto SHOWSPRITE; } } - if (gFullMap || show2dsprite[j]) + if (gFullMap || (sprite[j].cstat2 & CSTAT2_SPRITE_MAPPED)) { SHOWSPRITE: spr = &sprite[j];