#include "pch.h"
CollisionQueue::CollisionQueue(void)
:
m_nCollisions(0),
m_maxCollisions(c_maxHitTests * 20), m_fDelete(true)
{
m_pCollisions = new CollisionEntry [m_maxCollisions];
assert (m_pCollisions);
}
CollisionQueue::CollisionQueue(int maxCollisions,
CollisionEntry* pCollisions)
:
m_nCollisions(0),
m_pCollisions(pCollisions),
m_maxCollisions(maxCollisions),
m_fDelete(false)
{
}
CollisionQueue::~CollisionQueue(void)
{
if (m_fDelete)
delete [] m_pCollisions;
}
void CollisionQueue::sort(int start)
{
if ((m_nCollisions - 1) > start)
{
if (start == 0)
{
CollisionEntry::longSort(m_pCollisions,
&m_pCollisions[m_nCollisions - 1]);
}
else
{
CollisionEntry::shortSort(&m_pCollisions[start],
&m_pCollisions[m_nCollisions - 1]);
}
}
}
void CollisionQueue::flush(int n,
HitTest* pHitTest1,
HitTest* pHitTest2)
{
assert (n > 0);
assert (n <= m_nCollisions);
bool oldDead1;
if (pHitTest1)
{
oldDead1 = pHitTest1->GetDeadF();
pHitTest1->AddRef();
pHitTest1->SetDeadF(true);
}
bool oldDead2;
if (pHitTest2)
{
oldDead2 = pHitTest2->GetDeadF();
pHitTest2->AddRef();
pHitTest2->SetDeadF(true);
}
float t = m_pCollisions[n - 1].m_tCollision;
int dest = n;
for (int source = n; (source < m_nCollisions); source++)
{
CollisionEntry* pentrySource = &m_pCollisions[source];
if (pentrySource->m_pHitTest1->GetDeadF() || pentrySource->m_pHitTest2->GetDeadF())
{
pentrySource->m_pHitTest1->Release();
pentrySource->m_pHitTest2->Release();
pentrySource->m_pHitTest1 = NULL; pentrySource->m_pHitTest2 = NULL;
}
else
{
CollisionEntry* pentryDest = &m_pCollisions[dest++];
pentryDest->m_pHitTest1 = pentrySource->m_pHitTest1;
pentryDest->m_pHitTest2 = pentrySource->m_pHitTest2;
pentryDest->m_hts1 = pentrySource->m_hts1;
pentryDest->m_hts2 = pentrySource->m_hts2;
pentryDest->m_tCollision = pentrySource->m_tCollision - t;
}
}
if (pHitTest2)
{
pHitTest2->SetDeadF(oldDead2);
pHitTest2->Release();
}
if (pHitTest1)
{
pHitTest1->SetDeadF(oldDead1);
pHitTest1->Release();
}
m_nCollisions = dest;
}
void CollisionQueue::purge(void)
{
int i = m_nCollisions;
while (--i >= 0)
{
CollisionEntry* pentry = &m_pCollisions[i];
pentry->m_pHitTest1->Release();
pentry->m_pHitTest2->Release();
}
m_nCollisions = 0;
}
void CollisionQueue::addCollision(float tCollision,
HitTest* pHitTest1,
HitTestShape hts1,
HitTest* pHitTest2,
HitTestShape hts2)
{
assert (hts1 <= pHitTest1->GetTrueShape());
assert (hts2 <= pHitTest2->GetTrueShape());
assert (m_nCollisions <= m_maxCollisions);
if (m_nCollisions == m_maxCollisions)
{
m_maxCollisions = (m_maxCollisions << 1);
debugf("Extending collision queue from %d to %d entries\n", m_nCollisions, m_maxCollisions);
CollisionEntry* p = new CollisionEntry[m_maxCollisions];
assert (p);
for (int i = 0; (i < m_nCollisions); i++)
{
p[i] = m_pCollisions[i];
}
delete [] m_pCollisions;
m_pCollisions = p;
}
assert (m_nCollisions < m_maxCollisions);
assert (pHitTest1);
assert (pHitTest2);
pHitTest1->AddRef();
pHitTest2->AddRef();
CollisionEntry* pentry = &m_pCollisions[m_nCollisions++];
pentry->m_tCollision = tCollision;
pentry->m_pHitTest1 = pHitTest1;
pentry->m_hts1 = hts1;
pentry->m_pHitTest2 = pHitTest2;
pentry->m_hts2 = hts2;
}