- Blood: separated actor spawning from map loading.

This commit is contained in:
Christoph Oelckers 2021-12-03 22:19:28 +01:00
parent e543c70439
commit ec888c097c
4 changed files with 91 additions and 86 deletions

View file

@ -79,6 +79,71 @@ void EndLevel(void)
seqKillAll(); seqKillAll();
} }
TArray<DBloodActor*> SpawnActors(SpawnSpriteDef& sprites)
{
TArray<DBloodActor*> spawns(sprites.sprites.Size(), true);
initspritelists();
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
{
RemoveSpriteStat(i);
auto actor = &bloodActors[i];
spawns[i] = actor;
actor->Clear();
actor->s() = sprites.sprites[i];
if (sprites.sprites[i].extra > 0)
{
actor->addX();
actor->x() = sprites.xspr[i];
}
InsertSpriteSect(i, actor->s().sectnum);
InsertSpriteStat(i, actor->s().statnum);
}
Numsprites = spawns.Size();
return spawns;
}
void PropagateMarkerReferences(void)
{
BloodStatIterator it(kStatMarker);
while (auto actor = it.Next())
{
switch (actor->s().type)
{
case kMarkerOff:
case kMarkerAxis:
case kMarkerWarpDest:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker0 = actor;
continue;
}
}
}
break;
case kMarkerOn:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker1 = actor;
continue;
}
}
}
break;
}
DeleteSprite(actor);
}
}
void StartLevel(MapRecord* level, bool newgame) void StartLevel(MapRecord* level, bool newgame)
{ {
if (!level) return; if (!level) return;
@ -111,7 +176,8 @@ void StartLevel(MapRecord* level, bool newgame)
} }
} }
//drawLoadingScreen(); //drawLoadingScreen();
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsector, nullptr); SpawnSpriteDef sprites;
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsector, nullptr, sprites);
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
STAT_NewLevel(currentLevel->fileName); STAT_NewLevel(currentLevel->fileName);
wsrand(dbReadMapCRC(currentLevel->LabelName())); wsrand(dbReadMapCRC(currentLevel->LabelName()));
@ -119,23 +185,13 @@ void StartLevel(MapRecord* level, bool newgame)
gSecretMgr.Clear(); gSecretMgr.Clear();
automapping = 1; automapping = 1;
// Here is where later the actors must be spawned. // Here is where later the actors must be spawned.
auto actorlist = SpawnActors(sprites);
// get a sorted list of all actors as we need to run some init code in spawn order. (iterating bloodActors would actually do, but that won't last forever) PropagateMarkerReferences();
TArray<DBloodActor*> actorlist;
BloodSpriteIterator sit;
while (auto act = sit.Next())
{
actorlist.Push(act);
}
std::sort(actorlist.begin(), actorlist.end(), [](DBloodActor* a, DBloodActor* b) { return a->GetIndex() < b->GetIndex(); });
int modernTypesErased = 0; int modernTypesErased = 0;
for(unsigned i = 0; i < actorlist.Size(); i++) for (auto actor : actorlist)
{ {
auto actor = actorlist[i];
spritetype* pSprite = &actor->s(); spritetype* pSprite = &actor->s();
if (actor->exists() && actor->hasX()) if (actor->exists() && actor->hasX())
{ {

View file

@ -171,7 +171,6 @@ extern HitInfo gHitInfo;
using BloodStatIterator = TStatIterator<DBloodActor>; using BloodStatIterator = TStatIterator<DBloodActor>;
using BloodSectIterator = TSectIterator<DBloodActor>; using BloodSectIterator = TSectIterator<DBloodActor>;
using BloodSpriteIterator = TSpriteIterator<DBloodActor>; using BloodSpriteIterator = TSpriteIterator<DBloodActor>;
using BloodLinearSpriteIterator = TLinearSpriteIterator<DBloodActor>;
inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom) inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
{ {

View file

@ -244,47 +244,6 @@ void dbInit(void)
} }
} }
void PropagateMarkerReferences(void)
{
BloodStatIterator it(kStatMarker);
while (auto actor = it.Next())
{
switch (actor->s().type)
{
case kMarkerOff:
case kMarkerAxis:
case kMarkerWarpDest:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker0 = actor;
continue;
}
}
}
break;
case kMarkerOn:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker1 = actor;
continue;
}
}
}
break;
}
DeleteSprite(actor);
}
}
bool drawtile2048, encrypted; bool drawtile2048, encrypted;
MAPHEADER2 byte_19AE44; MAPHEADER2 byte_19AE44;
@ -384,8 +343,7 @@ struct walltypedisk
#pragma pack(pop) #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)
{ {
int16_t tpskyoff[256]; int16_t tpskyoff[256];
ClearAutomap(); ClearAutomap();
@ -728,21 +686,19 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
} }
} }
initspritelists();
leveltimer = mapHeader.numsprites; leveltimer = mapHeader.numsprites;
sprites.sprites.Resize(mapHeader.numsprites);
sprites.xspr.Resize(mapHeader.numsprites);
for (int i = 0; i < mapHeader.numsprites; i++) for (int i = 0; i < mapHeader.numsprites; i++)
{ {
RemoveSpriteStat(i);
spritetypedisk load; spritetypedisk load;
auto actor = &bloodActors[i];
actor->Clear();
spritetype* pSprite = &actor->s();
fr.Read(&load, sizeof(spritetypedisk)); // load into an intermediate buffer so that spritetype is no longer bound by file formats. fr.Read(&load, sizeof(spritetypedisk)); // load into an intermediate buffer so that spritetype is no longer bound by file formats.
if (encrypted) // What were these people thinking? :( if (encrypted) // What were these people thinking? :(
{ {
dbCrypt((char*)&load, sizeof(spritetypedisk), (gMapRev * sizeof(spritetypedisk)) | 0x7474614d); dbCrypt((char*)&load, sizeof(spritetypedisk), (gMapRev * sizeof(spritetypedisk)) | 0x7474614d);
} }
auto pSprite = &sprites.sprites[i];
pSprite->clear();
pSprite->x = LittleLong(load.x); pSprite->x = LittleLong(load.x);
pSprite->y = LittleLong(load.y); pSprite->y = LittleLong(load.y);
pSprite->z = LittleLong(load.z); pSprite->z = LittleLong(load.z);
@ -770,14 +726,11 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
pSprite->time = i; pSprite->time = i;
ValidateSprite(*pSprite); ValidateSprite(*pSprite);
InsertSpriteSect(i, pSprite->sectnum);
InsertSpriteStat(i, pSprite->statnum);
Numsprites++;
if (pSprite->extra > 0) if (pSprite->extra > 0)
{ {
char pBuffer[nXSpriteSize]; char pBuffer[nXSpriteSize];
actor->addX(); XSPRITE* pXSprite = &sprites.xspr[i];
XSPRITE* pXSprite = &actor->x(); *pXSprite = {};
int nCount; int nCount;
if (!encrypted) if (!encrypted)
{ {
@ -863,10 +816,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
gModernMap = true; gModernMap = true;
#endif #endif
} }
if ((sprite[i].cstat & 0x30) == 0x30)
{
sprite[i].cstat &= ~0x30;
}
} }
unsigned int nCRC = fr.ReadUInt32(); unsigned int nCRC = fr.ReadUInt32();
@ -874,7 +823,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
auto buffer = fr.Read(); auto buffer = fr.Read();
uint8_t md4[16]; uint8_t md4[16];
md4once(buffer.Data(), buffer.Size(), md4); md4once(buffer.Data(), buffer.Size(), md4);
G_LoadMapHack(mapname, md4, sprite, mapHeader.numsprites); G_LoadMapHack(mapname, md4, sprites.sprites.Data(), mapHeader.numsprites);
if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC) if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC)
{ {
@ -882,7 +831,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
} }
if (pCRC) if (pCRC)
*pCRC = nCRC; *pCRC = nCRC;
PropagateMarkerReferences();
if (encrypted) if (encrypted)
{ {
if (gMattId == 0x7474614d || gMattId == 0x4d617474) if (gMattId == 0x7474614d || gMattId == 0x4d617474)
@ -908,9 +856,9 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
switch (header.version & 0xff) switch (header.version & 0xff)
{ {
case 0: case 0:
for (int i = 0; i < numsectors; i++) for (auto& sect : sectors())
{ {
sectortype* pSector = &sector[i]; sectortype* pSector = &sect;
if (pSector->hasX()) if (pSector->hasX())
{ {
XSECTOR* pXSector = &pSector->xs(); XSECTOR* pXSector = &pSector->xs();
@ -932,9 +880,9 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
} }
[[fallthrough]]; [[fallthrough]];
case 1: case 1:
for (int i = 0; i < numsectors; i++) for (auto& sect : sectors())
{ {
sectortype* pSector = &sector[i]; sectortype* pSector = &sect;
if (pSector->hasX()) if (pSector->hasX())
{ {
XSECTOR* pXSector = &pSector->xs(); XSECTOR* pXSector = &pSector->xs();
@ -943,9 +891,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
} }
[[fallthrough]]; [[fallthrough]];
case 2: case 2:
for (int i = 0; i < kMaxSprites; i++)
{
}
break; break;
} }
@ -964,8 +909,9 @@ END_BLD_NS
// only used by the backup loader. // only used by the backup loader.
void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang) void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang)
{ {
Blood::SpawnSpriteDef sprites;
sectortype* sp; sectortype* sp;
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, NULL); Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, nullptr, sprites);
Blood::dbInit(); // clean up immediately. Blood::dbInit(); // clean up immediately.
} }

View file

@ -74,7 +74,11 @@ struct MAPHEADER2 {
#pragma pack(pop) #pragma pack(pop)
extern unsigned int gStatCount[kMaxStatus + 1];; struct SpawnSpriteDef
{
TArray<spritetype> sprites;
TArray<XSPRITE> xspr;
};
extern bool drawtile2048, encrypted; extern bool drawtile2048, encrypted;
extern MAPHEADER2 byte_19AE44; extern MAPHEADER2 byte_19AE44;
@ -125,7 +129,7 @@ int ChangeSpriteStat(int nSprite, int nStatus);
void dbInit(void); void dbInit(void);
void PropagateMarkerReferences(void); void PropagateMarkerReferences(void);
unsigned int dbReadMapCRC(const char *pPath); unsigned int dbReadMapCRC(const char *pPath);
void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC); void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, SpawnSpriteDef& sprites);
END_BLD_NS END_BLD_NS