diff --git a/source/build/include/build.h b/source/build/include/build.h index 3f2680a5a..a9eabffa2 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -349,11 +349,18 @@ int32_t engineInit(void); void engineUnInit(void); void initspritelists(void); +struct SpawnSpriteDef +{ + TArray sprites; + TArray sprext; +}; + + void allocateMapArrays(int numsprites); void ValidateSprite(spritetype& spr); void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int *dacursectnum); void loadMapBackup(const char* filename); -void G_LoadMapHack(const char* filename, const unsigned char*, spritetype*, int); +void G_LoadMapHack(const char* filename, const unsigned char*, SpawnSpriteDef& sprites); void videoSetCorrectedAspect(); void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 4563759c4..406c971c2 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -6,6 +6,7 @@ #include "engine_priv.h" #include "polymost.h" #include "mdsprite.h" +#include "coreactor.h" #include "palette.h" #include "textures.h" @@ -1553,9 +1554,13 @@ void updateModelInterpolation() omdtims = mdtims; mdtims = I_msTime(); - for (int i = 0; i < MAXSPRITES; ++i) - if ((mdpause && spriteext[i].mdanimtims) || (spriteext[i].flags & SPREXT_NOMDANIM)) - spriteext[i].mdanimtims += mdtims - omdtims; + TSpriteIterator it; + while (auto actor = it.Next()) + { + auto& sx = actor->sx(); + if ((mdpause && sx.mdanimtims) || (sx.flags & SPREXT_NOMDANIM)) + sx.mdanimtims += mdtims - omdtims; + } } #endif diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 756d956c9..0bdd05e01 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -22,6 +22,16 @@ public: return sprite[index]; } + spriteext_t& sx() const + { + return spriteext[index]; + } + + spritesmooth_t& sm() const + { + return spritesmooth[index]; + } + int GetIndex() const { // For error printing only! This is only identical with the sprite index for items spawned at map start. diff --git a/source/core/maphack.cpp b/source/core/maphack.cpp index 6c51f6ea0..20a3802b2 100644 --- a/source/core/maphack.cpp +++ b/source/core/maphack.cpp @@ -48,11 +48,12 @@ void AddUserMapHack(usermaphack_t& mhk) usermaphacks.Push(mhk); } -static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numsprites) +static int32_t LoadMapHack(const char *filename, SpawnSpriteDef& sprites) { int currentsprite = -1; int currentwall = -1; int currentsector = -1; + int numsprites = sprites.sprites.Size(); FScanner sc; int lump = fileSystem.FindFile(filename); @@ -61,6 +62,8 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr return -1; } sc.OpenLumpNum(lump); + sprites.sprext.Resize(numsprites); + memset(sprites.sprext.Data(), 0, sizeof(spriteext_t) * sprites.sprext.Size()); while (sc.GetString()) { @@ -157,7 +160,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr { if (currentsprite != -1 && validateSprite()) { - sprites[currentsprite].sectnum = sc.Number; + sprites.sprites[currentsprite].sectnum = sc.Number; } } } @@ -171,7 +174,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr } else if (currentsprite != -1 && validateSprite()) { - sprites[currentsprite].picnum = sc.Number; + sprites.sprites[currentsprite].picnum = sc.Number; } } } @@ -222,7 +225,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr } else if (currentsprite != -1 && validateSprite()) { - sprites[currentsprite].cstat &= ~sc.Number; + sprites.sprites[currentsprite].cstat &= ~sc.Number; } } } @@ -236,7 +239,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr } else if (currentsprite != -1 && validateSprite()) { - sprites[currentsprite].cstat |= sc.Number; + sprites.sprites[currentsprite].cstat |= sc.Number; } } } @@ -250,7 +253,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr } else if (currentsprite != -1 && validateSprite()) { - sprites[currentsprite].lotag = sc.Number; + sprites.sprites[currentsprite].lotag = sc.Number; } } } @@ -262,73 +265,73 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr else if (sc.Compare("angleoff") || sc.Compare("angoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].angoff = (int16_t)sc.Number; + sprites.sprext[currentsprite].angoff = (int16_t)sc.Number; } else if (sc.Compare("notmd") || sc.Compare("notmd2") || sc.Compare("notmd3")) { if (validateSprite()) - spriteext[currentsprite].flags |= SPREXT_NOTMD; + sprites.sprext[currentsprite].flags |= SPREXT_NOTMD; } else if (sc.Compare("nomdanim") || sc.Compare("nomd2anim") || sc.Compare("nomd3anim")) { if (validateSprite()) - spriteext[currentsprite].flags |= SPREXT_NOMDANIM; + sprites.sprext[currentsprite].flags |= SPREXT_NOMDANIM; } else if (sc.Compare("pitch")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].pitch = (int16_t)sc.Number; + sprites.sprext[currentsprite].pitch = (int16_t)sc.Number; } else if (sc.Compare("roll")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].roll = (int16_t)sc.Number; + sprites.sprext[currentsprite].roll = (int16_t)sc.Number; } else if (sc.Compare("mdxoff") || sc.Compare("mdpivxoff") || sc.Compare("mdpivotxoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].pivot_offset.x = sc.Number; + sprites.sprext[currentsprite].pivot_offset.x = sc.Number; } else if (sc.Compare("mdyoff") || sc.Compare("mdpivyoff") || sc.Compare("mdpivotyoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].pivot_offset.y = sc.Number; + sprites.sprext[currentsprite].pivot_offset.y = sc.Number; } else if (sc.Compare("mdzoff") || sc.Compare("mdpivzoff") || sc.Compare("mdpivotzoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].pivot_offset.z = sc.Number; + sprites.sprext[currentsprite].pivot_offset.z = sc.Number; } else if (sc.Compare("mdposxoff") || sc.Compare("mdpositionxoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].position_offset.x = sc.Number; + sprites.sprext[currentsprite].position_offset.x = sc.Number; } else if (sc.Compare("mdposyoff") || sc.Compare("mdpositionyoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].position_offset.x = sc.Number; + sprites.sprext[currentsprite].position_offset.x = sc.Number; } else if (sc.Compare("mdposzoff") || sc.Compare("mdpositionzoff")) { if (sc.CheckNumber() && validateSprite()) - spriteext[currentsprite].position_offset.x = sc.Number; + sprites.sprext[currentsprite].position_offset.x = sc.Number; } else if (sc.Compare("away1")) { if (validateSprite()) - spriteext[currentsprite].flags |= SPREXT_AWAY1; + sprites.sprext[currentsprite].flags |= SPREXT_AWAY1; } else if (sc.Compare("away2")) { if (validateSprite()) - spriteext[currentsprite].flags |= SPREXT_AWAY2; + sprites.sprext[currentsprite].flags |= SPREXT_AWAY2; } else if (sc.Compare("mhkreset")) { if (validateSprite()) { - auto& sx = spriteext[currentsprite]; + auto& sx = sprites.sprext[currentsprite]; sx.angoff = 0; sx.flags &= ~(SPREXT_NOTMD | SPREXT_NOMDANIM | SPREXT_AWAY1 | SPREXT_AWAY2); sx.pitch = 0; @@ -377,7 +380,7 @@ static int32_t LoadMapHack(const char *filename, spritetype* sprites, int numspr return 0; } -void G_LoadMapHack(const char* filename, const unsigned char* md4, spritetype* sprites, int numsprites) +void G_LoadMapHack(const char* filename, const unsigned char* md4, SpawnSpriteDef& sprites) { hw_ClearSplitSector(); blockingpairs.Reset(); @@ -387,16 +390,16 @@ void G_LoadMapHack(const char* filename, const unsigned char* md4, spritetype* s { internal.AppendFormat("%02x", md4[j]); } - LoadMapHack(internal + ".mhk", sprites, numsprites); + LoadMapHack(internal + ".mhk", sprites); FString hack = StripExtension(filename) + ".mhk"; - if (LoadMapHack(hack, sprites, numsprites)) + if (LoadMapHack(hack, sprites)) { for (auto& mhk : usermaphacks) { if (!memcmp(md4, mhk.md4, 16)) { - LoadMapHack(mhk.mhkfile, sprites, numsprites); + LoadMapHack(mhk.mhkfile, sprites); } } } diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index efc4f917f..844f01922 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -429,6 +429,7 @@ void allocateMapArrays(int numsprites) void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int* cursectnum) { + SpawnSpriteDef sprites; inputState.ClearAllInput(); FileReader fr = fileSystem.OpenFileReader(filename); @@ -459,6 +460,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, // Now that we know the map's size, set up the globals. allocateMapArrays(numsprites); initspritelists(); // may not be used in Blood! + sprites.sprites.Resize(numsprites); // Now load the actual data. fr.Seek(sectorpos, FileReader::SeekSet); @@ -513,7 +515,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, auto buffer = fr.Read(); unsigned char md4[16]; md4once(buffer.Data(), buffer.Size(), md4); - G_LoadMapHack(filename, md4, sprite, numsprites); + G_LoadMapHack(filename, md4, sprites); setWallSectors(); hw_BuildSections(); sectorGeometry.SetSize(numsections); diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index 8026080e1..4e09eb0fa 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -79,7 +79,7 @@ void EndLevel(void) seqKillAll(); } -TArray SpawnActors(SpawnSpriteDef& sprites) +TArray SpawnActors(BloodSpawnSpriteDef& sprites) { TArray spawns(sprites.sprites.Size(), true); initspritelists(); @@ -90,6 +90,10 @@ TArray SpawnActors(SpawnSpriteDef& sprites) spawns[i] = actor; actor->Clear(); actor->s() = sprites.sprites[i]; + if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i]; + else actor->sx() = {}; + actor->sm() = {}; + if (sprites.sprites[i].extra > 0) { actor->addX(); @@ -176,7 +180,7 @@ void StartLevel(MapRecord* level, bool newgame) } } //drawLoadingScreen(); - SpawnSpriteDef sprites; + BloodSpawnSpriteDef sprites; dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsector, nullptr, sprites); SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); STAT_NewLevel(currentLevel->fileName); diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 42c80a360..d464382a4 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -343,7 +343,7 @@ struct walltypedisk #pragma pack(pop) -void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, SpawnSpriteDef& sprites) +void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, BloodSpawnSpriteDef& sprites) { int16_t tpskyoff[256]; ClearAutomap(); @@ -823,7 +823,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect auto buffer = fr.Read(); uint8_t md4[16]; md4once(buffer.Data(), buffer.Size(), md4); - G_LoadMapHack(mapname, md4, sprites.sprites.Data(), mapHeader.numsprites); + G_LoadMapHack(mapname, md4, sprites); if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC) { @@ -909,7 +909,7 @@ END_BLD_NS // only used by the backup loader. void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang) { - Blood::SpawnSpriteDef sprites; + Blood::BloodSpawnSpriteDef sprites; sectortype* sp; Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, nullptr, sprites); Blood::dbInit(); // clean up immediately. diff --git a/source/games/blood/src/db.h b/source/games/blood/src/db.h index d85bfdd13..b685829a0 100644 --- a/source/games/blood/src/db.h +++ b/source/games/blood/src/db.h @@ -74,12 +74,6 @@ struct MAPHEADER2 { #pragma pack(pop) -struct SpawnSpriteDef -{ - TArray sprites; - TArray xspr; -}; - extern bool drawtile2048, encrypted; extern MAPHEADER2 byte_19AE44; @@ -101,6 +95,11 @@ template void GetSpriteExtents(T const * const pSprite, int *top, in } } +struct BloodSpawnSpriteDef : public SpawnSpriteDef +{ + TArray xspr; +}; + #ifdef POLYMER #pragma pack(push, 1) struct PolymerLight_t { @@ -129,7 +128,7 @@ int ChangeSpriteStat(int nSprite, int nStatus); void dbInit(void); void PropagateMarkerReferences(void); unsigned int dbReadMapCRC(const char *pPath); -void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, SpawnSpriteDef& sprites); +void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, BloodSpawnSpriteDef& sprites); END_BLD_NS diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index b7b3875a0..1d269e79c 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -124,8 +124,8 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8 if (show2dsector[s->sectnum]) act->s->cstat2 |= CSTAT2_SPRITE_MAPPED; else act->s->cstat2 &= ~CSTAT2_SPRITE_MAPPED; - spriteext[i] = {}; - spritesmooth[i] = {}; + act->sx() = {}; + act->sm() = {}; return act; }