From a855d6202536ff28e5aae4f22a0f31d8f5b325d0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 21 Jan 2017 15:18:31 -0500 Subject: Port of Duke Nukem 3D This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9 --- .../sdl/src/main/symbian/EKA2/vectorbuffer.h | 240 +++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h (limited to 'apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h') diff --git a/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h new file mode 100644 index 0000000000..3d8be58d6a --- /dev/null +++ b/apps/plugins/sdl/src/main/symbian/EKA2/vectorbuffer.h @@ -0,0 +1,240 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#ifndef __VECTORBUFFER_H__ +#define __VECTORBUFFER_H__ + +#include +#define VLOG(x) +#define VECPANIC(x) VectorPanic(x, __LINE__) +void VectorPanic(TInt, TInt); + + +//int DEBUG_INT; + +NONSHARABLE_CLASS(TNodeBuffer) + { + public: + protected: + NONSHARABLE_CLASS(TNode) + { + public: + static TNode* Empty(TUint8* iBuffer); + static TNode* New(TNode* aPrev, const TDesC8& aData); + const TUint8* Ptr() const; + TInt Size() const; + inline TNode* Succ(); + static void SetSucc(TNode*& aNode); + void Terminator(TNode* aNode); + private: + TNode* iSucc; + }; + }; + +inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ() + { + return iSucc; + } + +template +NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer + { + public: + TVectorBuffer(); + TInt Append(const TDesC8& aData); + // TInt AppendOverwrite(const TDesC8& aData); + TPtrC8 Shift(); + TPtrC8 operator[](TInt aIndex) const; + TInt Size() const; + private: + TInt GetRoom(TInt aSize) const; + TInt Unreserved() const; + private: + TNode* iTop; + TNode* iBottom; + TInt iSize; + TUint8 iBuffer[C]; + }; + +template +TVectorBuffer::TVectorBuffer() : iSize(0) + { + Mem::FillZ(iBuffer, C); + iTop = TNode::Empty(iBuffer); //these points to buffer + iBottom = TNode::Empty(iBuffer); + } + +template +TInt TVectorBuffer::Unreserved() const + { + __ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt)); + const TInt bytesbetween = + reinterpret_cast(iBottom->Succ()) - + reinterpret_cast(iTop); + const TInt topsize = sizeof(TNode); + if(bytesbetween > 0) //bytesbetween is room between bottom and top + { //therefore free room is subracted from free space + + const TInt room = C - bytesbetween - topsize; + return room; + } + if(bytesbetween == 0) + { + + if(Size() > 0) + return 0; + else + return C - topsize; + } + const TInt room = -bytesbetween - topsize; //free is space between pointers + return room; + } + +template +TInt TVectorBuffer::GetRoom(TInt aSize) const + { + const TInt bytesnew = sizeof(TNode) + aSize; + const TInt room = Unreserved() - bytesnew; + return room; + } + +template +TInt TVectorBuffer::Append(const TDesC8& aData) //ei ole ok! + { + const TInt len = aData.Length(); + if(GetRoom(len) < 0) + { + return KErrOverflow; + } + if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode))))) + { + VLOG("rc"); + // RDebug::Print(_L("vector: append")); + TNode* p = TNode::Empty(iBuffer); + iBottom->Terminator(p); + iBottom = p; + return Append(aData); + // Append(); + // iBottom = TNode::New(p, aData); //just append something into end + } + + //DEBUG_INT++; + + iBottom = TNode::New(iBottom, aData); + + iSize += len; + return KErrNone; + } + +/* +template +TInt TVectorBuffer::AppendOverwrite(const TDesC8& aData) //ei ole ok! + { + while(Append(aData) == KErrOverflow) + { + if(iTop->Succ() == NULL) + { + return KErrUnderflow; + } + //Shift(); //data is lost + } + return KErrNone; + } +*/ +template +TPtrC8 TVectorBuffer::Shift() + { + __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + TNode* node = iTop; + iTop = iTop->Succ(); + if(iTop > node) + { + // DEBUG_INT--; + iSize -= node->Size(); + return TPtrC8(node->Ptr(), node->Size()); + } + else + { + // RDebug::Print(_L("vector: shift")); + return Shift(); //this happens when buffer is terminated, and data lies in next + } + } + +template +TInt TVectorBuffer::Size() const + { + return iSize; + } + +template +TPtrC8 TVectorBuffer::operator[](TInt aIndex) const + { + TInt index = 0; + TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator + while(index < aIndex) + { + TNode* nt = t->Succ(); + if(nt < t) + { + nt = nt->Succ(); + } + t = nt; + if(t->Size() > 0) + index++; + __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + } + return t->Ptr(); + } + + +template +NONSHARABLE_CLASS(TVector) : public TVectorBuffer + { + public: + TVector(); + TInt Append(const T& aData); + const T& Shift(); + TInt Size() const; + const T& operator[](TInt aIndex) const; + }; + +template +TVector::TVector() : TVectorBuffer() + { + } + +template +TInt TVector::Append(const T& aData) + { + const TPckgC data(aData); + return TVectorBuffer::Append(data); + } + +template +const T& TVector::Shift() + { + const TPtrC8 ptr = TVectorBuffer::Shift(); + return *(reinterpret_cast(ptr.Ptr())); + } + + +template +TInt TVector::Size() const + { + return TVectorBuffer::Size() / sizeof(T); + } + +template +const T& TVector::operator[](TInt aIndex) const + { + const TPtrC8 ptr = TVectorBuffer::operator[](aIndex); + return *(reinterpret_cast(ptr.Ptr())); + } + +#endif + + -- cgit v1.2.3