Tons of PART rendering preparation

This commit is contained in:
Jack Andersen 2016-02-15 19:50:41 -10:00
parent 0260ebcd64
commit a80142728d
29 changed files with 1048 additions and 67 deletions

View File

@ -42,7 +42,7 @@ static inline uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y)
int ry = y % 8;
int bidx = by * bwidth + bx;
const uint8_t* btexels = &texels[32*bidx];
return btexels[ry*4+rx/2] >> ((rx%2)?0:4) & 0xf;
return btexels[ry*4+rx/2] >> ((rx&1)?0:4) & 0xf;
}
static inline uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y)

View File

@ -43,6 +43,7 @@ add_executable(urde WIN32 MACOSX_BUNDLE
ParticleEditor.hpp ParticleEditor.cpp atdna_ParticleEditor.cpp
InformationCenter.hpp InformationCenter.hpp atdna_InformationCenter.cpp
ProjectManager.hpp ProjectManager.cpp
ProjectResourceFactory.hpp ProjectResourceFactory.cpp
ViewManager.hpp ViewManager.cpp
Resource.hpp Resource.cpp
Camera.hpp Camera.cpp)

View File

@ -6,9 +6,22 @@ namespace URDE
{
static LogVisor::LogModule Log("URDE::ProjectManager");
void ProjectManager::IndexMP1Resources()
{
const std::vector<HECL::Database::Project::ProjectDataSpec>& specs = m_proj->getDataSpecs();
for (const HECL::Database::Project::ProjectDataSpec& spec : m_proj->getDataSpecs())
{
if (&spec.spec == &DataSpec::SpecEntMP1)
{
m_factory.BuildObjectMap(spec);
break;
}
}
}
bool ProjectManager::m_registeredSpecs = false;
ProjectManager::ProjectManager(ViewManager &vm)
: m_vm(vm)
: m_vm(vm), m_objStore(m_factory)
{
if (!m_registeredSpecs)
{
@ -96,6 +109,8 @@ bool ProjectManager::openProject(const HECL::SystemString& path)
#endif
IndexMP1Resources();
m_vm.BuildTestPART(m_objStore);
m_vm.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
m_vm.DismissSplash();
m_vm.FadeInEditors();

View File

@ -3,6 +3,8 @@
#include <HECL/Database.hpp>
#include <Athena/DNAYaml.hpp>
#include "ProjectResourceFactory.hpp"
#include "Runtime/CSimplePool.hpp"
namespace URDE
{
@ -21,6 +23,11 @@ class ProjectManager
ViewManager& m_vm;
std::unique_ptr<HECL::Database::Project> m_proj;
static bool m_registeredSpecs;
ProjectResourceFactory m_factory;
pshag::CSimplePool m_objStore;
void IndexMP1Resources();
public:
ProjectManager(ViewManager& vm);
operator bool() const {return m_proj.operator bool();}

View File

@ -0,0 +1,87 @@
#include "ProjectResourceFactory.hpp"
#include "Runtime/IOStreams.hpp"
#include "Runtime/Particle/CParticleDataFactory.hpp"
#include "Runtime/CTexture.hpp"
namespace URDE
{
ProjectResourceFactory::ProjectResourceFactory()
{
m_factoryMgr.AddFactory(HECL::FOURCC('TXTR'), pshag::FTextureFactory);
m_factoryMgr.AddFactory(HECL::FOURCC('PART'), pshag::FParticleFactory);
}
void ProjectResourceFactory::RecursiveAddDirObjects(const HECL::ProjectPath& path)
{
HECL::DirectoryEnumerator de = path.enumerateDir();
for (const HECL::DirectoryEnumerator::Entry& ent : de)
{
if (ent.m_isDir)
RecursiveAddDirObjects(HECL::ProjectPath(path, ent.m_name));
if (ent.m_name.size() == 13 && ent.m_name[4] == _S('_'))
{
HECL::SystemUTF8View entu8(ent.m_name);
u32 id = strtoul(entu8.c_str() + 5, nullptr, 16);
if (id)
{
pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id};
if (m_resPaths.find(objTag) == m_resPaths.end())
m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name);
}
}
}
}
void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec)
{
m_resPaths.clear();
RecursiveAddDirObjects(spec.cookedPath);
}
std::unique_ptr<pshag::IObj> ProjectResourceFactory::Build(const pshag::SObjectTag& tag,
const pshag::CVParamTransfer& paramXfer)
{
auto search = m_resPaths.find(tag);
if (search == m_resPaths.end())
return {};
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
if (fr.hasError())
return {};
return m_factoryMgr.MakeObject(tag, fr, paramXfer);
}
void ProjectResourceFactory::BuildAsync(const pshag::SObjectTag& tag,
const pshag::CVParamTransfer& paramXfer,
pshag::IObj** objOut)
{
std::unique_ptr<pshag::IObj> obj = Build(tag, paramXfer);
*objOut = obj.release();
}
void ProjectResourceFactory::CancelBuild(const pshag::SObjectTag&)
{
}
bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag)
{
auto search = m_resPaths.find(tag);
if (search == m_resPaths.end())
return false;
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
if (fr.hasError())
return false;
return true;
}
const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char*) const
{
return nullptr;
}
}

View File

@ -0,0 +1,28 @@
#ifndef URDE_PROJECT_RESOURCE_FACTORY_HPP
#define URDE_PROJECT_RESOURCE_FACTORY_HPP
#include "Runtime/IFactory.hpp"
#include "Runtime/CFactoryMgr.hpp"
namespace URDE
{
class ProjectResourceFactory : public pshag::IFactory
{
std::unordered_map<pshag::SObjectTag, HECL::ProjectPath> m_resPaths;
pshag::CFactoryMgr m_factoryMgr;
void RecursiveAddDirObjects(const HECL::ProjectPath& path);
public:
ProjectResourceFactory();
void BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec);
std::unique_ptr<pshag::IObj> Build(const pshag::SObjectTag&, const pshag::CVParamTransfer&);
void BuildAsync(const pshag::SObjectTag&, const pshag::CVParamTransfer&, pshag::IObj**);
void CancelBuild(const pshag::SObjectTag&);
bool CanBuild(const pshag::SObjectTag&);
const pshag::SObjectTag* GetResourceIdByName(const char*) const;
};
}
#endif // URDE_PROJECT_RESOURCE_FACTORY_HPP

View File

@ -76,6 +76,16 @@ void ViewManager::DismissSplash()
m_splash->close();
}
void ViewManager::BuildTestPART(pshag::IObjectStore& objStore)
{
m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x0B4D0FBF});
m_partGen.reset(new pshag::CElementGen(m_partGenDesc,
pshag::CElementGen::EModelOrientationType::Normal,
pshag::CElementGen::EOptionalSystemFlags::None));
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
m_rootView->accessContentViews().push_back(m_particleView.get());
}
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish()),
@ -168,6 +178,9 @@ void ViewManager::init(boo::IApplication* app)
root->updateSize();
m_mainWindow->setWaitCursor(false);
pshag::CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue());
pshag::CElementGen::Initialize();
}
bool ViewManager::proc()

View File

@ -5,6 +5,8 @@
#include "ProjectManager.hpp"
#include "Space.hpp"
#include "Runtime/Particle/CElementGen.hpp"
namespace URDE
{
class SplashScreen;
@ -31,6 +33,31 @@ class ViewManager : public Specter::IViewManager
std::unique_ptr<RootSpace> m_rootSpace;
Specter::View* m_rootSpaceView = nullptr;
class ParticleView : public Specter::View
{
ViewManager& m_vm;
public:
ParticleView(ViewManager& vm, Specter::ViewResources& res, Specter::View& parent)
: View(res, parent), m_vm(vm) {}
void draw(boo::IGraphicsCommandQueue* gfxQ)
{
if (m_vm.m_partGen)
{
m_vm.m_partGen->Update(1.0 / 60.0);
pshag::CGraphics::SetModelMatrix(Zeus::CTransform::Identity());
pshag::CGraphics::SetViewPointMatrix(Zeus::CTransform::Identity() + Zeus::CVector3f(0.f, -10.f, 0.f));
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
float aspect = windowRect.size[0] / float(windowRect.size[1]);
pshag::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
gfxQ->clearTarget(false, true);
m_vm.m_partGen->Render();
}
}
};
std::unique_ptr<ParticleView> m_particleView;
pshag::TLockedToken<pshag::CGenDescription> m_partGenDesc;
std::unique_ptr<pshag::CElementGen> m_partGen;
HECL::SystemString m_recentProjectsPath;
std::vector<HECL::SystemString> m_recentProjects;
HECL::SystemString m_recentFilesPath;
@ -53,6 +80,8 @@ class ViewManager : public Specter::IViewManager
unsigned m_editorFrames = 120;
void FadeInEditors() {m_editorFrames = 0;}
void BuildTestPART(pshag::IObjectStore& objStore);
Space* m_deferSplit = nullptr;
Specter::SplitView::Axis m_deferSplitAxis;
int m_deferSplitThisSlot;

View File

@ -29,7 +29,7 @@ boo::GraphicsDataToken InitializeIcons(Specter::ViewResources& viewRes)
Log.report(LogVisor::FatalError, "unable to decompress icons");
g_IconAtlas.initializeAtlas(viewRes.m_factory->newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8,
std::move(texels), destSz));
texels.get(), destSz));
return viewRes.m_factory->commit();
}

View File

@ -24,7 +24,6 @@ struct Application : boo::IApplicationCallback
int appMain(boo::IApplication* app)
{
pshag::CElementGen::Initialize();
m_viewManager.init(app);
while (m_running)
{

View File

@ -0,0 +1,36 @@
#include "CFactoryMgr.hpp"
#include "IObj.hpp"
namespace pshag
{
CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, pshag::CInputStream& in,
const CVParamTransfer& paramXfer)
{
auto search = m_factories.find(tag.type);
if (search == m_factories.end())
return {};
return search->second(tag, in, paramXfer);
}
CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, void* buf, int size,
bool compressed, const CVParamTransfer& paramXfer)
{
auto search = m_factories.find(tag.type);
if (search == m_factories.end())
return {};
if (compressed)
{
CZipInputStream r(std::make_unique<Athena::io::MemoryReader>(buf, size));
return search->second(tag, r, paramXfer);
}
else
{
Athena::io::MemoryReader r(buf, size);
return search->second(tag, r, paramXfer);
}
}
}

View File

@ -3,21 +3,27 @@
#include <unordered_map>
#include "RetroTypes.hpp"
#include "IOStreams.hpp"
namespace pshag
{
class SObjectTag;
class CVParamTransfer;
class CInputStream;
typedef void(*CFactoryFnReturn)(const SObjectTag&, CInputStream&, const CVParamTransfer&);
class IObj;
using CFactoryFnReturn = std::unique_ptr<IObj>;
using FFactoryFunc = std::function<CFactoryFnReturn(const pshag::SObjectTag& tag,
pshag::CInputStream& in,
const pshag::CVParamTransfer& vparms)>;
class CFactoryMgr
{
std::unordered_map<u32, CFactoryFnReturn> m_factories;
std::unordered_map<FourCC, FFactoryFunc> m_factories;
public:
MakeObjectFromMemory(const SObjectTag&, void*, int, bool, const CVParamTransfer&);
void AddFactory(FourCC key, CFactoryFnReturn func)
CFactoryFnReturn MakeObject(const SObjectTag& tag, pshag::CInputStream& in,
const CVParamTransfer& paramXfer);
CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, void* buf, int size, bool compressed,
const CVParamTransfer& paramXfer);
void AddFactory(FourCC key, FFactoryFunc func)
{
m_factories[key] = func;
}

View File

@ -121,6 +121,17 @@ struct SClipScreenRect
enum class ETexelFormat
{
I4 = 0,
I8 = 1,
IA4 = 2,
IA8 = 3,
C4 = 4,
C8 = 5,
C14X2 = 6,
RGB565 = 7,
RGB5A3 = 8,
RGBA8 = 9,
CMPR = 10
};
class CGraphics
@ -163,7 +174,7 @@ public:
static Zeus::CMatrix4f GetPerspectiveProjectionMatrix();
static const CProjectionState& GetProjectionState();
static void SetProjectionState(const CProjectionState&);
static void SetPerspective(float, float, float, float);
static void SetPerspective(float fovy, float aspect, float near, float far);
static void FlushProjection();
static Zeus::CVector2i ProjectPoint(const Zeus::CVector3f& point);
static SClipScreenRect ClipScreenRectFromMS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
@ -173,6 +184,12 @@ public:
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
static boo::ITextureR* g_SpareTexture;
static void InitializeBoo(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cc)
{
g_BooFactory = factory;
g_BooMainCommandQueue = cc;
}
static boo::IGraphicsBufferD* NewDynamicGPUBuffer(boo::BufferUse use, size_t stride, size_t count)
{
return g_BooFactory->newDynamicBuffer(use, stride, count);
@ -185,8 +202,9 @@ public:
{
g_BooMainCommandQueue->setShaderDataBinding(binding);
}
static void DrawInstances(size_t start, size_t count, size_t instCount)
static void DrawInstances(boo::Primitive prim, size_t start, size_t count, size_t instCount)
{
g_BooMainCommandQueue->setDrawPrimitive(prim);
g_BooMainCommandQueue->drawInstances(start, count, instCount);
}
};

View File

@ -58,7 +58,7 @@ add_library(RuntimeCommon
CPakFile.hpp CPakFile.cpp
CStringExtras.hpp
CCallStack.hpp
CTexture.hpp CTexture.cpp
CTexture.hpp CTextureBoo.cpp
CLight.hpp CLight.cpp
IOStreams.hpp IOStreams.cpp
CMainFlowBase.hpp CMainFlowBase.cpp

View File

@ -11,7 +11,9 @@ CSimplePool::CSimplePool(IFactory& factory)
CToken CSimplePool::GetObj(const SObjectTag& tag, const CVParamTransfer& paramXfer)
{
auto iter = std::find_if(x4_resources.begin(), x4_resources.end(), [&tag](std::pair<SObjectTag, CObjectReference*> pair)->bool{
auto iter = std::find_if(x4_resources.begin(), x4_resources.end(),
[&tag](std::pair<SObjectTag, CObjectReference*> pair) -> bool
{
return pair.first == tag;
});

View File

@ -1,11 +0,0 @@
#include "CTexture.hpp"
namespace pshag
{
void CTexture::Load(int slot, EClampMode clamp)
{
}
}

View File

@ -2,28 +2,54 @@
#define __PSHAG_CTEXTURE_HPP__
#include "GCNTypes.hpp"
#include "IObj.hpp"
#include "IOStreams.hpp"
#include "CGraphics.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
namespace pshag
{
class CVParamTransfer;
class CTexture
{
ETexelFormat x0_fmt;
u16 x4_w;
u16 x6_h;
u32 x8_mips;
boo::GraphicsDataToken m_booToken;
boo::ITexture* m_booTex;
size_t ComputeMippedTexelCount();
size_t ComputeMippedBlockCountDXT1();
void BuildI4FromGCN(CInputStream& in);
void BuildI8FromGCN(CInputStream& in);
void BuildIA4FromGCN(CInputStream& in);
void BuildIA8FromGCN(CInputStream& in);
void BuildC4FromGCN(CInputStream& in);
void BuildC8FromGCN(CInputStream& in);
void BuildC14X2FromGCN(CInputStream& in);
void BuildRGB565FromGCN(CInputStream& in);
void BuildRGB5A3FromGCN(CInputStream& in);
void BuildRGBA8FromGCN(CInputStream& in);
void BuildDXT1FromGCN(CInputStream& in);
public:
CTexture(CInputStream& in);
enum class EClampMode
{
None,
One
};
ETexelFormat GetTexelFormat() const {return x0_fmt;}
u16 GetWidth() const {return x4_w;}
u16 GetHeight() const {return x6_h;}
void Load(int slot, EClampMode clamp);
boo::ITexture* GetBooTexture() {return m_booTex;}
};
std::unique_ptr<IObj> FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
}
#endif // __PSHAG_CTEXTURE_HPP__

679
Runtime/CTextureBoo.cpp Normal file
View File

@ -0,0 +1,679 @@
#include "CTexture.hpp"
#include "CSimplePool.hpp"
#include "CToken.hpp"
#include "CGraphics.hpp"
namespace pshag
{
/* GX uses this upsampling technique to prevent banding on downsampled texture formats */
static inline uint8_t Convert3To8(uint8_t v)
{
/* Swizzle bits: 00000123 -> 12312312 */
return (v << 5) | (v << 2) | (v >> 1);
}
static inline uint8_t Convert4To8(uint8_t v)
{
/* Swizzle bits: 00001234 -> 12341234 */
return (v << 4) | v;
}
static inline uint8_t Convert5To8(uint8_t v)
{
/* Swizzle bits: 00012345 -> 12345123 */
return (v << 3) | (v >> 2);
}
static inline uint8_t Convert6To8(uint8_t v)
{
/* Swizzle bits: 00123456 -> 12345612 */
return (v << 2) | (v >> 4);
}
size_t CTexture::ComputeMippedTexelCount()
{
size_t w = x4_w;
size_t h = x6_h;
size_t ret = w * h;
for (int i=x8_mips ; i>1 ; --i)
{
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
ret += w * h;
}
return ret;
}
size_t CTexture::ComputeMippedBlockCountDXT1()
{
size_t w = x4_w / 4;
size_t h = x6_h / 4;
size_t ret = w * h;
for (int i=x8_mips ; i>1 ; --i)
{
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
ret += w * h;
}
return ret;
}
struct RGBA8
{
u8 r;
u8 g;
u8 b;
u8 a;
};
void CTexture::BuildI4FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 7) / 8;
int bheight = (h + 7) / 8;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 8;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 8;
for (int y=0 ; y<8 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[4];
in.readBytesToBuf(source, 4);
for (int x=0 ; x<8 ; ++x)
{
target[x].r = Convert4To8(source[x/2] >> ((x&1)?0:4) & 0xf);
target[x].g = target[x].r;
target[x].b = target[x].r;
target[x].a = target[x].r;
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildI8FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 7) / 8;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 8;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[8];
in.readBytesToBuf(source, 8);
for (int x=0 ; x<8 ; ++x)
{
target[x].r = source[x];
target[x].g = source[x];
target[x].b = source[x];
target[x].a = source[x];
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildIA4FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 7) / 8;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 8;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[8];
in.readBytesToBuf(source, 8);
for (int x=0 ; x<8 ; ++x)
{
u8 intensity = Convert4To8(source[x] >> 4 & 0xf);
target[x].r = intensity;
target[x].g = intensity;
target[x].b = intensity;
target[x].a = Convert4To8(source[x] & 0xf);
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildIA8FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 3) / 4;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 4;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u16 source[4];
in.readBytesToBuf(source, 8);
for (int x=0 ; x<4 ; ++x)
{
u8 intensity = source[x] >> 8;
target[x].r = intensity;
target[x].g = intensity;
target[x].b = intensity;
target[x].a = source[x] & 0xff;
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
static std::vector<RGBA8> DecodePalette(int numEntries, CInputStream& in)
{
std::vector<RGBA8> ret;
ret.reserve(numEntries);
enum class EPaletteType
{
IA8,
RGB565,
RGB5A3
};
EPaletteType format = EPaletteType(in.readUint32Big());
in.readUint32Big();
switch (format)
{
case EPaletteType::IA8:
{
for (int e=0 ; e<numEntries ; ++e)
{
u8 intensity = in.readUByte();
u8 alpha = in.readUByte();
ret.push_back({intensity, intensity, intensity, alpha});
}
break;
}
case EPaletteType::RGB565:
{
for (int e=0 ; e<numEntries ; ++e)
{
u16 texel = in.readUint16Big();
ret.push_back({Convert5To8(texel >> 11 & 0x1f),
Convert6To8(texel >> 5 & 0x3f),
Convert5To8(texel & 0x1f),
0xff});
}
break;
}
case EPaletteType::RGB5A3:
{
for (int e=0 ; e<numEntries ; ++e)
{
u16 texel = in.readUint16Big();
if (texel & 0x8000)
{
ret.push_back({Convert5To8(texel >> 10 & 0x1f),
Convert5To8(texel >> 5 & 0x1f),
Convert5To8(texel & 0x1f),
0xff});
}
else
{
ret.push_back({Convert4To8(texel >> 8 & 0xf),
Convert4To8(texel >> 4 & 0xf),
Convert4To8(texel & 0xf),
Convert3To8(texel >> 12 & 0x7)});
}
}
break;
}
}
return ret;
}
void CTexture::BuildC4FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
std::vector<RGBA8> palette = DecodePalette(16, in);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 7) / 8;
int bheight = (h + 7) / 8;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 8;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 8;
for (int y=0 ; y<8 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[4];
in.readBytesToBuf(source, 4);
for (int x=0 ; x<8 ; ++x)
target[x] = palette[source[x/2] >> ((x&1)?0:4) & 0xf];
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildC8FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
std::vector<RGBA8> palette = DecodePalette(256, in);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 7) / 8;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 8;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[8];
in.readBytesToBuf(source, 8);
for (int x=0 ; x<8 ; ++x)
target[x] = palette[source[x]];
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildC14X2FromGCN(CInputStream& in)
{
}
void CTexture::BuildRGB565FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 3) / 4;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 4;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
for (int x=0 ; x<4 ; ++x)
{
u16 texel = in.readUint16Big();
target[x].r = Convert5To8(texel >> 11 & 0x1f);
target[x].g = Convert6To8(texel >> 5 & 0x3f);
target[x].b = Convert5To8(texel & 0x1f);
target[x].a = 0xff;
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildRGB5A3FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 3) / 4;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 4;
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
for (int x=0 ; x<4 ; ++x)
{
u16 texel = in.readUint16Big();
if (texel & 0x8000)
{
target[x].r = Convert5To8(texel >> 10 & 0x1f);
target[x].g = Convert5To8(texel >> 5 & 0x1f);
target[x].b = Convert5To8(texel & 0x1f);
target[x].a = 0xff;
}
else
{
target[x].r = Convert4To8(texel >> 8 & 0xf);
target[x].g = Convert4To8(texel >> 4 & 0xf);
target[x].b = Convert4To8(texel & 0xf);
target[x].a = Convert3To8(texel >> 12 & 0x7);
}
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
void CTexture::BuildRGBA8FromGCN(CInputStream& in)
{
size_t texelCount = ComputeMippedTexelCount();
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
int w = x4_w;
int h = x6_h;
RGBA8* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 3) / 4;
int bheight = (h + 3) / 4;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 4;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 4;
for (int c=0 ; c<2 ; ++c)
{
for (int y=0 ; y<4 ; ++y)
{
RGBA8* target = targetMip + (baseY + y) * w + baseX;
u8 source[8];
in.readBytesToBuf(source, 8);
for (int x=0 ; x<4 ; ++x)
{
if (c)
{
target[x].g = source[x*2];
target[x].b = source[x*2+1];
}
else
{
target[x].a = source[x*2];
target[x].r = source[x*2+1];
}
}
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::RGBA8,
buf.get(), texelCount * 4,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
struct DXT1Block
{
uint16_t color1;
uint16_t color2;
uint8_t lines[4];
};
void CTexture::BuildDXT1FromGCN(CInputStream& in)
{
size_t blockCount = ComputeMippedBlockCountDXT1();
std::unique_ptr<DXT1Block[]> buf(new DXT1Block[blockCount]);
int w = x4_w / 4;
int h = x6_h / 4;
DXT1Block* targetMip = buf.get();
for (int mip=0 ; mip<x8_mips ; ++mip)
{
int bwidth = (w + 1) / 2;
int bheight = (h + 1) / 2;
for (int by=0 ; by<bheight ; ++by)
{
int baseY = by * 2;
for (int bx=0 ; bx<bwidth ; ++bx)
{
int baseX = bx * 2;
for (int y=0 ; y<2 ; ++y)
{
DXT1Block* target = targetMip + (baseY + y) * w + baseX;
DXT1Block source[2];
in.readBytesToBuf(source, 16);
for (int x=0 ; x<2 ; ++x)
{
target[x].color1 = HECL::SBig(source[x].color1);
target[x].color2 = HECL::SBig(source[x].color2);
target[x].lines[0] = source[x].lines[3];
target[x].lines[1] = source[x].lines[2];
target[x].lines[2] = source[x].lines[1];
target[x].lines[3] = source[x].lines[0];
}
}
}
}
targetMip += w * h;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
boo::TextureFormat::DXT1,
buf.get(), blockCount * 8,
reinterpret_cast<boo::ITextureS**>(&m_booTex));
}
CTexture::CTexture(CInputStream& in)
{
x0_fmt = ETexelFormat(in.readUint32Big());
x4_w = in.readUint16Big();
x6_h = in.readUint16Big();
x8_mips = in.readUint32Big();
switch (x0_fmt)
{
case ETexelFormat::I4:
BuildI4FromGCN(in);
break;
case ETexelFormat::I8:
BuildI8FromGCN(in);
break;
case ETexelFormat::IA4:
BuildIA4FromGCN(in);
break;
case ETexelFormat::IA8:
BuildIA8FromGCN(in);
break;
case ETexelFormat::C4:
BuildC4FromGCN(in);
break;
case ETexelFormat::C8:
BuildC8FromGCN(in);
break;
case ETexelFormat::C14X2:
BuildC14X2FromGCN(in);
break;
case ETexelFormat::RGB565:
BuildRGB565FromGCN(in);
break;
case ETexelFormat::RGB5A3:
BuildRGB5A3FromGCN(in);
break;
case ETexelFormat::RGBA8:
BuildRGBA8FromGCN(in);
break;
case ETexelFormat::CMPR:
BuildDXT1FromGCN(in);
break;
}
}
void CTexture::Load(int slot, EClampMode clamp)
{
}
std::unique_ptr<IObj> FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
{
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(in));
}
}

View File

@ -17,7 +17,7 @@ class CVParamTransfer
{
std::shared_ptr<IVParamObj> m_ref;
public:
CVParamTransfer();
CVParamTransfer() = default;
CVParamTransfer(IVParamObj* obj) : m_ref(obj) {}
CVParamTransfer(const CVParamTransfer& other) : m_ref(other.m_ref) {}
IVParamObj* GetObj() const {return m_ref.get();}

View File

@ -54,13 +54,13 @@ class CMain* g_main = nullptr;
class CGameGlobalObjects
{
CMemoryCardSys m_memoryCardSys;
CResFactory m_resFactory;
CSimplePool m_simplePool;
CCharacterFactoryBuilder m_charFactoryBuilder;
CAiFuncMap m_aiFuncMap;
CGameState m_gameState;
CInGameTweakManager m_tweakManager;
CMemoryCardSys x0_memoryCardSys;
CResFactory x20_resFactory;
CSimplePool x114_simplePool;
CCharacterFactoryBuilder x14c_charFactoryBuilder;
CAiFuncMap x188_aiFuncMap;
CGameState x1a8_gameState;
CInGameTweakManager x1c0_tweakManager;
std::unique_ptr<CBooRenderer> m_renderer;
void AddPaksAndFactories()
@ -79,22 +79,22 @@ class CGameGlobalObjects
public:
CGameGlobalObjects()
: m_simplePool(m_resFactory)
: x114_simplePool(x20_resFactory)
{
g_MemoryCardSys = &m_memoryCardSys;
g_ResFactory = &m_resFactory;
g_SimplePool = &m_simplePool;
g_CharFactoryBuilder = &m_charFactoryBuilder;
g_AiFuncMap = &m_aiFuncMap;
g_GameState = &m_gameState;
g_TweakManager = &m_tweakManager;
g_MemoryCardSys = &x0_memoryCardSys;
g_ResFactory = &x20_resFactory;
g_SimplePool = &x114_simplePool;
g_CharFactoryBuilder = &x14c_charFactoryBuilder;
g_AiFuncMap = &x188_aiFuncMap;
g_GameState = &x1a8_gameState;
g_TweakManager = &x1c0_tweakManager;
}
void PostInitialize(CMemorySys& memSys)
{
AddPaksAndFactories();
LoadStringTable();
m_renderer.reset(AllocateRenderer(m_simplePool, memSys, m_resFactory));
m_renderer.reset(AllocateRenderer(x114_simplePool, memSys, x20_resFactory));
}
};

View File

@ -183,7 +183,7 @@ void CElementGenShaders::Initialize()
case boo::IGraphicsDataFactory::Platform::D3D12:
m_bindFactory.reset(Initialize(*static_cast<boo::ID3DDataFactory*>(CGraphics::g_BooFactory)));
break;
#elif __APPLE__
#elif BOO_HAS_METAL
case boo::IGraphicsDataFactory::Platform::Metal:
m_bindFactory.reset(Initialize(*static_cast<boo::MetalDataFactory*>(CGraphics::g_BooFactory)));
break;
@ -1175,6 +1175,7 @@ void CElementGen::Render()
void CElementGen::RenderModels()
{
return;
CGenDescription* desc = x1c_genDesc.GetObj();
if (x225_29_modelsUseLights)
@ -1365,6 +1366,7 @@ void CElementGen::RenderModels()
void CElementGen::RenderLines()
{
return;
CGenDescription* desc = x1c_genDesc.GetObj();
CGlobalRandom gr(x230_randState);
@ -1498,7 +1500,7 @@ void CElementGen::RenderParticles()
CUVElement* tind = desc->x58_TIND.get();
if (texr && tind)
{
RenderParticlesIndirectTexture();
//RenderParticlesIndirectTexture();
return;
}
@ -1623,6 +1625,7 @@ void CElementGen::RenderParticles()
}
float size = 0.5f * particle.x2c_lineLengthOrSize;
fprintf(stderr, "%p (%f %f %f) %f\n", this, viewPoint.x, viewPoint.y, viewPoint.z, size);
if (0.f == particle.x30_lineWidthOrRota)
{
switch (m_shaderClass)
@ -1698,11 +1701,11 @@ void CElementGen::RenderParticles()
{
case CElementGenShaders::EShaderClass::Tex:
m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex));
CGraphics::DrawInstances(0, 4, g_instTexData.size());
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size());
break;
case CElementGenShaders::EShaderClass::NoTex:
m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex));
CGraphics::DrawInstances(0, 4, g_instNoTexData.size());
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size());
break;
default: break;
}
@ -1837,11 +1840,11 @@ void CElementGen::RenderParticles()
{
case CElementGenShaders::EShaderClass::Tex:
m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex));
CGraphics::DrawInstances(0, 4, g_instTexData.size());
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size());
break;
case CElementGenShaders::EShaderClass::NoTex:
m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex));
CGraphics::DrawInstances(0, 4, g_instNoTexData.size());
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size());
break;
default: break;
}

View File

@ -108,7 +108,7 @@ private:
bool x224_25_LIT_;
bool x224_26_AAPH;
bool x224_27_ZBUF;
bool x224_28_zTest = true;
bool x224_28_zTest = false;
bool x224_29_MBLR;
bool x224_30_VMD1;
bool x224_31_VMD2;

View File

@ -63,7 +63,7 @@ public:
static IDataBindingFactory* Initialize(boo::GLDataFactory& factory);
#if _WIN32
static IDataBindingFactory* Initialize(boo::ID3DDataFactory& factory);
#elif __APPLE__
#elif BOO_HAS_METAL
static IDataBindingFactory* Initialize(boo::MetalDataFactory& factory);
#endif

View File

@ -7,7 +7,7 @@ namespace pshag
static const char* VS_GLSL_TEX =
"#version 330\n"
"layout(location=0) in vec3 posIn[4];\n"
"layout(location=0) in vec4 posIn[4];\n"
"layout(location=4) in vec4 colorIn;\n"
"layout(location=5) in vec2 uvsIn[4];\n"
"\n"
@ -29,6 +29,7 @@ static const char* VS_GLSL_TEX =
" vtf.color = colorIn * moduColor;\n"
" vtf.uv = uvsIn[gl_VertexID];\n"
" gl_Position = mvp * posIn[gl_VertexID];\n"
" gl_Position = vec4(posIn[gl_VertexID].x, posIn[gl_VertexID].z, 0.0, 1.0);\n"
"}\n";
static const char* FS_GLSL_TEX =
@ -45,6 +46,7 @@ static const char* FS_GLSL_TEX =
"void main()\n"
"{\n"
" colorOut = vtf.color * texture(texs[0], vtf.uv);\n"
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
"}\n";
static const char* FS_GLSL_TEX_REDTOALPHA =
@ -62,11 +64,12 @@ static const char* FS_GLSL_TEX_REDTOALPHA =
"{\n"
" colorOut = vtf.color * texture(texs[0], vtf.uv);\n"
" colorOut.a = colorOut.r;\n"
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
"}\n";
static const char* VS_GLSL_INDTEX =
"#version 330\n"
"layout(location=0) in vec3 posIn[4];\n"
"layout(location=0) in vec4 posIn[4];\n"
"layout(location=4) in vec4 colorIn;\n"
"layout(location=5) in vec4 uvsInTexrTind[4];\n"
"layout(location=9) in vec2 uvsInScene[4];\n"
@ -110,11 +113,12 @@ static const char* FS_GLSL_INDTEX =
"uniform sampler2D texs[3];\n"
"void main()\n"
"{\n"
" vec2 tindTexel = texture(texs[2], vtf.uvTind);\n"
" vec2 tindTexel = texture(texs[2], vtf.uvTind).xy;\n"
" vec4 sceneTexel = texture(texs[1], vtf.uvScene + tindTexel);\n"
" vec4 texrTexel = texture(texs[0], vtf.uvTexr);\n"
" colorOut = vtf.color * sceneTexel + texrTexel;\n"
" colorOut.a = vtf.color.a * texrTexel.a;"
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
"}\n";
static const char* FS_GLSL_CINDTEX =
@ -132,14 +136,15 @@ static const char* FS_GLSL_CINDTEX =
"uniform sampler2D texs[3];\n"
"void main()\n"
"{\n"
" vec2 tindTexel = texture(texs[2], vtf.uvTind);\n"
" vec2 tindTexel = texture(texs[2], vtf.uvTind).xy;\n"
" vec4 sceneTexel = texture(texs[1], vtf.uvScene + tindTexel);\n"
" colorOut = vtf.color * sceneTexel * texture(texs[0], vtf.uvTexr);\n"
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
"}\n";
static const char* VS_GLSL_NOTEX =
"#version 330\n"
"layout(location=0) in vec3 posIn[4];\n"
"layout(location=0) in vec4 posIn[4];\n"
"layout(location=4) in vec4 colorIn;\n"
"\n"
"uniform ParticleUniform\n"
@ -172,6 +177,7 @@ static const char* FS_GLSL_NOTEX =
"void main()\n"
"{\n"
" colorOut = vtf.color;\n"
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
"}\n";
struct DataBindingFactory : CElementGenShaders::IDataBindingFactory

View File

@ -0,0 +1,18 @@
#include "CEmitterElement.hpp"
namespace pshag
{
bool CEESimpleEmitter::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
{
}
bool CVESphere::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
{
}
bool CVEAngleSphere::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
{
}
}

View File

@ -105,6 +105,19 @@ bool CREClamp::GetValue(int frame,float& valOut) const
return false;
}
bool CREInitialRandom::GetValue(int frame, float& valOut) const
{
if (frame == 0)
{
float a, b;
x4_min->GetValue(frame, a);
x8_max->GetValue(frame, b);
float rand = CRandom16::GetRandomNumber()->Float();
valOut = b * rand + a * (1.0f - rand);
}
return false;
}
bool CRERandom::GetValue(int frame, float& valOut) const
{
float a, b;
@ -217,61 +230,61 @@ bool CRECompareEquals::GetValue(int frame, float& valOut) const
bool CREParticleAccessParam1::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[0];
//valOut = CParticleGlobals::g_papValues[0];
return false;
}
bool CREParticleAccessParam2::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[1];
//valOut = CParticleGlobals::g_papValues[1];
return false;
}
bool CREParticleAccessParam3::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[2];
//valOut = CParticleGlobals::g_papValues[2];
return false;
}
bool CREParticleAccessParam4::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[3];
//valOut = CParticleGlobals::g_papValues[3];
return false;
}
bool CREParticleAccessParam5::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[4];
//valOut = CParticleGlobals::g_papValues[4];
return false;
}
bool CREParticleAccessParam6::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[5];
//valOut = CParticleGlobals::g_papValues[5];
return false;
}
bool CREParticleAccessParam7::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[6];
//valOut = CParticleGlobals::g_papValues[6];
return false;
}
bool CREParticleAccessParam8::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_papValues[7];
//valOut = CParticleGlobals::g_papValues[7];
return false;
}
bool CREPSLL::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_particleMetrics->x2c_psll;
//valOut = CParticleGlobals::g_particleMetrics->x2c_psll;
return false;
}
bool CREPRLW::GetValue(int frame, float& valOut) const
{
valOut = CParticleGlobals::g_particleMetrics->x30_prlw;
//valOut = CParticleGlobals::g_particleMetrics->x30_prlw;
return false;
}

View File

@ -268,6 +268,12 @@ bool CVEParticleVelocity::GetValue(int /*frame*/, Zeus::CVector3f& valOut) const
return false;
}
bool CVESPOS::GetValue(int frame, Zeus::CVector3f& valOut) const
{
/* TODO: Do */
return false;
}
bool CVEPLCO::GetValue(int /*frame*/, Zeus::CVector3f& valOut) const
{
valOut = CParticleGlobals::g_particleMetrics->x10_plco;

2
hecl

@ -1 +1 @@
Subproject commit 2c5df80a56a07f9147e82a5981dcd311304f3b1d
Subproject commit 268a2071b75323022ef4f4cf61f9f8441b6579d2

@ -1 +1 @@
Subproject commit ca6d7ff93bb8cf951d47752c0892258330bf5caa
Subproject commit 0d22ed8d625a58d8eac7a63d09c80c490d581db2