From 8c298de11431c8f18bc024b207f2f6855ad45c2d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Dec 2021 13:02:38 +0100 Subject: [PATCH] - Duke: replaced DukeLinearSpriteIterator and explicit loops over the sprite[] array. --- source/games/duke/src/duke3d.h | 2 +- source/games/duke/src/dukeactor.h | 1 - source/games/duke/src/funct.h | 16 ++++---- source/games/duke/src/premap.cpp | 23 +++++++++-- source/games/duke/src/premap_d.cpp | 28 +++++++------- source/games/duke/src/premap_r.cpp | 59 +++++++++++++++-------------- source/games/duke/src/sectors_d.cpp | 2 +- source/games/duke/src/sectors_r.cpp | 11 ++++-- source/games/duke/src/spawn.cpp | 33 ++++++++-------- source/games/duke/src/spawn_d.cpp | 4 +- source/games/duke/src/spawn_r.cpp | 4 +- source/games/duke/src/types.h | 3 +- 12 files changed, 104 insertions(+), 82 deletions(-) diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 978e1cc20..c36768701 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -85,7 +85,7 @@ struct Dispatcher bool (*checkhitceiling)(sectortype* sn); void (*checkhitsprite)(DDukeActor* i, DDukeActor* sn); void (*checksectors)(int low); - DDukeActor* (*spawninit)(DDukeActor* actj, DDukeActor* act); + DDukeActor* (*spawninit)(DDukeActor* actj, DDukeActor* act, TArray* actors); bool (*ceilingspace)(sectortype* sectp); bool (*floorspace)(sectortype* sectp); diff --git a/source/games/duke/src/dukeactor.h b/source/games/duke/src/dukeactor.h index 4f4a902f6..66cc9ae1a 100644 --- a/source/games/duke/src/dukeactor.h +++ b/source/games/duke/src/dukeactor.h @@ -8,7 +8,6 @@ BEGIN_DUKE_NS using DukeStatIterator = TStatIterator; using DukeSectIterator = TSectIterator; using DukeSpriteIterator = TSpriteIterator; -using DukeLinearSpriteIterator = TLinearSpriteIterator; inline DDukeActor* player_struct::GetActor() { diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index a5aba7736..c7424dfa4 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -180,14 +180,14 @@ void checkplayerhurt_d(struct player_struct* p, const Collision& coll); void checkplayerhurt_r(struct player_struct* p, const Collision& coll); DDukeActor* dospawnsprite(DDukeActor* actj, int pn); -void spriteinit_d(int); -void spriteinit_r(int); -DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act); -DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act); +void spriteinit_d(DDukeActor*); +void spriteinit_r(DDukeActor*); +DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* actors); +DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* actors); void addspritetodelete(int spnum=0); void checkavailinven(struct player_struct* p); -int initspriteforspawn(int spn, const std::initializer_list &excludes); +bool initspriteforspawn(DDukeActor* spn, const std::initializer_list &excludes); void spawninitdefault(DDukeActor* actj, DDukeActor* act); void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam); int spawnbloodpoolpart1(DDukeActor* acti); @@ -196,7 +196,7 @@ void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell); void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE); void initwaterdrip(DDukeActor* actj, DDukeActor* acti); int initreactor(DDukeActor* actj, DDukeActor* acti, bool isrecon); -void spawneffector(DDukeActor* actor); +void spawneffector(DDukeActor* actor, TArray* actors); int startrts(int lumpNum, int localPlayer); void pickrandomspot(int pn); @@ -224,8 +224,8 @@ void setgamepalette(int palid); void resetmys(); void resettimevars(); bool setnextmap(bool checksecretexit); -void prelevel_d(int g); -void prelevel_r(int g); +void prelevel_d(int g, TArray&); +void prelevel_r(int g, TArray&); void e4intro(const CompletionFunc& completion); void exitlevel(MapRecord *next); void enterlevel(MapRecord* mi, int gm); diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index bc0b9ea07..972a26f99 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -929,6 +929,23 @@ static void SpawnPortals() mergePortals(); } +//--------------------------------------------------------------------------- +// +// this is just a dummy for now to provide the intended setup. +// +//--------------------------------------------------------------------------- + +static TArray spawnactors(SpawnSpriteDef& spawns) +{ + insertAllSprites(spawns); + TArray actorlist; + for(unsigned i = 0; i < spawns.sprites.Size(); i++) + { + if (hittype[i].exists()) actorlist.Push(&hittype[i]); + } + return actorlist; +} + //--------------------------------------------------------------------------- // // @@ -956,10 +973,10 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode) memset(gotpic, 0, sizeof(gotpic)); - insertAllSprites(sprites); + auto actorlist = spawnactors(sprites); - if (isRR()) prelevel_r(gamemode); - else prelevel_d(gamemode); + if (isRR()) prelevel_r(gamemode, actorlist); + else prelevel_d(gamemode, actorlist); SpawnPortals(); diff --git a/source/games/duke/src/premap_d.cpp b/source/games/duke/src/premap_d.cpp index 95ee1563a..6945a8b71 100644 --- a/source/games/duke/src/premap_d.cpp +++ b/source/games/duke/src/premap_d.cpp @@ -269,13 +269,13 @@ void cacheit_d(void) // // //--------------------------------------------------------------------------- -void spriteinit_d(int i) +void spriteinit_d(DDukeActor* actor, TArray& actors) { - i = initspriteforspawn(i, { CRACK1, CRACK2, CRACK3, CRACK4, SPEAKER, LETTER, DUCK, TARGET, TRIPBOMB, VIEWSCREEN, VIEWSCREEN2 }); - if ((i & 0x1000000)) spawninit_d(nullptr, &hittype[i&0xffffff]); + bool res = initspriteforspawn(actor, { CRACK1, CRACK2, CRACK3, CRACK4, SPEAKER, LETTER, DUCK, TARGET, TRIPBOMB, VIEWSCREEN, VIEWSCREEN2 }); + if (res) spawninit_d(nullptr, actor, &actors); } -void prelevel_d(int g) +void prelevel_d(int g, TArray& actors) { int i, j, lotaglist; short lotags[65]; @@ -316,32 +316,32 @@ void prelevel_d(int g) } - for (i = 0; i < MAXSPRITES; i++) + for (auto actor : actors) { - auto spr = &sprite[i]; - if (spr->statnum < MAXSTATUS) + if (actor->exists()) { + auto spr = actor->s; if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) continue; - spriteinit_d(i); + spriteinit_d(actor, actors); } } - for (i = 0; i < MAXSPRITES; i++) + for (auto actor : actors) { - auto spr = &sprite[i]; - if (spr->statnum < MAXSTATUS) + if (actor->exists()) { + auto spr = actor->s; if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) - spriteinit_d(i); + spriteinit_d(actor, actors); } } lotaglist = 0; it.Reset(STAT_DEFAULT); - while ((i = it.NextIndex()) >= 0) + while (auto actor = it.Next()) { - auto spr = &sprite[i]; + auto spr = actor->s; switch (spr->picnum) { case DIPSWITCH + 1: diff --git a/source/games/duke/src/premap_r.cpp b/source/games/duke/src/premap_r.cpp index 390791c00..d9fe80e30 100644 --- a/source/games/duke/src/premap_r.cpp +++ b/source/games/duke/src/premap_r.cpp @@ -407,13 +407,13 @@ void cacheit_r(void) // //--------------------------------------------------------------------------- -void spriteinit_r(int i) +void spriteinit_r(DDukeActor* actor, TArray& actors) { - i = initspriteforspawn(i, { CRACK1, CRACK2, CRACK3, CRACK4 }); - if ((i & 0x1000000)) spawninit_r(nullptr, &hittype[i & 0xffffff]); + bool res = initspriteforspawn(actor, { CRACK1, CRACK2, CRACK3, CRACK4 }); + if (res) spawninit_r(nullptr, actor, &actors); } -void prelevel_r(int g) +void prelevel_r(int g, TArray& actors) { struct player_struct* p; int i; @@ -433,14 +433,14 @@ void prelevel_r(int g) if (isRRRA()) { - - for (j = 0; j < MAXSPRITES; j++) + for(auto actor : actors) { - auto spr = &sprite[j]; + if (!actor->exists()) continue; + auto spr = actor->s; if (spr->pal == 100) { if (numplayers > 1) - deletesprite(j); + deletesprite(actor); else spr->pal = 0; } @@ -449,7 +449,7 @@ void prelevel_r(int g) spr->extra = 0; spr->hitag = 1; spr->pal = 0; - changespritestat(j, 118); + ChangeActorStat(actor, 118); } } } @@ -600,9 +600,10 @@ void prelevel_r(int g) } } - for (i = 0; i < MAXSPRITES; i++) + for (auto actor : actors) { - auto spr = &sprite[i]; + if (!actor->exists()) continue; + auto spr = actor->s; if (spr->picnum == RRTILE19) { if (geocnt > 64) @@ -610,10 +611,10 @@ void prelevel_r(int g) if (spr->hitag == 0) { geosector[geocnt] = spr->sector(); - for (j = 0; j < MAXSPRITES; j++) + for (auto actor2 : actors) { - auto spj = &sprite[j]; - if (spr->lotag == spj->lotag && j != i && spj->picnum == RRTILE19) + auto spj = actor2->s; + if (spr->lotag == spj->lotag && actor2 != actor && spj->picnum == RRTILE19) { if (spj->hitag == 1) { @@ -636,31 +637,31 @@ void prelevel_r(int g) } } - for (i = 0; i < MAXSPRITES; i++) + for (auto actor : actors) { - auto spr = &sprite[i]; - if (spr->statnum < MAXSTATUS) + if (actor->exists()) { + auto spr = actor->s; if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) continue; - spriteinit_r(i); + spriteinit_r(actor, actors); } } - for (i = 0; i < MAXSPRITES; i++) + for (auto actor : actors) { - auto spr = &sprite[i]; - if (spr->statnum < MAXSTATUS) + if (actor->exists()) { + auto spr = actor->s; if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) - spriteinit_r(i); - } - if (spr->picnum == RRTILE19) - deletesprite(i); - if (spr->picnum == RRTILE34) - { - spr->sector()->keyinfo = uint8_t(spr->lotag); - deletesprite(i); + spriteinit_r(actor, actors); + if (spr->picnum == RRTILE19) + deletesprite(actor); + if (spr->picnum == RRTILE34) + { + spr->sector()->keyinfo = uint8_t(spr->lotag); + deletesprite(actor); + } } } diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index f56f87e6b..078950011 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -726,7 +726,7 @@ void checkhitwall_d(DDukeActor* spr, walltype* wal, int x, int y, int z, int atw auto spawned = EGS(sptr, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); if (spawned) { - spawned->s->lotag = 128; + spawned->s->lotag = SE_128_GLASS_BREAKING; spawned->temp_data[1] = 5; spawned->temp_walls[0] = wal; S_PlayActorSound(GLASS_BREAKING, spawned); diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 10e669991..3246b934b 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -790,7 +790,7 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act) DDukeActor* switches[3]; int switchcount = 0, j; S_PlaySound3D(SWITCH_ON, act, &v); - DukeLinearSpriteIterator it; + DukeSpriteIterator it; while (auto actt = it.Next()) { int jpn = actt->s->picnum; @@ -806,6 +806,11 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act) } if (switchcount == 3) { + // This once was a linear search over sprites[] so bring things back in order, just to be safe. + if (switches[0]->GetIndex() > switches[1]->GetIndex()) std::swap(switches[0], switches[1]); + if (switches[0]->GetIndex() > switches[2]->GetIndex()) std::swap(switches[0], switches[2]); + if (switches[1]->GetIndex() > switches[2]->GetIndex()) std::swap(switches[1], switches[2]); + S_PlaySound3D(78, act, &v); for (j = 0; j < switchcount; j++) { @@ -1038,7 +1043,7 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, int x, int y, int z, int atw auto spawned = EGS(sptr, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); if (spawned) { - spawned->s->lotag = 128; + spawned->s->lotag = SE_128_GLASS_BREAKING; spawned->temp_walls[0] = wal; S_PlayActorSound(GLASS_BREAKING, spawned); } @@ -1059,7 +1064,7 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, int x, int y, int z, int atw auto spawned = EGS(sptr, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); if (spawned) { - spawned->s->lotag = 128; + spawned->s->lotag = SE_128_GLASS_BREAKING; spawned->temp_data[1] = 2; spawned->temp_walls[0] = wal; S_PlayActorSound(GLASS_BREAKING, spawned); diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index 1d269e79c..c47d10e8b 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -137,9 +137,8 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8 // //--------------------------------------------------------------------------- -int initspriteforspawn(int i, const std::initializer_list &excludes) +bool initspriteforspawn(DDukeActor* act, const std::initializer_list &excludes) { - auto act = &hittype[i]; auto sp = act->s; auto t = act->temp_data; @@ -168,7 +167,7 @@ int initspriteforspawn(int i, const std::initializer_list &excludes) if (sp->cstat & 48) if (!isIn(sp->picnum, excludes) && (sp->cstat & 48)) { - if (sp->shade == 127) return i; + if (sp->shade == 127) return false; if (wallswitchcheck(act) && (sp->cstat & 16)) { if (sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2 && sp->pal) @@ -177,21 +176,21 @@ int initspriteforspawn(int i, const std::initializer_list &excludes) { sp->xrepeat = sp->yrepeat = 0; sp->cstat = sp->lotag = sp->hitag = 0; - return i; + return false; } } sp->cstat |= 257; if (sp->pal && sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2) sp->pal = 0; - return i; + return false; } if (sp->hitag) { - changespritestat(i, 12); + ChangeActorStat(act, 12); sp->cstat |= 257; sp->extra = gs.impact_damage; - return i; + return false; } } @@ -209,7 +208,7 @@ int initspriteforspawn(int i, const std::initializer_list &excludes) sp->hitag = s3; } else t[1] = t[4] = 0; - return i | 0x1000000; + return true; } //--------------------------------------------------------------------------- @@ -226,7 +225,7 @@ DDukeActor* spawn(DDukeActor* actj, int pn) if (spawned) { spawned->picnum = actj->s->picnum; - return fi.spawninit(actj, spawned); + return fi.spawninit(actj, spawned, nullptr); } } return nullptr; @@ -619,7 +618,7 @@ int initreactor(DDukeActor* actj, DDukeActor* actor, bool isrecon) // //--------------------------------------------------------------------------- -void spawneffector(DDukeActor* actor) +void spawneffector(DDukeActor* actor, TArray* actors) { auto sp = actor->s; auto sectp = sp->sector(); @@ -637,18 +636,18 @@ void spawneffector(DDukeActor* actor) break; case SE_7_TELEPORT: // Transporters!!!! case SE_23_ONE_WAY_TELEPORT:// XPTR END - if (sp->lotag != SE_23_ONE_WAY_TELEPORT) + if (sp->lotag != SE_23_ONE_WAY_TELEPORT && actors) { - DukeLinearSpriteIterator it; - while (auto act2 = it.Next()) - { + + for(auto act2 : *actors) + { if (act2->s->statnum < MAXSTATUS && act2->s->picnum == SECTOREFFECTOR && (act2->s->lotag == SE_7_TELEPORT || act2->s->lotag == SE_23_ONE_WAY_TELEPORT) && actor != act2 && act2->s->hitag == sp->hitag) { actor->SetOwner(act2); break; } - } + } } else actor->SetOwner(actor); @@ -943,9 +942,9 @@ void spawneffector(DDukeActor* actor) sectp->hitag = ActorToScriptIndex(actor); } - DukeLinearSpriteIterator it; + bool found = false; - while (auto act2 = it.Next()) + if (actors) for(auto act2 : *actors) { auto spr = act2->s; if (spr->statnum < MAXSTATUS) diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 47a09d70a..b045526d4 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -41,7 +41,7 @@ source as it is released. BEGIN_DUKE_NS -DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act) +DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* actors) { auto sp = act->s; auto spj = actj == nullptr ? nullptr : actj->s; @@ -1125,7 +1125,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act) break; case SECTOREFFECTOR: - spawneffector(act); + spawneffector(act, actors); break; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 877c59165..b70a5c4f2 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -35,7 +35,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms BEGIN_DUKE_NS -DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act) +DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* actors) { auto sp = act->s; auto spj = actj == nullptr ? nullptr : actj->s; @@ -1371,7 +1371,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act) ChangeActorStat(act, STAT_STANDABLE); break; case SECTOREFFECTOR: - spawneffector(act); + spawneffector(act, actors); break; case SEENINE: diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index ef483c897..7010e0696 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -45,9 +45,10 @@ struct DDukeActor : public DCoreActor static DDukeActor* array(); // this is necessary to allow define inline functions referencing the global array inside the definition itself. - DDukeActor() : s(&sprite[this - array()]) + DDukeActor() { index = int(this - array()); + s = &DCoreActor::s(); } DDukeActor(const DDukeActor& other) = delete; // we also do not want to allow copies. DDukeActor& operator=(const DDukeActor& other) = delete;