Optimization: rewrite DelayQueue w/o STL vectors.

This commit is contained in:
Christian Speckner 2017-05-15 00:43:18 +02:00
parent 145d47315e
commit 744571b1da
11 changed files with 383 additions and 350 deletions

View File

@ -742,7 +742,7 @@ bool TIADebug::vblank() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
shared_ptr<DelayQueueIterator> TIADebug::delayQueueIterator() const shared_ptr<DelayQueueIterator> TIADebug::delayQueueIterator() const
{ {
return shared_ptr<DelayQueueIterator>(new DelayQueueIterator(myTIA.myDelayQueue)); return myTIA.delayQueueIterator();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -1,100 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "DelayQueue.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DelayQueue::DelayQueue(uInt8 length, uInt8 size)
: myIndex(0)
{
myMembers.reserve(length);
for (uInt16 i = 0; i < length; i++)
myMembers.emplace_back(size);
memset(myIndices, 0xFF, 0xFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueue::push(uInt8 address, uInt8 value, uInt8 delay)
{
uInt8 length = myMembers.size();
if (delay >= length)
throw runtime_error("delay exceeds queue length");
uInt8 currentIndex = myIndices[address];
if (currentIndex < 0xFF)
myMembers.at(currentIndex).remove(address);
uInt8 index = (myIndex + delay) % length;
myMembers.at(index).push(address, value);
myIndices[address] = index;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueue::reset()
{
for (DelayQueueMember& member : myMembers)
member.clear();
memset(myIndices, 0xFF, 0xFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueue::save(Serializer& out) const
{
try
{
out.putInt(uInt32(myMembers.size()));
for(const DelayQueueMember& m: myMembers)
m.save(out);
out.putByte(myIndex);
out.putByteArray(myIndices, 0xFF);
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueue::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueue::load(Serializer& in)
{
try
{
myMembers.resize(in.getInt());
for(DelayQueueMember& m: myMembers)
m.load(in);
myIndex = in.getByte();
in.getByteArray(myIndices, 0xFF);
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueue::load" << endl;
return false;
}
return true;
}

View File

@ -22,13 +22,17 @@
#include "bspf.hxx" #include "bspf.hxx"
#include "DelayQueueMember.hxx" #include "DelayQueueMember.hxx"
template<int length, int capacity>
class DelayQueueIteratorImpl;
template<int length, int capacity>
class DelayQueue : public Serializable class DelayQueue : public Serializable
{ {
public: public:
friend class DelayQueueIterator; friend DelayQueueIteratorImpl<length, capacity>;
public: public:
DelayQueue(uInt8 length, uInt8 size); DelayQueue();
public: public:
@ -46,12 +50,11 @@ class DelayQueue : public Serializable
string name() const override { return "TIA_DelayQueue"; } string name() const override { return "TIA_DelayQueue"; }
private: private:
vector<DelayQueueMember> myMembers; DelayQueueMember<capacity> myMembers[length];
uInt8 myIndex; uInt8 myIndex;
uInt8 myIndices[0xFF]; uInt8 myIndices[0xFF];
private: private:
DelayQueue() = delete;
DelayQueue(const DelayQueue&) = delete; DelayQueue(const DelayQueue&) = delete;
DelayQueue(DelayQueue&&) = delete; DelayQueue(DelayQueue&&) = delete;
DelayQueue& operator=(const DelayQueue&) = delete; DelayQueue& operator=(const DelayQueue&) = delete;
@ -62,18 +65,104 @@ class DelayQueue : public Serializable
// Implementation // Implementation
// ############################################################################ // ############################################################################
template<class T> void DelayQueue::execute(T executor) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
DelayQueue<length, capacity>::DelayQueue()
: myIndex(0)
{ {
DelayQueueMember& currentMember = myMembers.at(myIndex); memset(myIndices, 0xFF, 0xFF);
}
for (auto&& entry : currentMember) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
executor(entry.address, entry.value); template<int length, int capacity>
myIndices[entry.address] = 0xFF; void DelayQueue<length, capacity>::push(uInt8 address, uInt8 value, uInt8 delay)
{
if (delay >= length)
throw runtime_error("delay exceeds queue length");
uInt8 currentIndex = myIndices[address];
if (currentIndex < 0xFF)
myMembers[currentIndex].remove(address);
uInt8 index = (myIndex + delay) % length;
myMembers[index].push(address, value);
myIndices[address] = index;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
void DelayQueue<length, capacity>::reset()
{
for (uInt8 i = 0; i < length; i++)
myMembers[i].clear();
myIndex = 0;
memset(myIndices, 0xFF, 0xFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
template<class T>
void DelayQueue<length, capacity>::execute(T executor)
{
DelayQueueMember<capacity>& currentMember = myMembers[myIndex];
for (uInt8 i = 0; i < currentMember.mySize; i++) {
executor(currentMember.myEntries[i].address, currentMember.myEntries[i].value);
myIndices[currentMember.myEntries[i].address] = 0xFF;
} }
currentMember.clear(); currentMember.clear();
myIndex = (myIndex + 1) % myMembers.size(); myIndex = (myIndex + 1) % length;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
bool DelayQueue<length, capacity>::save(Serializer& out) const
{
try
{
out.putInt(length);
for (uInt8 i = 0; i < length; i++)
myMembers[i].save(out);
out.putByte(myIndex);
out.putByteArray(myIndices, 0xFF);
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueue::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
bool DelayQueue<length, capacity>::load(Serializer& in)
{
try
{
if (in.getInt() != length) throw runtime_error("delay queue length mismatch");
for (uInt8 i = 0; i < length; i++)
myMembers[i].load(in);
myIndex = in.getByte();
in.getByteArray(myIndices, 0xFF);
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueue::load" << endl;
return false;
}
return true;
} }
#endif // TIA_DELAY_QUEUE #endif // TIA_DELAY_QUEUE

View File

@ -1,94 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "DelayQueueIterator.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DelayQueueIterator::DelayQueueIterator(const DelayQueue& delayQueue)
: myDelayQueue(delayQueue),
myDelayCycle(0)
{
while (isValid()) {
const DelayQueueMember& currentMember = myDelayQueue.myMembers.at(currentIndex());
myCurrentIterator = currentMember.begin();
if (myCurrentIterator == currentMember.end())
myDelayCycle++;
else
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueueIterator::isValid() const
{
return myDelayCycle < myDelayQueue.myMembers.size();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 DelayQueueIterator::delay() const
{
if (!isValid()) {
throw runtime_error("delay called on invalid DelayQueueInterator");
}
return myDelayCycle;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 DelayQueueIterator::address() const
{
if (!isValid()) {
throw runtime_error("address called on invalid DelayQueueInterator");
}
return myCurrentIterator->address;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 DelayQueueIterator::value() const
{
if (!isValid()) {
throw runtime_error("value called on invalid DelayQueueIterator");
}
return myCurrentIterator->value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueueIterator::next()
{
if (!isValid()) {
return false;
}
if (++myCurrentIterator == myDelayQueue.myMembers.at(currentIndex()).end()) {
myDelayCycle++;
while (isValid()) {
const DelayQueueMember& currentMember = myDelayQueue.myMembers.at(currentIndex());
myCurrentIterator = currentMember.begin();
if (myCurrentIterator == currentMember.end())
myDelayCycle++;
else
break;
}
}
return isValid();
}

View File

@ -25,28 +25,18 @@
class DelayQueueIterator class DelayQueueIterator
{ {
public: public:
DelayQueueIterator(const DelayQueue&); virtual ~DelayQueueIterator() {}
bool isValid() const; public:
virtual bool isValid() const = 0;
uInt8 delay() const; virtual uInt8 delay() const = 0;
uInt8 address() const; virtual uInt8 address() const = 0;
uInt8 value() const; virtual uInt8 value() const = 0;
bool next(); virtual bool next() = 0;
private:
uInt8 currentIndex() const {
return (myDelayQueue.myIndex + myDelayCycle) % myDelayQueue.myMembers.size();
}
private:
const DelayQueue& myDelayQueue;
uInt8 myDelayCycle;
DelayQueueMember::iterator myCurrentIterator;
}; };
#endif // TIA_DELAY_QUEUE_ITERATOR #endif // TIA_DELAY_QUEUE_ITERATOR

View File

@ -0,0 +1,135 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef TIA_DELAY_QUEUE_ITERATOR_IMPL
#define TIA_DELAY_QUEUE_ITERATOR_IMPL
#include "bspf.hxx"
#include "DelayQueue.hxx"
#include "DelayQueueMember.hxx"
#include "DelayQueueIterator.hxx"
template<int length, int capacity>
class DelayQueueIteratorImpl : public DelayQueueIterator
{
public:
DelayQueueIteratorImpl(const DelayQueue<length, capacity>& delayQueue);
public:
bool isValid() const override;
uInt8 delay() const override;
uInt8 address() const override;
uInt8 value() const override;
bool next() override;
private:
uInt8 currentIndex() const;
private:
const DelayQueue<length, capacity>& myDelayQueue;
uInt8 myDelayCycle;
uInt8 myIndex;
};
// ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
DelayQueueIteratorImpl<length,capacity>::DelayQueueIteratorImpl(
const DelayQueue<length, capacity>& delayQueue
)
: myDelayQueue(delayQueue),
myDelayCycle(0),
myIndex(0)
{
while (myDelayQueue.myMembers[currentIndex()].mySize == 0 && isValid())
myDelayCycle++;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
bool DelayQueueIteratorImpl<length, capacity>::isValid() const
{
return myDelayCycle < length;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::delay() const
{
if (!isValid()) {
throw runtime_error("delay called on invalid DelayQueueInterator");
}
return myDelayCycle;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::address() const
{
if (!isValid()) {
throw runtime_error("address called on invalid DelayQueueInterator");
}
return myDelayQueue.myMembers[currentIndex()].myEntries[myIndex].address;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::value() const
{
if (!isValid()) {
throw runtime_error("value called on invalid DelayQueueInterator");
}
return myDelayQueue.myMembers[currentIndex()].myEntries[myIndex].value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
bool DelayQueueIteratorImpl<length, capacity>::next()
{
if (!isValid()) return false;
if (++myIndex < myDelayQueue.myMembers[currentIndex()].mySize)
return true;
myIndex = 0;
do {
myDelayCycle++;
} while (myDelayQueue.myMembers[currentIndex()].mySize == 0 && isValid());
return isValid();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::currentIndex() const
{
return (myDelayQueue.myIndex + myDelayCycle) % length;
}
#endif // TIA_DELAY_QUEUE_ITERATOR_IMPL

View File

@ -1,93 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "DelayQueueMember.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DelayQueueMember::DelayQueueMember(uInt8 size)
: myEntries(size),
mySize(0)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueueMember::push(uInt8 address, uInt8 value)
{
Entry& entry = myEntries.at(mySize++);
entry.address = address;
entry.value = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueueMember::remove(uInt8 address)
{
size_t index;
for (index = 0; index < mySize; index++)
if (myEntries.at(index).address == address)
break;
if (index < mySize) {
myEntries.at(index) = myEntries.at(mySize - 1);
mySize--;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueueMember::save(Serializer& out) const
{
try
{
out.putInt(mySize);
for(uInt32 i = 0; i < mySize; ++i)
{
const Entry& e = myEntries[i];
out.putByte(e.address);
out.putByte(e.value);
}
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueueMember::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DelayQueueMember::load(Serializer& in)
{
try
{
mySize = in.getInt();
for(uInt32 i = 0; i < mySize; ++i)
{
Entry& e = myEntries[i];
e.address = in.getByte();
e.value = in.getByte();
}
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueueMember::load" << endl;
return false;
}
return true;
}

View File

@ -21,8 +21,9 @@
#include "Serializable.hxx" #include "Serializable.hxx"
#include "bspf.hxx" #include "bspf.hxx"
class DelayQueueMember : public Serializable template<int capacity>
{ class DelayQueueMember : public Serializable {
public: public:
struct Entry { struct Entry {
uInt8 address; uInt8 address;
@ -30,47 +31,137 @@ class DelayQueueMember : public Serializable
}; };
public: public:
DelayQueueMember(uInt8 size = 0); DelayQueueMember();
DelayQueueMember(DelayQueueMember&&) = default;
DelayQueueMember& operator=(DelayQueueMember&&) = default;
public: public:
typedef vector<Entry>::const_iterator iterator;
public:
void push(uInt8 address, uInt8 value); void push(uInt8 address, uInt8 value);
void remove(uInt8 address); void remove(uInt8 address);
iterator begin() const { void clear();
return myEntries.begin();
}
iterator end() const {
return (mySize < myEntries.size()) ? (myEntries.begin() + mySize) : myEntries.end();
}
void clear() {
mySize = 0;
}
/** /**
Serializable methods (see that class for more information). Serializable methods (see that class for more information).
*/ */
bool save(Serializer& out) const override; bool save(Serializer& out) const override;
bool load(Serializer& in) override; bool load(Serializer& in) override;
string name() const override { return "TIA_DelayQueueMember"; } string name() const override;
public:
Entry myEntries[capacity];
uInt8 mySize;
private: private:
vector<Entry> myEntries;
uInt32 mySize;
private: DelayQueueMember(const DelayQueueMember<capacity>&) = delete;
DelayQueueMember(const DelayQueueMember&) = delete; DelayQueueMember(DelayQueueMember<capacity>&&) = delete;
DelayQueueMember& operator=(const DelayQueueMember&) = delete; DelayQueueMember<capacity>& operator=(const DelayQueueMember<capacity>&) = delete;
DelayQueueMember<capacity>& operator=(DelayQueueMember<capacity>&&) = delete;
}; };
#endif // TIA_DELAY_QUEUE_MEMBER // ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
DelayQueueMember<capacity>::DelayQueueMember()
: mySize(0)
{}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
void DelayQueueMember<capacity>::push(uInt8 address, uInt8 value)
{
if (mySize == capacity) throw runtime_error("delay queue overflow");
myEntries[mySize].address = address;
myEntries[mySize++].value = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
void DelayQueueMember<capacity>::remove(uInt8 address)
{
uInt8 index;
for (index = 0; index < mySize; index++) {
if (myEntries[index].address == address) break;
}
if (index < mySize) {
for (uInt8 i = index + 1; i < mySize; i++) {
myEntries[i-1] = myEntries[i];
}
mySize--;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
void DelayQueueMember<capacity>::clear()
{
mySize = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
bool DelayQueueMember<capacity>::save(Serializer& out) const
{
try
{
out.putInt(mySize);
for(uInt8 i = 0; i < mySize; ++i)
{
const Entry& e = myEntries[i];
out.putByte(e.address);
out.putByte(e.value);
}
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueueMember::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
bool DelayQueueMember<capacity>::load(Serializer& in)
{
try
{
mySize = in.getInt();
if (mySize > capacity) throw new runtime_error("invalid delay queue size");
for(uInt32 i = 0; i < mySize; ++i)
{
Entry& e = myEntries[i];
e.address = in.getByte();
e.value = in.getByte();
}
}
catch(...)
{
cerr << "ERROR: TIA_DelayQueueMember::load" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity>
string DelayQueueMember<capacity>::name() const
{
stringstream ss;
ss << "TIA_DelayQueueMember<" << capacity << ">";
return ss.str();
}
#endif // TIA_DELAY_QUEUE_MEMBER

View File

@ -20,6 +20,7 @@
#include "Console.hxx" #include "Console.hxx"
#include "Control.hxx" #include "Control.hxx"
#include "Paddles.hxx" #include "Paddles.hxx"
#include "DelayQueueIteratorImpl.hxx"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
#include "CartDebug.hxx" #include "CartDebug.hxx"
@ -66,7 +67,6 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
: myConsole(console), : myConsole(console),
mySound(sound), mySound(sound),
mySettings(settings), mySettings(settings),
myDelayQueue(10, 20),
myPlayfield(~CollisionMask::playfield & 0x7FFF), myPlayfield(~CollisionMask::playfield & 0x7FFF),
myMissile0(~CollisionMask::missile0 & 0x7FFF), myMissile0(~CollisionMask::missile0 & 0x7FFF),
myMissile1(~CollisionMask::missile1 & 0x7FFF), myMissile1(~CollisionMask::missile1 & 0x7FFF),
@ -935,6 +935,14 @@ bool TIA::toggleJitter(uInt8 mode)
return myFrameManager.jitterEnabled(); return myFrameManager.jitterEnabled();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
shared_ptr<DelayQueueIterator> TIA::delayQueueIterator() const
{
return shared_ptr<DelayQueueIterator>(
new DelayQueueIteratorImpl<delayQueueLength, delayQueueSize>(myDelayQueue)
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA& TIA::updateScanline() TIA& TIA::updateScanline()
{ {

View File

@ -26,6 +26,7 @@
#include "Serializer.hxx" #include "Serializer.hxx"
#include "TIATypes.hxx" #include "TIATypes.hxx"
#include "DelayQueue.hxx" #include "DelayQueue.hxx"
#include "DelayQueueIterator.hxx"
#include "FrameManager.hxx" #include "FrameManager.hxx"
#include "FrameLayout.hxx" #include "FrameLayout.hxx"
#include "Background.hxx" #include "Background.hxx"
@ -35,6 +36,7 @@
#include "Ball.hxx" #include "Ball.hxx"
#include "LatchedInput.hxx" #include "LatchedInput.hxx"
#include "PaddleReader.hxx" #include "PaddleReader.hxx"
#include "DelayQueueIterator.hxx"
/** /**
This class is a device that emulates the Television Interface Adaptor This class is a device that emulates the Television Interface Adaptor
@ -341,6 +343,11 @@ class TIA : public Device
*/ */
void flushLineCache(); void flushLineCache();
/**
Create a new delayQueueIterator for the debugger.
*/
shared_ptr<DelayQueueIterator> delayQueueIterator() const;
/** /**
Save the current state of this device to the given Serializer. Save the current state of this device to the given Serializer.
@ -442,7 +449,10 @@ class TIA : public Device
Sound& mySound; Sound& mySound;
Settings& mySettings; Settings& mySettings;
DelayQueue myDelayQueue; static constexpr int delayQueueLength = 10;
static constexpr int delayQueueSize = 20;
DelayQueue<delayQueueLength, delayQueueSize> myDelayQueue;
FrameManager myFrameManager; FrameManager myFrameManager;
Background myBackground; Background myBackground;

View File

@ -2,8 +2,6 @@ MODULE := src/emucore/tia
MODULE_OBJS := \ MODULE_OBJS := \
src/emucore/tia/TIA.o \ src/emucore/tia/TIA.o \
src/emucore/tia/DelayQueueMember.o \
src/emucore/tia/DelayQueue.o \
src/emucore/tia/FrameManager.o \ src/emucore/tia/FrameManager.o \
src/emucore/tia/Playfield.o \ src/emucore/tia/Playfield.o \
src/emucore/tia/DrawCounterDecodes.o \ src/emucore/tia/DrawCounterDecodes.o \
@ -13,8 +11,7 @@ MODULE_OBJS := \
src/emucore/tia/Background.o \ src/emucore/tia/Background.o \
src/emucore/tia/LatchedInput.o \ src/emucore/tia/LatchedInput.o \
src/emucore/tia/PaddleReader.o \ src/emucore/tia/PaddleReader.o \
src/emucore/tia/VblankManager.o \ src/emucore/tia/VblankManager.o
src/emucore/tia/DelayQueueIterator.o
MODULE_DIRS += \ MODULE_DIRS += \
src/emucore/tia src/emucore/tia