Skip to content

Commit

Permalink
Replaced C style list with STL list (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mia75owo authored Dec 9, 2023
1 parent e565910 commit 0bc68c3
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 150 deletions.
168 changes: 48 additions & 120 deletions Hurrican/src/Projectiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,18 @@
// --------------------------------------------------------------------------------------


#include "Projectiles.hpp"
#include "Console.hpp"
#include "DX8Font.hpp"
#include "DX8Sound.hpp"
#include "Gameplay.hpp"
#include "Gegner_Helper.hpp"
#include "Globals.hpp"
#include "Logdatei.hpp"
#include "Partikelsystem.hpp"
#include "Player.hpp"
#include "Projectiles.hpp"
#include "Tileengine.hpp"
#include "Timer.hpp"

#include <cmath>
#include <algorithm>

// --------------------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1809,7 +1805,6 @@ void ProjectileClass::CreateShot(float x, float y, int Art, PlayerClass *pTemp)
// --------------------------------------------------------------------------------------

void ProjectileClass::CheckCollision() {

for (auto& pEnemy: Gegner.enemies) // Noch nicht alle durch ?
{
if (pEnemy->Active && // Ist der Gegner überhaupt aktiv ?
Expand Down Expand Up @@ -4116,9 +4111,6 @@ void ProjectileClass::ExplodeShot() {
// Konstruktor : laden der Projektil Grafiken
// --------------------------------------------------------------------------------------
ProjectileListClass::ProjectileListClass() {
pStart = nullptr;
pEnd = nullptr;
NumProjectiles = 0;
}

void ProjectileListClass::LoadSprites() {
Expand Down Expand Up @@ -4677,7 +4669,6 @@ void ProjectileListClass::LoadSprites() {
// --------------------------------------------------------------------------------------

ProjectileListClass::~ProjectileListClass() {
// Schuss-Liste komplett leeren
ClearAll();
}

Expand Down Expand Up @@ -4718,28 +4709,21 @@ bool ProjectileListClass::PushProjectile(float x, float y, int Art, PlayerClass*
return true;
}
#endif // 0

bool ProjectileListClass::PushProjectile(float x, float y, int Art, PlayerClass *pTemp) {
if (NumProjectiles >= MAX_SHOTS)
if (GetNumProjectiles() >= MAX_SHOTS)
return false;

// DKS - added support for new, fast pooled mem-manager:
#ifdef USE_NO_MEMPOOLING
ProjectileClass *pNew = new ProjectileClass;
#else
ProjectileClass *pNew = projectile_pool.alloc();
#endif

pNew->CreateShot(x, y, Art, pTemp);
pNew->pNext = nullptr;

if (pEnd)
pEnd->pNext = pNew; // If list isn't empty, insert this projectile on the end.
else
pStart = pNew; // Or, if list is empty, make this the new head of the list.

pEnd = pNew; // Update end-of-list pointer
projectiles.push_front(pNew);

NumProjectiles++;
return true;
}

Expand All @@ -4748,19 +4732,18 @@ bool ProjectileListClass::PushProjectile(float x, float y, int Art, PlayerClass
// --------------------------------------------------------------------------------------

bool ProjectileListClass::PushBlitzBeam(int Size, float Richtung, PlayerClass *pSource) {
if (NumProjectiles >= MAX_SHOTS) // Grenze überschritten ?
if (GetNumProjectiles() >= MAX_SHOTS) // Grenze überschritten ?
return false;

// DKS - added support for new, fast pooled mem-manager
#ifdef USE_NO_MEMPOOLING
ProjectileClass *pNew = new ProjectileClass; // Neues zu erstellendes Projectile
ProjectileClass *pNew = new ProjectileClass;
#else
ProjectileClass *pNew = projectile_pool.alloc();
#endif

pNew->ShotArt = BLITZBEAM;
pNew->xPos = pSource->xpos - Size / 2 + 20;
pNew->yPos = pSource->ypos - Size / 2 + 32;
pNew->xPos = pSource->xpos - Size / 2.0f + 20;
pNew->yPos = pSource->ypos - Size / 2.0f + 32;
pNew->xPosOld = pNew->xPos;
pNew->yPosOld = pNew->yPos;
pNew->AnimPhase = 0;
Expand Down Expand Up @@ -4806,101 +4789,66 @@ bool ProjectileListClass::PushBlitzBeam(int Size, float Richtung, PlayerClass *p
ShotRect[BLITZBEAM].right = ShotRect[BLITZBEAM].left + Size / 2;
ShotRect[BLITZBEAM].bottom = ShotRect[BLITZBEAM].top + Size / 2;

pNew->pNext = nullptr;

if (pEnd)
pEnd->pNext = pNew; // If list isn't empty, insert this projectile on the end.
else
pStart = pNew; // Or, if list is empty, make this the new head of the list.
projectiles.push_front(pNew);

pEnd = pNew; // Update end-of-list pointer

NumProjectiles++; // Projektilanzahl erhöhen
return true;
}

// --------------------------------------------------------------------------------------
// Bestimmtes Projektil der Liste löschen
// Remove all dead projectiles
// --------------------------------------------------------------------------------------

// DKS - Replaced DelSel() with DelNode(), which supports the now-singly-linked-list. It operates
// a bit differently:
// It is now up to the caller to splice the list, this blindly deletes what is passed to it
// and returns the pointer that was in pPtr->pNext, or NULL if pPtr was NULL.
ProjectileClass *ProjectileListClass::DelNode(ProjectileClass *pPtr) {
ProjectileClass *pNext = nullptr;
if (pPtr != nullptr) {
pNext = pPtr->pNext;

if (pStart == pPtr) // Are we deleting the first node in the list?
pStart = pNext;
void ProjectileListClass::ClearDeadProjectiles() {
auto iter = projectiles.begin();
while (iter != projectiles.end()) {
ProjectileClass* projectile = *iter;

// DKS - added support for new, fast pooled mem-manager:
if (projectile->Damage > 0) {
++iter;
} else {
#ifdef USE_NO_MEMPOOLING
delete (pPtr);
delete projectile;
#else
projectile_pool.free(pPtr);
projectile_pool.free(projectile);
#endif

NumProjectiles--;
iter = projectiles.erase(iter);
}
}
return pNext;
}

// --------------------------------------------------------------------------------------
// Alle Projectile der Liste löschen
// --------------------------------------------------------------------------------------
// DKS - Converted ProjectileListClass to a singly-linked list (depends on DelNode() now).
// and added support for new pooled memory manager.
void ProjectileListClass::ClearAll() {
if (pStart) {
ProjectileClass *pNext = pStart->pNext;

while (pNext) // Delete everything but the head of the list
pNext = DelNode(pNext);

DelNode(pStart); // Finally, delete the head of the list
void ProjectileListClass::ClearAll() {
#ifdef USE_NO_MEMPOOLING
for (auto& projectile: projectiles) {
delete projectile;
}
pStart = pEnd = nullptr;

#ifndef NDEBUG
if (NumProjectiles != 0)
Protokoll << "ERROR: poss. mem leak / corruption in linked list of projectiles" << std::endl;
#endif

// DKS - added support for new, fast pooled mem-manager:
#ifndef USE_NO_MEMPOOLING
#else
projectile_pool.reinit();
#endif

// Just to be safe:
NumProjectiles = 0;
projectiles.clear();
}

// --------------------------------------------------------------------------------------
// Alle Projectiles eines Typs löschen
// --------------------------------------------------------------------------------------

// DKS - Adapted after converting ProjectileListClass to a singly-linked list:
void ProjectileListClass::ClearType(int Type) {
ProjectileClass *pPrev = nullptr;
ProjectileClass *pCurr = pStart;

while (pCurr != nullptr) {
if (pCurr->ShotArt == Type) {
// If this is the last node in the list, update the main class's pEnd pointer
if (pEnd == pCurr)
pEnd = pPrev;

pCurr = DelNode(pCurr); // pCurr now points to the node after the one deleted
auto iter = projectiles.begin();
while (iter != projectiles.end()) {
ProjectileClass* projectile = *iter;

if (pPrev) {
// This is not the first node in the list, so splice this node onto the previous one
pPrev->pNext = pCurr;
}
if (projectile->ShotArt != Type) {
++iter;
} else {
pPrev = pCurr;
pCurr = pCurr->pNext;
#ifdef USE_NO_MEMPOOLING
delete projectile;
#else
projectile_pool.free(projectile);
#endif
iter = projectiles.erase(iter);
}
}
}
Expand All @@ -4910,48 +4858,28 @@ void ProjectileListClass::ClearType(int Type) {
// --------------------------------------------------------------------------------------

int ProjectileListClass::GetNumProjectiles() const {
return NumProjectiles;
return projectiles.size();
}

// --------------------------------------------------------------------------------------
// Alle Proectile der Liste animieren und bewegen
// --------------------------------------------------------------------------------------

// DKS - Adapted after converting projectile list to singly-linked one
void ProjectileListClass::DoProjectiles() {
ProjectileClass *pPrev = nullptr;
ProjectileClass *pCurr = pStart;

CurrentShotTexture = -1; // Aktuelle Textur gibt es noch keine
CurrentShotTexture = -1; // Aktuelle Textur gibt es noch keine

while (pCurr != nullptr) {
if (!Console.Showing)
pCurr->Run();

if (pCurr->Damage > 0)
pCurr->Render();
ClearDeadProjectiles();

for (auto& projectile: projectiles) {
if (!Console.Showing) {
if (pCurr->Damage <= 0) // ggf Schuss löschen (bei Damage <= 0)
{
// Projectile's time to die..
// If this is the last node in the list, update the class's pEnd pointer
if (pEnd == pCurr)
pEnd = pPrev;

pCurr = DelNode(pCurr); // pCurr now points to the node after the one deleted
projectile->Run();
}
if (projectile->Damage > 0) {
projectile->Render();

// If this is not the first node in the list, splice this node onto the previous one:
if (pPrev)
pPrev->pNext = pCurr;
} else {
pCurr->CheckCollision();
pPrev = pCurr;
pCurr = pCurr->pNext;
if (!Console.Showing) {
projectile->CheckCollision();
}
} else {
pPrev = pCurr;
pCurr = pCurr->pNext;
}
}
}
22 changes: 5 additions & 17 deletions Hurrican/src/Projectiles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,6 @@ class ProjectileClass {
void Render(); // Schuss rendern
void CheckCollision(); // Kollision checken
void ExplodeShot(); // Schuss explodiert und erzeugt Partikel
ProjectileClass *pNext; // Zeiger auf den nächsten Schuss
// DKS - Made a singly-linked list, there's no need or benefit for a doubly-linked list here.
// ProjectileClass *pPrev; // Zeiger auf den vorherigen Schuss
PlayerClass *pParent;
};

Expand All @@ -223,16 +220,13 @@ class ProjectileClass {

class ProjectileListClass {
private:
int NumProjectiles; // aktuelle Zahl der Schüsse

// DKS - New, very simple pooled memory manager decreases alloc/dealloc overhead: (see DataStructures.h)
#ifndef USE_NO_MEMPOOLING
MemPool<ProjectileClass, MAX_SHOTS> projectile_pool;
#endif

public:
ProjectileClass *pStart; // Erstes Element der Liste
ProjectileClass *pEnd; // Letztes Element der Liste
std::list<ProjectileClass*> projectiles;

// DKS - All of these 5 sprites are no longer globals, I moved them here cleaning up big messes
// and fixing ambiguous orders of calls to destructors.
Expand Down Expand Up @@ -264,17 +258,11 @@ class ProjectileListClass {
float Richtung,
PlayerClass *pSource); // BlitzBeam hinzufügen (in verschiedenen Größen und Richtungen möglich)

// DKS - Converted projectile linked-list to be singly-linked:
// DelNode() is new and takes the place of DelSel(), but operates a bit differently.
// It is now up to the caller to splice the list: DelNode() blindly deletes the node
// passed to it and returns the pointer that was in pPtr->pNext, or NULL if pPtr was NULL.
// void DelSel (ProjectileClass *pTemp); // Ausgewähltes Objekt entfernen
ProjectileClass *DelNode(ProjectileClass *pPtr);

void ClearAll(); // Alle Objekte löschen
void ClearType(int type); // Alle Objekte eines Typs löschen
void ClearDeadProjectiles(); // Remove all dead projectiles
void ClearAll(); // Alle Objekte löschen
void ClearType(int type); // Alle Objekte eines Typs löschen
int GetNumProjectiles() const; // Zahl der Schüsse zurückliefern
void DoProjectiles(); // Alle Schüsse der Liste animieren
void DoProjectiles(); // Alle Schüsse der Liste animieren
};

// --------------------------------------------------------------------------------------
Expand Down
20 changes: 7 additions & 13 deletions Hurrican/src/bosses/Boss_FahrstuhlBoss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,14 +524,11 @@ void GegnerFahrstuhlBoss::DoKI() {
}
}

ProjectileClass *pTemp2 = Projectiles.pStart; // Zeiger auf den ersten Schuss
while (pTemp2 != nullptr) // Ende der Liste erreicht ?
{
if (pTemp2->ShotArt != STELZLASER) {
pTemp2->yPos += Timer.sync(40.0f); // Nach unten bewegen
pTemp2->yPosOld += Timer.sync(40.0f);
for (const auto& projectile: Projectiles.projectiles) {
if (projectile->ShotArt != STELZLASER) {
projectile->yPos += Timer.sync(40.0f); // Nach unten bewegen
projectile->yPosOld += Timer.sync(40.0f);
}
pTemp2 = pTemp2->pNext; // Zeiger auf das nächste Element
}

// Level-Hintergrund wiederholen und alle Objekte wieder nach oben setzen
Expand All @@ -550,12 +547,9 @@ void GegnerFahrstuhlBoss::DoKI() {
}
}

ProjectileClass *pTemp4 = Projectiles.pStart; // Zeiger auf den ersten Schuss
while (pTemp4 != nullptr) // Ende der Liste erreicht ?
{
pTemp4->yPos -= A; // Nach oben bewegen
pTemp4->yPosOld -= A;
pTemp4 = pTemp4->pNext; // Zeiger auf das nächste Element
for (const auto& projectile: Projectiles.projectiles) {
projectile->yPos -= A; // Nach oben bewegen
projectile->yPosOld -= A;
}

for (auto& particle: PartikelSystem.particles) {
Expand Down

0 comments on commit 0bc68c3

Please sign in to comment.