Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 73 additions & 27 deletions src/Layers/xrRender/PSLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "PSLibrary.h"
#include "ParticleEffect.h"
#include "ParticleGroup.h"
#include "../../xrCore/_thread_types.h"

#ifdef _EDITOR
# include "ParticleEffectActions.h"
Expand Down Expand Up @@ -191,49 +192,76 @@ bool CPSLibrary::Load2()
}


bool CPSLibrary::Load(const char* nm)
bool CPSLibrary::LoadDefinitions(const char* nm)
{
CTimer startupTimer;
startupTimer.Start();
FS_FileSet files;
string_path _path;

FS.update_path(_path, "$game_particles$", "");
FS.file_list(files, _path, FS_ListFiles, "*.pe,*.pg");

FS_FileSet::iterator it = files.begin();
FS_FileSet::iterator it_e = files.end();
struct PreparedParticle
{
xr_string file;
shared_str name;
bool effect = false;
std::unique_ptr<PS::CPEDef> effectDefinition;
std::unique_ptr<PS::CPGDef> groupDefinition;
};

xr_vector<PreparedParticle> prepared(files.size());
u32 sourceIndex = 0;
for (const FS_File& file : files)
{
string_path path;
string_path name;
string_path extension;
_splitpath(file.name.c_str(), nullptr, path, name, extension);

PreparedParticle& result = prepared[sourceIndex++];
result.file = file.name.c_str();
result.name.printf("%s%s", path, name);
result.effect = 0 == stricmp(extension, ".pe");
R_ASSERT(result.effect || 0 == stricmp(extension, ".pg"));
}

string_path p_path, p_name, p_ext;
for (; it != it_e; ++it)
xr_parallel_for(0u, static_cast<u32>(prepared.size()), [&](u32 index)
{
const FS_File& f = (*it);
_splitpath(f.name.c_str(), 0, p_path, p_name, p_ext);
FS.update_path(_path, "$game_particles$", f.name.c_str());
CInifile ini(_path, TRUE, TRUE, FALSE);
PreparedParticle& result = prepared[index];
string_path fullPath;
FS.update_path(fullPath, "$game_particles$", result.file.c_str());
CInifile ini(fullPath, TRUE, TRUE, FALSE);

xr_sprintf(_path, sizeof(_path), "%s%s", p_path, p_name);
if (0 == stricmp(p_ext, ".pe"))
if (result.effect)
{
PS::CPEDef* def = xr_new<PS::CPEDef>();
def->m_Name = _path;
if (def->Load2(ini))
m_PEDs.push_back(def);
else
xr_delete(def);
std::unique_ptr<PS::CPEDef> definition = std::make_unique<PS::CPEDef>();
definition->m_Name = result.name;
if (definition->Load2(ini))
result.effectDefinition = std::move(definition);
}
else if (0 == stricmp(p_ext, ".pg"))
else
{
PS::CPGDef* def = xr_new<PS::CPGDef>();
def->m_Name = _path;
if (def->Load2(ini))
m_PGDs.push_back(def);
else
xr_delete(def);
std::unique_ptr<PS::CPGDef> definition = std::make_unique<PS::CPGDef>();
definition->m_Name = result.name;
if (definition->Load2(ini))
result.groupDefinition = std::move(definition);
}
else
});

for (PreparedParticle& result : prepared)
{
if (result.effectDefinition)
{
R_ASSERT(0);
m_PEDs.push_back(result.effectDefinition.release());
}
else if (result.groupDefinition)
{
m_PGDs.push_back(result.groupDefinition.release());
}
}
m_prepare_loose_ms = startupTimer.GetElapsed_ms();

bool bRes = true;
if (FS.exist(nm))
Expand Down Expand Up @@ -316,14 +344,32 @@ bool CPSLibrary::Load(const char* nm)

FS.r_close(F);
}
m_prepare_library_ms = startupTimer.GetElapsed_ms() - m_prepare_loose_ms;

std::sort(m_PEDs.begin(), m_PEDs.end(), ped_sort_pred);
std::sort(m_PGDs.begin(), m_PGDs.end(), pgd_sort_pred);
m_prepare_sort_ms = startupTimer.GetElapsed_ms() - m_prepare_loose_ms - m_prepare_library_ms;

return bRes;
}

void CPSLibrary::FinalizeLoad()
{
CTimer shaderTimer;
shaderTimer.Start();
for (PS::PEDIt e_it = m_PEDs.begin(); e_it != m_PEDs.end(); ++e_it)
(*e_it)->CreateShader();
Msg("* [STARTUP/RENDER PARTICLES] loose=%u library=%u sort=%u shaders=%u effects=%u groups=%u total=%u ms",
m_prepare_loose_ms, m_prepare_library_ms, m_prepare_sort_ms, shaderTimer.GetElapsed_ms(),
static_cast<u32>(m_PEDs.size()), static_cast<u32>(m_PGDs.size()),
m_prepare_loose_ms + m_prepare_library_ms + m_prepare_sort_ms + shaderTimer.GetElapsed_ms());
}

return bRes;
bool CPSLibrary::Load(const char* nm)
{
const bool result = LoadDefinitions(nm);
FinalizeLoad();
return result;
}

//----------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions src/Layers/xrRender/PSLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ class ECORE_API CPSLibrary : public particles_systems::library_interface
{
PS::PEDVec m_PEDs;
PS::PGDVec m_PGDs;
u32 m_prepare_loose_ms = 0;
u32 m_prepare_library_ms = 0;
u32 m_prepare_sort_ms = 0;

bool LoadDefinitions(LPCSTR nm);
void FinalizeLoad();

#ifdef _EDITOR
AnsiString m_CurrentParticles;
Expand Down
Loading