Initial round of particle runtime implementations

This commit is contained in:
Jack Andersen 2016-02-04 15:27:03 -10:00
parent cf2464a02b
commit 7a35dac972
46 changed files with 885 additions and 146 deletions

View File

@ -85,7 +85,7 @@ class CArchitectureMessage
{ {
EArchMsgTarget x0_target; EArchMsgTarget x0_target;
EArchMsgType x4_type; EArchMsgType x4_type;
rstl::rc_ptr<IArchMsgParm> x8_parm; std::shared_ptr<IArchMsgParm> x8_parm;
public: public:
CArchitectureMessage(EArchMsgTarget target, EArchMsgType type, IArchMsgParm* parm) CArchitectureMessage(EArchMsgTarget target, EArchMsgType type, IArchMsgParm* parm)
: x0_target(target), x4_type(type), x8_parm(parm) {} : x0_target(target), x4_type(type), x8_parm(parm) {}

View File

@ -2,7 +2,7 @@
#define __RETRO_CIOWIN_HPP__ #define __RETRO_CIOWIN_HPP__
#include <string> #include <string>
#include "rstl.hpp" #include <memory>
namespace Retro namespace Retro
{ {
@ -31,7 +31,7 @@ public:
size_t GetNameHash() const {return m_nameHash;} size_t GetNameHash() const {return m_nameHash;}
}; };
static bool operator==(rstl::rc_ptr<CIOWin> a, rstl::rc_ptr<CIOWin> b) static bool operator==(std::shared_ptr<CIOWin> a, std::shared_ptr<CIOWin> b)
{ {
return a.get() == b.get(); return a.get() == b.get();
} }

View File

@ -20,7 +20,7 @@ bool CIOWinManager::OnIOWinMessage(const CArchitectureMessage& msg)
case EArchMsgType::CreateIOWin: case EArchMsgType::CreateIOWin:
{ {
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmCreateIOWin(msg); const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmCreateIOWin(msg);
rstl::rc_ptr<CIOWin> iow(static_cast<CIOWin*>(parm.xc_parm3)); std::shared_ptr<CIOWin> iow(static_cast<CIOWin*>(parm.xc_parm3));
AddIOWin(iow, parm.x4_parm1, parm.x8_parm2); AddIOWin(iow, parm.x4_parm1, parm.x8_parm2);
return false; return false;
} }
@ -146,14 +146,14 @@ CIOWin* CIOWinManager::FindIOWin(const std::string& name)
return nullptr; return nullptr;
} }
rstl::rc_ptr<CIOWin> CIOWinManager::FindAndShareIOWin(const std::string& name) std::shared_ptr<CIOWin> CIOWinManager::FindAndShareIOWin(const std::string& name)
{ {
size_t findHash = std::hash<std::string>()(name); size_t findHash = std::hash<std::string>()(name);
IOWinPQNode* node = x4_pumpRoot; IOWinPQNode* node = x4_pumpRoot;
while (node) while (node)
{ {
rstl::rc_ptr<CIOWin> iow = node->ShareIOWin(); std::shared_ptr<CIOWin> iow = node->ShareIOWin();
if (iow->GetNameHash() == findHash) if (iow->GetNameHash() == findHash)
return iow; return iow;
node = node->x8_next; node = node->x8_next;
@ -162,13 +162,13 @@ rstl::rc_ptr<CIOWin> CIOWinManager::FindAndShareIOWin(const std::string& name)
node = x0_drawRoot; node = x0_drawRoot;
while (node) while (node)
{ {
rstl::rc_ptr<CIOWin> iow = node->ShareIOWin(); std::shared_ptr<CIOWin> iow = node->ShareIOWin();
if (iow->GetNameHash() == findHash) if (iow->GetNameHash() == findHash)
return iow; return iow;
node = node->x8_next; node = node->x8_next;
} }
return rstl::rc_ptr<CIOWin>(); return std::shared_ptr<CIOWin>();
} }
void CIOWinManager::ChangeIOWinPriority(CIOWin* toChange, int pumpPrio, int drawPrio) void CIOWinManager::ChangeIOWinPriority(CIOWin* toChange, int pumpPrio, int drawPrio)
@ -289,7 +289,7 @@ void CIOWinManager::RemoveIOWin(CIOWin* chIow)
} }
} }
void CIOWinManager::AddIOWin(rstl::ncrc_ptr<CIOWin> chIow, int pumpPrio, int drawPrio) void CIOWinManager::AddIOWin(std::weak_ptr<CIOWin> chIow, int pumpPrio, int drawPrio)
{ {
IOWinPQNode* node = x4_pumpRoot; IOWinPQNode* node = x4_pumpRoot;
IOWinPQNode* prevNode = nullptr; IOWinPQNode* prevNode = nullptr;

View File

@ -14,13 +14,13 @@ class CIOWinManager
{ {
struct IOWinPQNode struct IOWinPQNode
{ {
rstl::rc_ptr<CIOWin> x0_iowin; std::shared_ptr<CIOWin> x0_iowin;
int x4_prio; int x4_prio;
CIOWinManager::IOWinPQNode* x8_next; CIOWinManager::IOWinPQNode* x8_next;
IOWinPQNode(rstl::ncrc_ptr<CIOWin> iowin, int prio, IOWinPQNode(std::weak_ptr<CIOWin> iowin, int prio,
CIOWinManager::IOWinPQNode* next) CIOWinManager::IOWinPQNode* next)
: x0_iowin(iowin), x4_prio(prio), x8_next(next) {} : x0_iowin(iowin), x4_prio(prio), x8_next(next) {}
rstl::rc_ptr<CIOWin> ShareIOWin() const {return rstl::rc_ptr<CIOWin>(x0_iowin);} std::shared_ptr<CIOWin> ShareIOWin() const {return std::shared_ptr<CIOWin>(x0_iowin);}
CIOWin* GetIOWin() const {return x0_iowin.get();} CIOWin* GetIOWin() const {return x0_iowin.get();}
}; };
IOWinPQNode* x0_drawRoot = nullptr; IOWinPQNode* x0_drawRoot = nullptr;
@ -32,11 +32,11 @@ public:
bool DistributeOneMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue); bool DistributeOneMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
void PumpMessages(CArchitectureQueue& queue); void PumpMessages(CArchitectureQueue& queue);
CIOWin* FindIOWin(const std::string& name); CIOWin* FindIOWin(const std::string& name);
rstl::rc_ptr<CIOWin> FindAndShareIOWin(const std::string& name); std::shared_ptr<CIOWin> FindAndShareIOWin(const std::string& name);
void ChangeIOWinPriority(CIOWin* toChange, int pumpPrio, int drawPrio); void ChangeIOWinPriority(CIOWin* toChange, int pumpPrio, int drawPrio);
void RemoveAllIOWins(); void RemoveAllIOWins();
void RemoveIOWin(CIOWin* toRemove); void RemoveIOWin(CIOWin* toRemove);
void AddIOWin(rstl::ncrc_ptr<CIOWin> toAdd, int pumpPrio, int drawPrio); void AddIOWin(std::weak_ptr<CIOWin> toAdd, int pumpPrio, int drawPrio);
}; };
} }

View File

@ -1,4 +1,4 @@
include_directories(${BOO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
add_subdirectory(Audio) add_subdirectory(Audio)
add_subdirectory(Character) add_subdirectory(Character)

View File

@ -4,6 +4,7 @@
#include <unordered_map> #include <unordered_map>
#include "IFactory.hpp" #include "IFactory.hpp"
#include "CResLoader.hpp" #include "CResLoader.hpp"
#include "IVParamObj.hpp"
namespace Retro namespace Retro
{ {
@ -15,15 +16,16 @@ class CResFactory : public IFactory
public: public:
struct SLoadingData struct SLoadingData
{ {
SObjectTag tag; SObjectTag x0_tag;
IDvdRequest* dvdReq; IDvdRequest* x8_dvdReq;
IObj** targetPtr; IObj** xc_targetPtr;
void* loadBuffer; void* x10_loadBuffer;
u32 resSize; u32 x14_resSize;
CVParamTransfer x18_cvXfer;
}; };
private: private:
std::unordered_map<SObjectTag, SLoadingData> m_loadList; std::unordered_map<SObjectTag, SLoadingData> m_loadList;
void AddToLoadList(const SLoadingData& data) {m_loadList[data.tag] = data;} void AddToLoadList(const SLoadingData& data) {m_loadList[data.x0_tag] = data;}
public: public:
CResLoader& GetLoader() {return x4_loader;} CResLoader& GetLoader() {return x4_loader;}
std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&); std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&);

View File

@ -1,7 +1,44 @@
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "IVParamObj.hpp" #include "IVParamObj.hpp"
#include "CToken.hpp"
namespace Retro namespace Retro
{ {
CSimplePool::CSimplePool(IFactory& factory)
: x30_factory(factory), x34_paramXfer(new TObjOwnerParam<IObjectStore*>(this))
{}
CToken CSimplePool::GetObj(const SObjectTag&, const CVParamTransfer&)
{
}
CToken CSimplePool::GetObj(const SObjectTag&)
{
}
CToken CSimplePool::GetObj(char const*)
{
}
CToken CSimplePool::GetObj(char const*, const CVParamTransfer&)
{
}
void CSimplePool::HasObject(const SObjectTag&) const
{
}
void CSimplePool::ObjectIsLive(const SObjectTag&) const
{
}
void CSimplePool::Flush()
{
}
void CSimplePool::ObjectUnreferenced(const SObjectTag&)
{
}
} }

View File

@ -2,28 +2,31 @@
#define __RETRO_CSIMPLEPOOL_HPP__ #define __RETRO_CSIMPLEPOOL_HPP__
#include "IObjectStore.hpp" #include "IObjectStore.hpp"
#include "RetroTypes.hpp"
#include "IVParamObj.hpp"
#include <unordered_map>
namespace Retro namespace Retro
{ {
class IFactory; class IFactory;
class CObjectReference;
class CSimplePool : public IObjectStore class CSimplePool : public IObjectStore
{ {
IFactory& m_factory; std::unordered_map<SObjectTag, CObjectReference*> x4_resources;
IFactory& x30_factory;
CVParamTransfer x34_paramXfer;
public: public:
CSimplePool(IFactory& factory) CSimplePool(IFactory& factory);
: m_factory(factory) CToken GetObj(const SObjectTag&, const CVParamTransfer&);
{ CToken GetObj(const SObjectTag&);
} CToken GetObj(char const*);
IObj* GetObj(const SObjectTag&, const CVParamTransfer&) {return nullptr;} CToken GetObj(char const*, const CVParamTransfer&);
IObj* GetObj(const SObjectTag&) {return nullptr;} void HasObject(const SObjectTag&) const;
IObj* GetObj(char const*) {return nullptr;} void ObjectIsLive(const SObjectTag&) const;
IObj* GetObj(char const*, const CVParamTransfer&) {return nullptr;} IFactory& GetFactory() const {return x30_factory;}
void HasObject(const SObjectTag&) const {} void Flush();
void ObjectIsLive(const SObjectTag&) const {} void ObjectUnreferenced(const SObjectTag&);
IFactory& GetFactory() const {return m_factory;}
void Flush() {}
void ObjectUnreferenced(const SObjectTag&) {}
}; };
} }

View File

@ -15,23 +15,44 @@ class IObj;
class CObjectReference class CObjectReference
{ {
friend class CToken;
u16 x0_refCount = 0; u16 x0_refCount = 0;
bool x3_loading = false; u16 x2_lockCount = 0;
bool x3_loading = false; /* Rightmost bit of lockCount */
SObjectTag x4_objTag; SObjectTag x4_objTag;
IObjectStore* xC_objectStore = nullptr; IObjectStore* xC_objectStore = nullptr;
std::unique_ptr<IObj> x10_object; IObj* x10_object = nullptr;
CVParamTransfer x14_params; CVParamTransfer x14_params;
public: public:
CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj, CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj,
const SObjectTag& objTag, CVParamTransfer buildParams) const SObjectTag& objTag, CVParamTransfer buildParams)
: x4_objTag(objTag), xC_objectStore(&objStore), : x4_objTag(objTag), xC_objectStore(&objStore),
x10_object(std::move(obj)), x14_params(buildParams) {} x10_object(obj.release()), x14_params(buildParams) {}
CObjectReference(std::unique_ptr<IObj>&& obj); CObjectReference(std::unique_ptr<IObj>&& obj)
: x10_object(obj.release()) {}
bool IsLoading() const {return x3_loading;} bool IsLoading() const {return x3_loading;}
void Unlock() {} void Unlock()
void Lock() {} {
u32 RemoveReference() --x2_lockCount;
if (x2_lockCount)
return;
if (x10_object && xC_objectStore)
Unload();
else if (IsLoading())
CancelLoad();
}
void Lock()
{
++x2_lockCount;
if (!x10_object && !x3_loading)
{
IFactory& fac = xC_objectStore->GetFactory();
fac.BuildAsync(x4_objTag, x14_params, &x10_object);
x3_loading = true;
}
}
u16 RemoveReference()
{ {
--x0_refCount; --x0_refCount;
if (x0_refCount == 0) if (x0_refCount == 0)
@ -42,31 +63,51 @@ public:
CancelLoad(); CancelLoad();
xC_objectStore->ObjectUnreferenced(x4_objTag); xC_objectStore->ObjectUnreferenced(x4_objTag);
} }
return x0_refCount;
}
void CancelLoad()
{
if (xC_objectStore && IsLoading())
{
xC_objectStore->GetFactory().CancelBuild(x4_objTag);
x3_loading = false;
}
} }
void CancelLoad() {}
void Unload() void Unload()
{ {
x10_object.reset(nullptr); delete x10_object;
x10_object = nullptr;
x3_loading = false; x3_loading = false;
} }
IObj& GetObject() IObj* GetObject()
{ {
IFactory& factory = xC_objectStore->GetFactory(); if (!x10_object)
factory.Build(x4_objTag, x14_params); {
IFactory& factory = xC_objectStore->GetFactory();
x10_object = factory.Build(x4_objTag, x14_params).release();
}
x3_loading = false;
return x10_object;
}
~CObjectReference()
{
if (x10_object)
delete x10_object;
else if (x3_loading)
xC_objectStore->GetFactory().CancelBuild(x4_objTag);
} }
}; };
class CToken class CToken
{ {
CObjectReference& x0_objRef; CObjectReference* x0_objRef = nullptr;
bool x4_lockHeld = false; bool x4_lockHeld = false;
public: public:
void Unlock() void Unlock()
{ {
if (x4_lockHeld) if (x4_lockHeld)
{ {
x0_objRef.Unlock(); x0_objRef->Unlock();
x4_lockHeld = false; x4_lockHeld = false;
} }
} }
@ -74,33 +115,77 @@ public:
{ {
if (!x4_lockHeld) if (!x4_lockHeld)
{ {
x0_objRef.Lock(); x0_objRef->Lock();
x4_lockHeld = true; x4_lockHeld = true;
} }
} }
void RemoveRef() void RemoveRef()
{ {
if (x0_objRef->RemoveReference() == 0)
{
delete x0_objRef;
x0_objRef = nullptr;
}
} }
IObj& GetObj() IObj* GetObj()
{ {
Lock(); Lock();
return x0_objRef.GetObject(); return x0_objRef->GetObject();
} }
CToken& operator=(CToken&& other) CToken& operator=(const CToken& other)
{ {
Unlock();
RemoveRef();
x0_objRef = other.x0_objRef;
++x0_objRef->x0_refCount;
if (other.x4_lockHeld)
Lock();
return *this;
}
CToken() {}
CToken(const CToken& other)
: x0_objRef(other.x0_objRef)
{
++x0_objRef->x0_refCount;
}
CToken(IObj* obj)
{
x0_objRef = new CObjectReference(std::unique_ptr<IObj>(obj));
++x0_objRef->x0_refCount;
Lock();
}
CToken(CObjectReference* obj)
{
x0_objRef = obj;
++x0_objRef->x0_refCount;
} }
~CToken() ~CToken()
{ {
if (x0_objRef && x4_lockHeld) if (x4_lockHeld)
x0_objRef->Unlock(); x0_objRef->Unlock();
RemoveRef();
} }
}; };
template<class T> template<class T>
class TLockedToken class TToken : public CToken
{ {
public:
static std::unique_ptr<TObjOwnerDerivedFromIObj<T>> GetIObjObjectFor(std::unique_ptr<T>&& obj)
{
return TObjOwnerDerivedFromIObj<T>::GetNewDerivedObject(std::move(obj));
}
TToken() {}
TToken(T* obj)
: CToken(GetIObjObjectFor(std::unique_ptr<T>(obj))) {}
TToken& operator=(T* obj) {*this = CToken(GetIObjObjectFor(obj)); return this;}
};
template<class T>
class TLockedToken : public TToken<T>
{
public:
using TToken<T>::TToken;
}; };
} }

View File

@ -9,14 +9,14 @@ namespace Retro
class IObj class IObj
{ {
public: public:
virtual ~IObj() {} virtual ~IObj() = default;
}; };
class TObjOwnerDerivedFromIObjUntyped : public IObj class TObjOwnerDerivedFromIObjUntyped : public IObj
{ {
protected: protected:
IObj* m_objPtr; void* m_objPtr;
TObjOwnerDerivedFromIObjUntyped(IObj* objPtr) : m_objPtr(objPtr) {} TObjOwnerDerivedFromIObjUntyped(void* objPtr) : m_objPtr(objPtr) {}
}; };
template<class T> template<class T>
@ -26,23 +26,12 @@ class TObjOwnerDerivedFromIObj : public TObjOwnerDerivedFromIObjUntyped
public: public:
static std::unique_ptr<TObjOwnerDerivedFromIObj<T>> GetNewDerivedObject(std::unique_ptr<T>&& obj) static std::unique_ptr<TObjOwnerDerivedFromIObj<T>> GetNewDerivedObject(std::unique_ptr<T>&& obj)
{ {
std::unique_ptr<T> movedObjPtr = std::move(obj);
return std::unique_ptr<TObjOwnerDerivedFromIObj<T>> return std::unique_ptr<TObjOwnerDerivedFromIObj<T>>
(new TObjOwnerDerivedFromIObj<T>(movedObjPtr.release())); (new TObjOwnerDerivedFromIObj<T>(obj.release()));
} }
~TObjOwnerDerivedFromIObj() {delete static_cast<T*>(m_objPtr);} ~TObjOwnerDerivedFromIObj() {delete static_cast<T*>(m_objPtr);}
}; };
template<class T>
class TToken
{
public:
static std::unique_ptr<TObjOwnerDerivedFromIObj<T>> GetIObjObjectFor(std::unique_ptr<T>&& obj)
{
return TObjOwnerDerivedFromIObj<T>::GetNewDerivedObject(std::move(obj));
}
};
} }
#endif // __RETRO_IOBJ_HPP__ #endif // __RETRO_IOBJ_HPP__

View File

@ -6,15 +6,15 @@ namespace Retro
struct SObjectTag; struct SObjectTag;
class CVParamTransfer; class CVParamTransfer;
class IFactory; class IFactory;
class IObj; class CToken;
class IObjectStore class IObjectStore
{ {
public: public:
virtual IObj* GetObj(const SObjectTag&, const CVParamTransfer&)=0; virtual CToken GetObj(const SObjectTag&, const CVParamTransfer&)=0;
virtual IObj* GetObj(const SObjectTag&)=0; virtual CToken GetObj(const SObjectTag&)=0;
virtual IObj* GetObj(char const*)=0; virtual CToken GetObj(char const*)=0;
virtual IObj* GetObj(char const*, const CVParamTransfer&)=0; virtual CToken GetObj(char const*, const CVParamTransfer&)=0;
virtual void HasObject(const SObjectTag&) const=0; virtual void HasObject(const SObjectTag&) const=0;
virtual void ObjectIsLive(const SObjectTag&) const=0; virtual void ObjectIsLive(const SObjectTag&) const=0;
virtual IFactory& GetFactory() const=0; virtual IFactory& GetFactory() const=0;

View File

@ -15,7 +15,7 @@ public:
class CVParamTransfer class CVParamTransfer
{ {
rstl::rc_ptr<IVParamObj> m_ref; std::shared_ptr<IVParamObj> m_ref;
public: public:
CVParamTransfer(); CVParamTransfer();
CVParamTransfer(IVParamObj* obj) : m_ref(obj) {} CVParamTransfer(IVParamObj* obj) : m_ref(obj) {}
@ -34,6 +34,7 @@ protected:
~TObjOwnerParam() {} ~TObjOwnerParam() {}
public: public:
TObjOwnerParam(T&& obj) : m_param(std::move(obj)) {} TObjOwnerParam(T&& obj) : m_param(std::move(obj)) {}
T& GetParam() {return m_param;}
}; };
} }

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CCOLORELEMENT_HPP__
#define __RETRO_CCOLORELEMENT_HPP__
namespace Retro
{
class CColorElement
{
};
}
#endif // __RETRO_CCOLORELEMENT_HPP__

View File

View File

@ -0,0 +1,4 @@
#ifndef __RETRO_CDECALDATAFACTORY_HPP__
#define __RETRO_CDECALDATAFACTORY_HPP__
#endif // __RETRO_CDECALDATAFACTORY_HPP__

View File

View File

@ -0,0 +1,4 @@
#ifndef __RETRO_CDECALDESCRIPTION_HPP__
#define __RETRO_CDECALDESCRIPTION_HPP__
#endif // __RETRO_CDECALDESCRIPTION_HPP__

View File

@ -0,0 +1,4 @@
#ifndef __RETRO_CELECTRICDESCRIPTION_HPP__
#define __RETRO_CELECTRICDESCRIPTION_HPP__
#endif // __RETRO_CELECTRICDESCRIPTION_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CEMITTERELEMENT_HPP__
#define __RETRO_CEMITTERELEMENT_HPP__
namespace Retro
{
class CEmitterElement
{
};
}
#endif // __RETRO_CEMITTERELEMENT_HPP__

View File

View File

@ -0,0 +1,116 @@
#ifndef __RETRO_CGENDESCRIPTION_HPP__
#define __RETRO_CGENDESCRIPTION_HPP__
#include <memory>
#include "CRealElement.hpp"
#include "CIntElement.hpp"
#include "CVectorElement.hpp"
#include "CModVectorElement.hpp"
#include "CColorElement.hpp"
#include "CUVElement.hpp"
#include "CEmitterElement.hpp"
#include "CSpawnSystemKeyframeData.hpp"
#include "CParticleDataFactory.hpp"
namespace Retro
{
class CGenDescription
{
public:
std::unique_ptr<CVectorElement> x0_PSIV;
std::unique_ptr<CModVectorElement> x4_PSVM;
std::unique_ptr<CVectorElement> x8_PSOV;
std::unique_ptr<CIntElement> xc_PSLT;
std::unique_ptr<CIntElement> x10_PSWT;
std::unique_ptr<CRealElement> x14_PSTS;
std::unique_ptr<CVectorElement> x18_POFS;
std::unique_ptr<CIntElement> x1c_PMED;
std::unique_ptr<CRealElement> x20_LENG;
std::unique_ptr<CRealElement> x24_WIDT;
std::unique_ptr<CIntElement> x28_MAXP;
std::unique_ptr<CRealElement> x2c_GRTE;
std::unique_ptr<CColorElement> x30_COLR;
std::unique_ptr<CIntElement> x34_LTME;
std::unique_ptr<CVectorElement> x38_ILOC;
std::unique_ptr<CVectorElement> x3c_IVEC;
std::unique_ptr<CEmitterElement> x40_EMTR;
union
{
struct
{
bool x44_28_SORT : 1; bool x44_30_MBLR : 1; bool x44_24_LINE : 1; bool x44_29_LIT_ : 1;
bool x44_26_AAPH : 1; bool x44_27_ZBUF : 1; bool x44_25_FXLL : 1; bool x44_31_PMAB : 1;
bool x45_29_VMD4 : 1; bool x45_28_VMD3 : 1; bool x45_27_VMD2 : 1; bool x45_26_VMD1 : 1;
bool x45_31_OPTS : 1; bool x45_24_PMUS : 1; bool x45_25_PMOO : 1; bool x45_30_CIND : 1;
};
uint16_t dummy1 = 0;
};
std::unique_ptr<CIntElement> x48_MBSP;
std::unique_ptr<CRealElement> x4c_SIZE;
std::unique_ptr<CRealElement> x50_ROTA;
std::unique_ptr<CUVElement> x54_TEXR;
std::unique_ptr<CUVElement> x58_TIND;
SParticleModel x5c_PMDL;
std::unique_ptr<CVectorElement> x6c_PMOP;
std::unique_ptr<CVectorElement> x70_PMRT;
std::unique_ptr<CVectorElement> x74_PMSC;
std::unique_ptr<CColorElement> x78_PMCL;
std::unique_ptr<CModVectorElement> x7c_VEL1;
std::unique_ptr<CModVectorElement> x80_VEL2;
std::unique_ptr<CModVectorElement> x84_VEL3;
std::unique_ptr<CModVectorElement> x88_VEL4;
SChildGeneratorDesc x8c_ICTS;
std::unique_ptr<CIntElement> x9c_NCSY;
std::unique_ptr<CIntElement> xa0_CSSD;
SChildGeneratorDesc xa4_IDTS;
std::unique_ptr<CIntElement> xb4_NDSY;
SChildGeneratorDesc xb8_IITS;
std::unique_ptr<CIntElement> xc8_PISY;
std::unique_ptr<CIntElement> xcc_SISY;
std::unique_ptr<CSpawnSystemKeyframeData> xd0_KSSM;
SSwooshGeneratorDesc xd4_SSWH;
std::unique_ptr<CIntElement> xe4_SSSD;
std::unique_ptr<CVectorElement> xe8_SSPO;
std::unique_ptr<CIntElement> xf8_SESD;
std::unique_ptr<CVectorElement> xfc_SEPO;
SChildGeneratorDesc xec_PMLC;
std::unique_ptr<CIntElement> x100_LTYP;
std::unique_ptr<CColorElement> x104_LCLR;
std::unique_ptr<CRealElement> x108_LINT;
std::unique_ptr<CVectorElement> x10c_LOFF;
std::unique_ptr<CVectorElement> x110_LDIR;
std::unique_ptr<CIntElement> x114_LFOT;
std::unique_ptr<CRealElement> x118_LFOR;
std::unique_ptr<CRealElement> x11c_LSLA;
/* 0-00 additions */
std::unique_ptr<CIntElement> x10_SEED;
SElectricGeneratorDesc xd8_SELC;
union
{
struct
{
bool x30_30_ORNT : 1;
bool x30_31_RSOP : 1;
};
uint16_t dummy2 = 0;
};
std::unique_ptr<CRealElement> x10c_ADV1;
std::unique_ptr<CRealElement> x110_ADV2;
std::unique_ptr<CRealElement> x114_ADV3;
std::unique_ptr<CRealElement> x118_ADV4;
std::unique_ptr<CRealElement> x11c_ADV5;
std::unique_ptr<CRealElement> x120_ADV6;
std::unique_ptr<CRealElement> x124_ADV7;
std::unique_ptr<CRealElement> x128_ADV8;
CGenDescription()
{
x45_25_PMOO = true;
}
};
}
#endif // __RETRO_CGENDESCRIPTION_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CINTELEMENT_HPP__
#define __RETRO_CINTELEMENT_HPP__
namespace Retro
{
class CIntElement
{
};
}
#endif // __RETRO_CINTELEMENT_HPP__

View File

@ -1,7 +1,22 @@
add_library(RuntimeCommonParticle add_library(RuntimeCommonParticle
CGenDescription.hpp CGenDescription.cpp
CRealElement.hpp CRealElement.cpp
CIntElement.hpp CIntElement.cpp
CVectorElement.hpp CVectorElement.cpp
CModVectorElement.hpp CModVectorElement.cpp
CColorElement.hpp CColorElement.cpp
CUVElement.hpp CUVElement.cpp
CEmitterElement.hpp CEmitterElement.cpp
CParticleDataFactory.hpp CParticleDataFactory.cpp
CSwooshDescription.hpp CSwooshDescription.cpp
CElectricDescription.hpp CElectricDescription.cpp
CDecalDescription.hpp CDecalDescription.cpp
CWeaponDescription.hpp CWeaponDescription.cpp
CDecalDataFactory.hpp CDecalDataFactory.cpp
CParticleGen.hpp CParticleGen.cpp CParticleGen.hpp CParticleGen.cpp
CElementGen.hpp CElementGen.cpp CElementGen.hpp CElementGen.cpp
CParticleSwoosh.hpp CParticleSwoosh.cpp CParticleSwoosh.hpp CParticleSwoosh.cpp
CParticleElectric.hpp CParticleElectric.cpp CParticleElectric.hpp CParticleElectric.cpp
CDecalManager.hpp CDecalManager.cpp CDecalManager.hpp CDecalManager.cpp
CSpawnSystemKeyframeData.hpp CSpawnSystemKeyframeData.cpp
CWarp.hpp CWarp.cpp) CWarp.hpp CWarp.cpp)

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CMODVECTORELEMENT_HPP__
#define __RETRO_CMODVECTORELEMENT_HPP__
namespace Retro
{
class CModVectorElement
{
};
}
#endif // __RETRO_CMODVECTORELEMENT_HPP__

View File

@ -0,0 +1,343 @@
#include "CParticleDataFactory.hpp"
#include "CToken.hpp"
#include "CSimplePool.hpp"
#include "CGenDescription.hpp"
namespace Retro
{
static LogVisor::LogModule Log("Retro::CParticleDataFactory");
float CParticleDataFactory::GetReal(CInputStream& in)
{
return in.readFloatBig();
}
int32_t CParticleDataFactory::GetInt(CInputStream& in)
{
return in.readInt32Big();
}
bool CParticleDataFactory::GetBool(CInputStream& in)
{
FourCC cid = GetClassID(in);
if (cid != FOURCC('CNST'))
Log.report(LogVisor::FatalError, "bool element does not begin with CNST");
return in.readBool();
}
FourCC CParticleDataFactory::GetClassID(CInputStream& in)
{
uint32_t val;
in.readBytesToBuf(&val, 4);
return val;
}
CGenDescription* CParticleDataFactory::GetGeneratorDesc(CInputStream& in, CSimplePool* resPool)
{
std::vector<TResID> tracker;
tracker.reserve(8);
return CreateGeneratorDescription(in, tracker, 0, resPool);
}
CGenDescription* CParticleDataFactory::CreateGeneratorDescription(CInputStream& in, std::vector<TResID>& tracker,
TResID resId, CSimplePool* resPool)
{
if (std::count(tracker.cbegin(), tracker.cend(), resId) == 0)
{
tracker.push_back(resId);
FourCC cid = GetClassID(in);
if (cid == FOURCC('GPSM'))
{
CGenDescription* ret = new CGenDescription;
CreateGPSM(ret, in, tracker, resPool);
LoadGPSMTokens(ret);
return ret;
}
}
return nullptr;
}
bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& in,
std::vector<TResID>& tracker, CSimplePool* resPool)
{
FourCC clsId = GetClassID(in);
while (clsId != SBIG('_END'))
{
switch (clsId)
{
case SBIG('PMCL'):
fillDesc->x78_PMCL.reset(GetColorElement(in));
break;
case SBIG('LFOR'):
fillDesc->x118_LFOR.reset(GetRealElement(in));
break;
case SBIG('IDTS'):
fillDesc->xa4_IDTS = GetChildGeneratorDesc(in, resPool, tracker);
break;
case SBIG('EMTR'):
fillDesc->x40_EMTR.reset(GetEmitterElement(in));
break;
case SBIG('COLR'):
fillDesc->x30_COLR.reset(GetColorElement(in));
break;
case SBIG('CIND'):
fillDesc->x45_30_CIND = GetBool(in);
break;
case SBIG('AAPH'):
fillDesc->x44_26_AAPH = GetBool(in);
break;
case SBIG('CSSD'):
fillDesc->xa0_CSSD.reset(GetIntElement(in));
break;
case SBIG('GRTE'):
fillDesc->x2c_GRTE.reset(GetRealElement(in));
break;
case SBIG('FXLL'):
fillDesc->x44_25_FXLL = GetBool(in);
break;
case SBIG('ICTS'):
fillDesc->x8c_ICTS = GetChildGeneratorDesc(in, resPool, tracker);
break;
case SBIG('KSSM'):
{
fillDesc->xd0_KSSM.reset();
FourCC cid = GetClassID(in);
if (cid != SBIG('CNST'))
break;
fillDesc->xd0_KSSM.reset(new CSpawnSystemKeyframeData(in));
fillDesc->xd0_KSSM->LoadAllSpawnedSystemTokens(resPool);
break;
}
case SBIG('ILOC'):
fillDesc->x38_ILOC.reset(GetVectorElement(in));
break;
case SBIG('IITS'):
fillDesc->xb8_IITS = GetChildGeneratorDesc(in, resPool, tracker);
break;
case SBIG('IVEC'):
fillDesc->x3c_IVEC.reset(GetVectorElement(in));
break;
case SBIG('LDIR'):
fillDesc->x110_LDIR.reset(GetVectorElement(in));
break;
case SBIG('LCLR'):
fillDesc->x104_LCLR.reset(GetColorElement(in));
break;
case SBIG('LENG'):
fillDesc->x20_LENG.reset(GetRealElement(in));
break;
case SBIG('MAXP'):
fillDesc->x28_MAXP.reset(GetIntElement(in));
break;
case SBIG('LOFF'):
fillDesc->x10c_LOFF.reset(GetVectorElement(in));
break;
case SBIG('LINT'):
fillDesc->x108_LINT.reset(GetRealElement(in));
break;
case SBIG('LINE'):
fillDesc->x44_24_LINE = GetBool(in);
break;
case SBIG('LFOT'):
fillDesc->x114_LFOT.reset(GetIntElement(in));
break;
case SBIG('LIT_'):
fillDesc->x44_29_LIT_ = GetBool(in);
break;
case SBIG('LTME'):
fillDesc->x34_LTME.reset(GetIntElement(in));
break;
case SBIG('LSLA'):
fillDesc->x11c_LSLA.reset(GetRealElement(in));
break;
case SBIG('LTYP'):
fillDesc->x100_LTYP.reset(GetIntElement(in));
break;
case SBIG('NDSY'):
fillDesc->xb4_NDSY.reset(GetIntElement(in));
break;
case SBIG('MBSP'):
fillDesc->x48_MBSP.reset(GetIntElement(in));
break;
case SBIG('MBLR'):
fillDesc->x44_30_MBLR = GetBool(in);
break;
case SBIG('NCSY'):
fillDesc->x9c_NCSY.reset(GetIntElement(in));
break;
case SBIG('PISY'):
fillDesc->xc8_PISY.reset(GetIntElement(in));
break;
case SBIG('OPTS'):
fillDesc->x45_31_OPTS = GetBool(in);
break;
case SBIG('PMAB'):
fillDesc->x44_31_PMAB = GetBool(in);
break;
case SBIG('SESD'):
fillDesc->xf8_SESD.reset(GetIntElement(in));
break;
case SBIG('SEPO'):
fillDesc->xfc_SEPO.reset(GetVectorElement(in));
break;
case SBIG('PSLT'):
fillDesc->xc_PSLT.reset(GetIntElement(in));
break;
case SBIG('PMSC'):
fillDesc->x74_PMSC.reset(GetVectorElement(in));
break;
case SBIG('PMOP'):
fillDesc->x6c_PMOP.reset(GetVectorElement(in));
break;
case SBIG('PMDL'):
fillDesc->x5c_PMDL = GetModel(in, resPool);
break;
case SBIG('PMRT'):
fillDesc->x70_PMRT.reset(GetVectorElement(in));
break;
case SBIG('POFS'):
fillDesc->x18_POFS.reset(GetVectorElement(in));
break;
case SBIG('PMUS'):
fillDesc->x45_24_PMUS = GetBool(in);
break;
case SBIG('PSIV'):
fillDesc->x0_PSIV.reset(GetVectorElement(in));
break;
case SBIG('ROTA'):
fillDesc->x50_ROTA.reset(GetRealElement(in));
break;
case SBIG('PSVM'):
fillDesc->x4_PSVM.reset(GetModVectorElement(in));
break;
case SBIG('PSTS'):
fillDesc->x14_PSTS.reset(GetRealElement(in));
break;
case SBIG('PSOV'):
fillDesc->x8_PSOV.reset(GetVectorElement(in));
break;
case SBIG('PSWT'):
fillDesc->x10_PSWT.reset(GetIntElement(in));
break;
case SBIG('PMLC'):
fillDesc->xec_PMLC = GetChildGeneratorDesc(in, resPool, tracker);
break;
case SBIG('PMED'):
fillDesc->x1c_PMED.reset(GetIntElement(in));
break;
case SBIG('PMOO'):
fillDesc->x45_25_PMOO = GetBool(in);
break;
case SBIG('SSSD'):
fillDesc->xe4_SSSD.reset(GetIntElement(in));
break;
case SBIG('SORT'):
fillDesc->x44_28_SORT = GetBool(in);
break;
case SBIG('SIZE'):
fillDesc->x4c_SIZE.reset(GetRealElement(in));
break;
case SBIG('SISY'):
fillDesc->xcc_SISY.reset(GetIntElement(in));
break;
case SBIG('SSPO'):
fillDesc->xe8_SSPO.reset(GetVectorElement(in));
break;
case SBIG('TEXR'):
fillDesc->x54_TEXR.reset(GetTextureElement(in, resPool));
break;
case SBIG('SSWH'):
fillDesc->xd4_SSWH = GetSwooshGeneratorDesc(in, resPool);
break;
case SBIG('TIND'):
fillDesc->x58_TIND.reset(GetTextureElement(in, resPool));
break;
case SBIG('VMD4'):
fillDesc->x45_29_VMD4 = GetBool(in);
break;
case SBIG('VMD3'):
fillDesc->x45_28_VMD3 = GetBool(in);
break;
case SBIG('VMD2'):
fillDesc->x45_27_VMD2 = GetBool(in);
break;
case SBIG('VMD1'):
fillDesc->x45_26_VMD1 = GetBool(in);
break;
case SBIG('VEL4'):
fillDesc->x88_VEL4.reset(GetModVectorElement(in));
break;
case SBIG('VEL3'):
fillDesc->x84_VEL3.reset(GetModVectorElement(in));
break;
case SBIG('VEL2'):
fillDesc->x80_VEL2.reset(GetModVectorElement(in));
break;
case SBIG('VEL1'):
fillDesc->x7c_VEL1.reset(GetModVectorElement(in));
break;
case SBIG('ZBUF'):
fillDesc->x44_27_ZBUF = GetBool(in);
break;
case SBIG('WIDT'):
fillDesc->x24_WIDT.reset(GetRealElement(in));
break;
case SBIG('ORNT'):
fillDesc->x30_30_ORNT = GetBool(in);
break;
case SBIG('RSOP'):
fillDesc->x30_31_RSOP = GetBool(in);
break;
case SBIG('SEED'):
fillDesc->x10_SEED.reset(GetIntElement(in));
break;
case SBIG('ADV1'):
fillDesc->x10c_ADV1.reset(GetRealElement(in));
break;
case SBIG('ADV2'):
fillDesc->x110_ADV2.reset(GetRealElement(in));
break;
case SBIG('ADV3'):
fillDesc->x114_ADV3.reset(GetRealElement(in));
break;
case SBIG('ADV4'):
fillDesc->x118_ADV4.reset(GetRealElement(in));
break;
case SBIG('ADV5'):
fillDesc->x11c_ADV5.reset(GetRealElement(in));
break;
case SBIG('ADV6'):
fillDesc->x120_ADV6.reset(GetRealElement(in));
break;
case SBIG('ADV7'):
fillDesc->x124_ADV7.reset(GetRealElement(in));
break;
case SBIG('ADV8'):
fillDesc->x128_ADV8.reset(GetRealElement(in));
break;
case SBIG('SELC'):
fillDesc->xd8_SELC = GetElectricGeneratorDesc(in, resPool);
break;
default:
{
uint32_t clsName = clsId.toUint32();
Log.report(LogVisor::FatalError, "Unknown GPSM class %.4s @%" PRIi64, &clsName, in.position());
return false;
}
}
clsId = GetClassID(in);
}
return true;
}
void CParticleDataFactory::LoadGPSMTokens(CGenDescription* desc)
{
}
std::unique_ptr<IObj> FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
{
CSimplePool* sp = static_cast<CSimplePool*>(static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam());
return TToken<CGenDescription>::GetIObjObjectFor(std::unique_ptr<CGenDescription>(CParticleDataFactory::GetGeneratorDesc(in, sp)));
}
}

View File

@ -0,0 +1,82 @@
#ifndef __RETRO_CPARTICLEDATAFACTORY_HPP__
#define __RETRO_CPARTICLEDATAFACTORY_HPP__
#include "RetroTypes.hpp"
#include "IObj.hpp"
#include "CToken.hpp"
#include "IOStreams.hpp"
namespace Retro
{
class CGenDescription;
class CSwooshDescription;
class CElectricDescription;
class CSimplePool;
class CVParamTransfer;
class CModel;
class CUVElement;
class CColorElement;
class CModVectorElement;
class CEmitterElement;
class CVectorElement;
class CRealElement;
class CIntElement;
struct SParticleModel
{
TToken<CModel> m_model;
bool m_found;
};
struct SChildGeneratorDesc
{
TToken<CSwooshDescription> m_model;
bool m_found;
};
struct SSwooshGeneratorDesc
{
TToken<CSwooshDescription> m_model;
bool m_found;
};
struct SElectricGeneratorDesc
{
TToken<CElectricDescription> m_model;
bool m_found;
};
class CParticleDataFactory
{
static SParticleModel GetModel(CInputStream& in, CSimplePool* resPool);
static SChildGeneratorDesc GetChildGeneratorDesc(TResID res, CSimplePool* resPool, const std::vector<TResID>& tracker);
static SChildGeneratorDesc GetChildGeneratorDesc(CInputStream& in, CSimplePool* resPool, const std::vector<TResID>& tracker);
static SSwooshGeneratorDesc GetSwooshGeneratorDesc(CInputStream& in, CSimplePool* resPool);
static SElectricGeneratorDesc GetElectricGeneratorDesc(CInputStream& in, CSimplePool* resPool);
static CUVElement* GetTextureElement(CInputStream& in, CSimplePool* resPool);
static CColorElement* GetColorElement(CInputStream& in);
static CModVectorElement* GetModVectorElement(CInputStream& in);
static CEmitterElement* GetEmitterElement(CInputStream& in);
static CVectorElement* GetVectorElement(CInputStream& in);
static CRealElement* GetRealElement(CInputStream& in);
static CIntElement* GetIntElement(CInputStream& in);
static float GetReal(CInputStream& in);
static int32_t GetInt(CInputStream& in);
static bool GetBool(CInputStream& in);
static FourCC GetClassID(CInputStream& in);
public:
static CGenDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool);
static CGenDescription* CreateGeneratorDescription(CInputStream& in, std::vector<TResID>& tracker,
TResID resId, CSimplePool* resPool);
static bool CreateGPSM(CGenDescription* fillDesc, CInputStream& in,
std::vector<TResID>& tracker, CSimplePool* resPool);
static void LoadGPSMTokens(CGenDescription* desc);
};
std::unique_ptr<IObj> FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
}
#endif // __RETRO_CPARTICLEDATAFACTORY_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CREALELEMENT_HPP__
#define __RETRO_CREALELEMENT_HPP__
namespace Retro
{
class CRealElement
{
};
}
#endif // __RETRO_CREALELEMENT_HPP__

View File

@ -0,0 +1,19 @@
#ifndef __RETRO_CSPAWNSYSTEMKEYFRAMEDATA_HPP__
#define __RETRO_CSPAWNSYSTEMKEYFRAMEDATA_HPP__
#include "IOStreams.hpp"
namespace Retro
{
class CSimplePool;
class CSpawnSystemKeyframeData
{
public:
CSpawnSystemKeyframeData(CInputStream& in);
void LoadAllSpawnedSystemTokens(CSimplePool* pool);
};
}
#endif // __RETRO_CSPAWNSYSTEMKEYFRAMEDATA_HPP__

View File

View File

@ -0,0 +1,4 @@
#ifndef __RETRO_CSWOOSHDESCRIPTION_HPP__
#define __RETRO_CSWOOSHDESCRIPTION_HPP__
#endif // __RETRO_CSWOOSHDESCRIPTION_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CUVELEMENT_HPP__
#define __RETRO_CUVELEMENT_HPP__
namespace Retro
{
class CUVElement
{
};
}
#endif // __RETRO_CUVELEMENT_HPP__

View File

View File

@ -0,0 +1,13 @@
#ifndef __RETRO_CVECTORELEMENT_HPP__
#define __RETRO_CVECTORELEMENT_HPP__
namespace Retro
{
class CVectorElement
{
};
}
#endif // __RETRO_CVECTORELEMENT_HPP__

View File

View File

@ -0,0 +1,4 @@
#ifndef __RETRO_CWEAPONDESCRIPTION_HPP__
#define __RETRO_CWEAPONDESCRIPTION_HPP__
#endif // __RETRO_CWEAPONDESCRIPTION_HPP__

View File

@ -12,11 +12,12 @@ namespace Retro
{ {
using FourCC = HECL::FourCC; using FourCC = HECL::FourCC;
using TResID = u32;
struct SObjectTag struct SObjectTag
{ {
FourCC type; FourCC type;
u32 id; TResID id = -1;
bool operator!=(const SObjectTag& other) const {return id != other.id;} bool operator!=(const SObjectTag& other) const {return id != other.id;}
bool operator==(const SObjectTag& other) const {return id == other.id;} bool operator==(const SObjectTag& other) const {return id == other.id;}
}; };

View File

@ -3,6 +3,4 @@
namespace rstl namespace rstl
{ {
CRefData rstl::CRefData::sNull;
} }

View File

@ -17,69 +17,6 @@ public:
reserved_vector() {this->reserve(N);} reserved_vector() {this->reserve(N);}
}; };
/**
* @brief Simple data/refcount pair
*/
class CRefData
{
void* x0_ptr;
int x4_refCount;
public:
CRefData() : x0_ptr(nullptr), x4_refCount(0xffffff) {}
CRefData(void* ptr) : x0_ptr(ptr), x4_refCount(0) {}
void* GetPtr() const {return x0_ptr;}
int AddRef() {return ++x4_refCount;}
int DelRef() {return --x4_refCount;}
static CRefData sNull;
};
template<class T>
class ncrc_ptr;
/**
* @brief Reference-counted shared smart pointer
*/
template<class T>
class rc_ptr
{
CRefData* m_aux;
friend class ncrc_ptr<T>;
public:
rc_ptr() : m_aux(&CRefData::sNull) {m_aux->AddRef();}
rc_ptr(void* ptr) : m_aux(new CRefData(ptr)) {m_aux->AddRef();}
rc_ptr(const rc_ptr<T>& other) : m_aux(other.m_aux) {m_aux->AddRef();}
rc_ptr(rc_ptr<T>&& other) : m_aux(other.m_aux) {other.m_aux = nullptr;}
rc_ptr(const ncrc_ptr<T>& other) : m_aux(other.m_aux) {m_aux->AddRef();}
~rc_ptr()
{
if (m_aux && !m_aux->DelRef())
{
delete static_cast<T*>(m_aux->GetPtr());
delete m_aux;
}
}
T* operator->() const {return static_cast<T*>(m_aux->GetPtr());}
T& operator*() const {return *static_cast<T*>(m_aux->GetPtr());}
T* get() const {return static_cast<T*>(m_aux->GetPtr());}
operator bool() {return m_aux->GetPtr() != nullptr;}
};
/**
* @brief Non-reference-counted shared smart pointer
*/
template<class T>
class ncrc_ptr
{
CRefData* m_aux;
friend class rc_ptr<T>;
public:
ncrc_ptr(const rc_ptr<T>& other) : m_aux(other.m_aux) {}
T* get() const {return static_cast<T*>(m_aux->GetPtr());}
};
} }
#endif // __RSTL_HPP__ #endif // __RSTL_HPP__