mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-10 23:08:05 -05:00
Save scriptstrings per zone and not per asset since that solves all problems with multiple assets of the same zone referencing the same struct in memory that has scriptstring indices
This commit is contained in:
@ -50,6 +50,8 @@ ContentLoader::ContentLoader()
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
assert(m_zone->m_script_strings.empty());
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
@ -67,16 +69,18 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
if (varScriptStringList->strings[i])
|
||||
{
|
||||
m_script_strings.emplace_back(varScriptStringList->strings[i]);
|
||||
m_zone->m_script_strings.emplace_back(varScriptStringList->strings[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_script_strings.emplace_back("");
|
||||
m_zone->m_script_strings.emplace_back("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
assert(m_zone->m_script_strings.size() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
|
||||
void ContentLoader::LoadXAsset(const bool atStreamStart)
|
||||
@ -84,7 +88,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart)
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(this, m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -155,7 +159,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
|
||||
for (asset_type_t assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||
{
|
||||
m_zone->GetPools()->InitPoolDynamic(assetType);
|
||||
m_zone->m_pools->InitPoolDynamic(assetType);
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
@ -189,15 +193,3 @@ void ContentLoader::Load(Zone* zone, IZoneInputStream* stream)
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
std::string& ContentLoader::GetZoneScriptString(const scr_string_t scrString)
|
||||
{
|
||||
assert(scrString >= 0 && scrString < m_script_strings.size());
|
||||
|
||||
if (scrString >= m_script_strings.size())
|
||||
{
|
||||
return m_script_strings[0];
|
||||
}
|
||||
|
||||
return m_script_strings[scrString];
|
||||
}
|
||||
|
@ -2,13 +2,11 @@
|
||||
#include "Loading/ContentLoaderBase.h"
|
||||
#include "Loading/IContentLoadingEntryPoint.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Loading/IZoneScriptStringProvider.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint, public IZoneScriptStringProvider
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
std::vector<std::string> m_script_strings;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
@ -21,6 +19,5 @@ namespace IW4
|
||||
ContentLoader();
|
||||
|
||||
void Load(Zone* zone, IZoneInputStream* stream) override;
|
||||
std::string& GetZoneScriptString(scr_string_t scrString) override;
|
||||
};
|
||||
}
|
||||
|
@ -204,7 +204,8 @@ public:
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto* zone = new Zone(fileName, 0, new GameAssetPoolIW4(0), &g_GameIW4);
|
||||
auto* zone = new Zone(fileName, 0, &g_GameIW4);
|
||||
zone->m_pools = std::make_unique<GameAssetPoolIW4>(zone, 0);
|
||||
zone->m_language = GetZoneLanguage(fileName);
|
||||
|
||||
// File is supported. Now setup all required steps for loading this file.
|
||||
|
@ -63,6 +63,8 @@ ContentLoader::ContentLoader()
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
assert(m_zone->m_script_strings.empty());
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
@ -80,16 +82,18 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
if (varScriptStringList->strings[i])
|
||||
{
|
||||
m_script_strings.emplace_back(varScriptStringList->strings[i]);
|
||||
m_zone->m_script_strings.emplace_back(varScriptStringList->strings[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_script_strings.emplace_back("");
|
||||
m_zone->m_script_strings.emplace_back("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
assert(m_zone->m_script_strings.size() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
|
||||
void ContentLoader::LoadXAsset(const bool atStreamStart)
|
||||
@ -97,7 +101,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart)
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(this, m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -177,7 +181,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
|
||||
for (asset_type_t assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||
{
|
||||
m_zone->GetPools()->InitPoolDynamic(assetType);
|
||||
m_zone->m_pools->InitPoolDynamic(assetType);
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
@ -220,15 +224,3 @@ void ContentLoader::Load(Zone* zone, IZoneInputStream* stream)
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
std::string& ContentLoader::GetZoneScriptString(const scr_string_t scrString)
|
||||
{
|
||||
assert(scrString >= 0 && scrString < m_script_strings.size());
|
||||
|
||||
if (scrString >= m_script_strings.size())
|
||||
{
|
||||
return m_script_strings[0];
|
||||
}
|
||||
|
||||
return m_script_strings[scrString];
|
||||
}
|
||||
|
@ -2,13 +2,11 @@
|
||||
#include "Loading/ContentLoaderBase.h"
|
||||
#include "Loading/IContentLoadingEntryPoint.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Loading/IZoneScriptStringProvider.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint, public IZoneScriptStringProvider
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
std::vector<std::string> m_script_strings;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
@ -21,6 +19,5 @@ namespace T6
|
||||
ContentLoader();
|
||||
|
||||
void Load(Zone* zone, IZoneInputStream* stream) override;
|
||||
std::string& GetZoneScriptString(scr_string_t scrString) override;
|
||||
};
|
||||
}
|
||||
|
@ -238,7 +238,8 @@ public:
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto* zone = new Zone(fileName, 0, new GameAssetPoolT6(0), &g_GameT6);
|
||||
auto* zone = new Zone(fileName, 0, &g_GameT6);
|
||||
zone->m_pools = std::make_unique<GameAssetPoolT6>(zone, 0);
|
||||
zone->m_language = GetZoneLanguage(fileName);
|
||||
|
||||
// File is supported. Now setup all required steps for loading this file.
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "AssetLoader.h"
|
||||
#include <cassert>
|
||||
|
||||
AssetLoader::AssetLoader(const asset_type_t assetType, IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream)
|
||||
AssetLoader::AssetLoader(const asset_type_t assetType, Zone* zone, IZoneInputStream* stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
m_asset_type(assetType),
|
||||
varScriptString(nullptr)
|
||||
{
|
||||
m_asset_type = assetType;
|
||||
m_script_string_provider = scriptStringProvider;
|
||||
m_zone = zone;
|
||||
m_stream = stream;
|
||||
varScriptString = nullptr;
|
||||
@ -16,7 +18,7 @@ void AssetLoader::AddDependency(XAssetInfoGeneric* assetInfo)
|
||||
return;
|
||||
|
||||
const auto existingEntry = std::find(m_dependencies.begin(), m_dependencies.end(), assetInfo);
|
||||
if(existingEntry != m_dependencies.end())
|
||||
if (existingEntry != m_dependencies.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -26,31 +28,12 @@ void AssetLoader::AddDependency(XAssetInfoGeneric* assetInfo)
|
||||
|
||||
scr_string_t AssetLoader::UseScriptString(const scr_string_t scrString)
|
||||
{
|
||||
std::string& scrStringValue = m_script_string_provider->GetZoneScriptString(scrString);
|
||||
assert(scrString < m_zone->m_script_strings.size());
|
||||
|
||||
scr_string_t scriptStringIndex = 0;
|
||||
for(auto& existingScriptString : m_used_script_strings)
|
||||
{
|
||||
if(existingScriptString == scrStringValue)
|
||||
{
|
||||
return scriptStringIndex;
|
||||
}
|
||||
if (scrString >= m_zone->m_script_strings.size())
|
||||
return 0u;
|
||||
|
||||
scriptStringIndex++;
|
||||
}
|
||||
|
||||
scriptStringIndex = static_cast<scr_string_t>(m_used_script_strings.size());
|
||||
|
||||
// If an asset uses script strings make sure that script string 0 is always empty
|
||||
if(scriptStringIndex == 0 && !scrStringValue.empty())
|
||||
{
|
||||
m_used_script_strings.emplace_back("");
|
||||
scriptStringIndex++;
|
||||
}
|
||||
|
||||
m_used_script_strings.push_back(scrStringValue);
|
||||
|
||||
return scriptStringIndex;
|
||||
return scrString;
|
||||
}
|
||||
|
||||
void AssetLoader::LoadScriptStringArray(const bool atStreamStart, const size_t count)
|
||||
@ -68,31 +51,12 @@ void AssetLoader::LoadScriptStringArray(const bool atStreamStart, const size_t c
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoader::LoadScriptStringArrayRealloc(const bool atStreamStart, const size_t count)
|
||||
{
|
||||
assert(varScriptString != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<scr_string_t>(varScriptString, count);
|
||||
|
||||
auto* scriptStringsNew = static_cast<scr_string_t*>(m_zone->GetMemory()->Alloc(sizeof scr_string_t * count));
|
||||
memcpy_s(scriptStringsNew, sizeof scr_string_t * count, varScriptString, sizeof scr_string_t * count);
|
||||
varScriptString = scriptStringsNew;
|
||||
|
||||
auto* ptr = varScriptString;
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
*ptr = UseScriptString(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoader::LinkAsset(std::string name, void* asset)
|
||||
{
|
||||
return m_zone->GetPools()->AddAsset(m_asset_type, std::move(name), asset, m_used_script_strings, m_dependencies);;
|
||||
return m_zone->m_pools->AddAsset(m_asset_type, std::move(name), asset, m_dependencies);
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoader::GetAssetInfo(std::string name) const
|
||||
{
|
||||
return m_zone->GetPools()->GetAsset(m_asset_type, std::move(name));
|
||||
return m_zone->m_pools->GetAsset(m_asset_type, std::move(name));
|
||||
}
|
||||
|
@ -1,28 +1,22 @@
|
||||
#pragma once
|
||||
#include "Pool/XAssetInfo.h"
|
||||
#include "ContentLoaderBase.h"
|
||||
#include "IZoneScriptStringProvider.h"
|
||||
|
||||
class AssetLoader : public ContentLoaderBase
|
||||
{
|
||||
asset_type_t m_asset_type;
|
||||
|
||||
std::vector<std::string> m_used_script_strings;
|
||||
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
|
||||
protected:
|
||||
IZoneScriptStringProvider* m_script_string_provider;
|
||||
|
||||
scr_string_t* varScriptString;
|
||||
|
||||
AssetLoader(asset_type_t assetType, IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);
|
||||
AssetLoader(asset_type_t assetType, Zone* zone, IZoneInputStream* stream);
|
||||
|
||||
void AddDependency(XAssetInfoGeneric* assetInfo);
|
||||
|
||||
scr_string_t UseScriptString(scr_string_t scrString);
|
||||
void LoadScriptStringArray(bool atStreamStart, size_t count);
|
||||
void LoadScriptStringArrayRealloc(bool atStreamStart, size_t count);
|
||||
|
||||
XAssetInfoGeneric* LinkAsset(std::string name, void* asset);
|
||||
|
||||
|
@ -5,11 +5,17 @@ const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
||||
const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast<void*>(-2);
|
||||
|
||||
ContentLoaderBase::ContentLoaderBase()
|
||||
: varXString(nullptr),
|
||||
m_zone(nullptr),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
varXString = nullptr;
|
||||
}
|
||||
|
||||
m_zone = nullptr;
|
||||
m_stream = nullptr;
|
||||
ContentLoaderBase::ContentLoaderBase(Zone* zone, IZoneInputStream* stream)
|
||||
: varXString(nullptr),
|
||||
m_zone(zone),
|
||||
m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
void ContentLoaderBase::LoadXString(const bool atStreamStart) const
|
||||
@ -19,9 +25,9 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const
|
||||
if (atStreamStart)
|
||||
m_stream->Load<const char*>(varXString);
|
||||
|
||||
if(*varXString != nullptr)
|
||||
if (*varXString != nullptr)
|
||||
{
|
||||
if(*varXString == PTR_FOLLOWING)
|
||||
if (*varXString == PTR_FOLLOWING)
|
||||
{
|
||||
*varXString = m_stream->Alloc<const char>(alignof(const char));
|
||||
m_stream->LoadNullTerminated(const_cast<char*>(*varXString));
|
||||
@ -37,12 +43,12 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
|
||||
{
|
||||
assert(varXString != nullptr);
|
||||
|
||||
if(atStreamStart)
|
||||
if (atStreamStart)
|
||||
m_stream->Load<const char*>(varXString, count);
|
||||
|
||||
for(size_t index = 0; index < count; index++)
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
LoadXString(false);
|
||||
varXString++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ protected:
|
||||
IZoneInputStream* m_stream;
|
||||
|
||||
ContentLoaderBase();
|
||||
ContentLoaderBase(Zone* zone, IZoneInputStream* stream);
|
||||
|
||||
void LoadXString(bool atStreamStart) const;
|
||||
void LoadXStringArray(bool atStreamStart, size_t count);
|
||||
|
@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/ZoneTypes.h"
|
||||
#include <string>
|
||||
|
||||
class IZoneScriptStringProvider
|
||||
{
|
||||
public:
|
||||
virtual std::string& GetZoneScriptString(scr_string_t scrString) = 0;
|
||||
};
|
Reference in New Issue
Block a user