mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
ObjLoading/ObjWriting: Initial skeleton for loading and writing obj files
This commit is contained in:
parent
a0d4e87b8e
commit
af55c202cf
@ -105,6 +105,7 @@ include "src/ZoneCommon.lua"
|
|||||||
include "src/ZoneLoading.lua"
|
include "src/ZoneLoading.lua"
|
||||||
include "src/ZoneWriting.lua"
|
include "src/ZoneWriting.lua"
|
||||||
include "src/ZoneCommon.lua"
|
include "src/ZoneCommon.lua"
|
||||||
|
include "src/ObjCommon.lua"
|
||||||
include "src/ObjLoading.lua"
|
include "src/ObjLoading.lua"
|
||||||
include "src/ObjWriting.lua"
|
include "src/ObjWriting.lua"
|
||||||
|
|
||||||
@ -117,6 +118,7 @@ group "Components"
|
|||||||
ZoneCommon:project()
|
ZoneCommon:project()
|
||||||
ZoneLoading:project()
|
ZoneLoading:project()
|
||||||
ZoneWriting:project()
|
ZoneWriting:project()
|
||||||
|
ObjCommon:project()
|
||||||
ObjLoading:project()
|
ObjLoading:project()
|
||||||
ObjWriting:project()
|
ObjWriting:project()
|
||||||
group ""
|
group ""
|
||||||
|
44
src/ObjCommon.lua
Normal file
44
src/ObjCommon.lua
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
ObjCommon = {}
|
||||||
|
|
||||||
|
function ObjCommon:include()
|
||||||
|
ZoneCommon:include()
|
||||||
|
includedirs {
|
||||||
|
path.join(ProjectFolder(), "ObjCommon")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function ObjCommon:link()
|
||||||
|
Utils:link()
|
||||||
|
ZoneCommon:link()
|
||||||
|
links {
|
||||||
|
"ObjCommon"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function ObjCommon:use()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function ObjCommon:project()
|
||||||
|
local folder = ProjectFolder();
|
||||||
|
|
||||||
|
project "ObjCommon"
|
||||||
|
targetdir(TargetDirectoryLib)
|
||||||
|
location "%{wks.location}/src/%{prj.name}"
|
||||||
|
kind "StaticLib"
|
||||||
|
language "C++"
|
||||||
|
|
||||||
|
files {
|
||||||
|
path.join(folder, "ObjCommon/**.h"),
|
||||||
|
path.join(folder, "ObjCommon/**.cpp")
|
||||||
|
}
|
||||||
|
|
||||||
|
vpaths {
|
||||||
|
["*"] = {
|
||||||
|
path.join(folder, "ObjCommon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self:include()
|
||||||
|
Utils:include()
|
||||||
|
end
|
0
src/ObjCommon/Obj/GDT/GDT.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDT.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDT.h
Normal file
0
src/ObjCommon/Obj/GDT/GDT.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTEntry.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDTEntry.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDTEntry.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTEntry.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTProperty.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDTProperty.cpp
Normal file
0
src/ObjCommon/Obj/GDT/GDTProperty.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTProperty.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTPropertyType.h
Normal file
0
src/ObjCommon/Obj/GDT/GDTPropertyType.h
Normal file
11
src/ObjCommon/ObjContainer/IObjContainer.h
Normal file
11
src/ObjCommon/ObjContainer/IObjContainer.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class IObjContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IObjContainer() = default;
|
||||||
|
|
||||||
|
virtual const std::string& GetName() = 0;
|
||||||
|
};
|
60
src/ObjCommon/ObjContainer/IPak/IPakTypes.h
Normal file
60
src/ObjCommon/ObjContainer/IPak/IPakTypes.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
typedef uint32_t IPakHash;
|
||||||
|
|
||||||
|
struct IPakHeader
|
||||||
|
{
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t sectionCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IPakSection
|
||||||
|
{
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t itemCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
union IPakIndexEntryKey
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
IPakHash nameHash;
|
||||||
|
IPakHash dataHash;
|
||||||
|
};
|
||||||
|
uint64_t combinedKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IPakIndexEntry
|
||||||
|
{
|
||||||
|
IPakIndexEntryKey key;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IPakDataChunkHeader
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t countAndOffset;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t offset : 24;
|
||||||
|
uint32_t count : 8;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t commands[31];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t size : 24;
|
||||||
|
uint32_t compressed : 8;
|
||||||
|
}_commands[31];
|
||||||
|
};
|
||||||
|
};
|
16
src/ObjCommon/ObjContainer/ObjContainerReferenceable.cpp
Normal file
16
src/ObjCommon/ObjContainer/ObjContainerReferenceable.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "ObjContainerReferenceable.h"
|
||||||
|
|
||||||
|
void ObjContainerReferenceable::AddReference(Zone* referencer)
|
||||||
|
{
|
||||||
|
m_references.insert(referencer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjContainerReferenceable::RemoveReference(Zone* zone)
|
||||||
|
{
|
||||||
|
return m_references.erase(zone) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjContainerReferenceable::IsReferenced() const
|
||||||
|
{
|
||||||
|
return !m_references.empty();
|
||||||
|
}
|
16
src/ObjCommon/ObjContainer/ObjContainerReferenceable.h
Normal file
16
src/ObjCommon/ObjContainer/ObjContainerReferenceable.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IObjContainer.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
class ObjContainerReferenceable : public IObjContainer
|
||||||
|
{
|
||||||
|
std::set<Zone*> m_references;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void AddReference(Zone* referencer);
|
||||||
|
bool RemoveReference(Zone* zone);
|
||||||
|
bool IsReferenced() const;
|
||||||
|
};
|
@ -1,6 +1,7 @@
|
|||||||
ObjLoading = {}
|
ObjLoading = {}
|
||||||
|
|
||||||
function ObjLoading:include()
|
function ObjLoading:include()
|
||||||
|
ObjCommon:include()
|
||||||
ZoneCommon:include()
|
ZoneCommon:include()
|
||||||
includedirs {
|
includedirs {
|
||||||
path.join(ProjectFolder(), "ObjLoading")
|
path.join(ProjectFolder(), "ObjLoading")
|
||||||
@ -9,7 +10,11 @@ end
|
|||||||
|
|
||||||
function ObjLoading:link()
|
function ObjLoading:link()
|
||||||
Utils:link()
|
Utils:link()
|
||||||
|
ObjCommon:link()
|
||||||
ZoneCommon:link()
|
ZoneCommon:link()
|
||||||
|
minilzo:link()
|
||||||
|
minizip:link()
|
||||||
|
zlib:link()
|
||||||
links {
|
links {
|
||||||
"ObjLoading"
|
"ObjLoading"
|
||||||
}
|
}
|
||||||
@ -40,5 +45,9 @@ function ObjLoading:project()
|
|||||||
}
|
}
|
||||||
|
|
||||||
self:include()
|
self:include()
|
||||||
|
Crypto:include()
|
||||||
Utils:include()
|
Utils:include()
|
||||||
|
minilzo:include()
|
||||||
|
minizip:include()
|
||||||
|
zlib:include()
|
||||||
end
|
end
|
||||||
|
60
src/ObjLoading/Game/T6/ObjLoaderT6.cpp
Normal file
60
src/ObjLoading/Game/T6/ObjLoaderT6.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "ObjLoaderT6.h"
|
||||||
|
#include "Game/T6/GameT6.h"
|
||||||
|
#include "Game/T6/GameAssetPoolT6.h"
|
||||||
|
|
||||||
|
const int ObjLoaderT6::IPAK_READ_HASH = ObjLoaderT6::Com_HashKey("ipak_read", 64);
|
||||||
|
const int ObjLoaderT6::GLOBAL_HASH = ObjLoaderT6::Com_HashKey("GLOBAL", 64);
|
||||||
|
|
||||||
|
int ObjLoaderT6::Com_HashKey(const char* str, const int maxLen)
|
||||||
|
{
|
||||||
|
if (str == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int hash = 0;
|
||||||
|
for (int i = 0; i < maxLen; i++)
|
||||||
|
{
|
||||||
|
if (str[i] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
hash += str[i] * (0x77 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjLoaderT6::SupportsZone(Zone* zone)
|
||||||
|
{
|
||||||
|
return zone->m_game == &g_GameT6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjLoaderT6::LoadIPakForZone(std::string ipakName, Zone* zone)
|
||||||
|
{
|
||||||
|
printf("Loading ipak '%s' for zone '%s'\n", ipakName.c_str(), zone->m_name.c_str());
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjLoaderT6::LoadReferencedContainersForZone(Zone* zone)
|
||||||
|
{
|
||||||
|
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(zone->GetPools());
|
||||||
|
const int zoneNameHash = Com_HashKey(zone->m_name.c_str(), 64);
|
||||||
|
|
||||||
|
if(assetPoolT6->m_key_value_pairs != nullptr)
|
||||||
|
{
|
||||||
|
for(auto* keyValuePairs : *assetPoolT6->m_key_value_pairs)
|
||||||
|
{
|
||||||
|
for(int variableIndex = 0; variableIndex < keyValuePairs->m_asset->numVariables; variableIndex++)
|
||||||
|
{
|
||||||
|
T6::KeyValuePair* variable = &keyValuePairs->m_asset->keyValuePairs[variableIndex];
|
||||||
|
|
||||||
|
if(variable->namespaceHash == zoneNameHash && variable->keyHash == IPAK_READ_HASH)
|
||||||
|
{
|
||||||
|
LoadIPakForZone(variable->value, zone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjLoaderT6::LoadObjDataForZone(Zone* zone)
|
||||||
|
{
|
||||||
|
}
|
17
src/ObjLoading/Game/T6/ObjLoaderT6.h
Normal file
17
src/ObjLoading/Game/T6/ObjLoaderT6.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IObjLoader.h"
|
||||||
|
|
||||||
|
class ObjLoaderT6 final : public IObjLoader
|
||||||
|
{
|
||||||
|
static const int IPAK_READ_HASH;
|
||||||
|
static const int GLOBAL_HASH;
|
||||||
|
static int Com_HashKey(const char* str, int maxLen);
|
||||||
|
|
||||||
|
static void LoadIPakForZone(std::string ipakName, Zone* zone);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool SupportsZone(Zone* zone) override;
|
||||||
|
void LoadReferencedContainersForZone(Zone* zone) override;
|
||||||
|
void LoadObjDataForZone(Zone* zone) override;
|
||||||
|
};
|
13
src/ObjLoading/IObjLoader.h
Normal file
13
src/ObjLoading/IObjLoader.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
class IObjLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IObjLoader() = default;
|
||||||
|
|
||||||
|
virtual bool SupportsZone(Zone* zone) = 0;
|
||||||
|
virtual void LoadReferencedContainersForZone(Zone* zone) = 0;
|
||||||
|
virtual void LoadObjDataForZone(Zone* zone) = 0;
|
||||||
|
};
|
@ -0,0 +1,16 @@
|
|||||||
|
#include "IPakLoadException.h"
|
||||||
|
|
||||||
|
IPakLoadException::IPakLoadException(std::string message)
|
||||||
|
{
|
||||||
|
m_message = std::move(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& IPakLoadException::DetailedMessage() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* IPakLoadException::what() const
|
||||||
|
{
|
||||||
|
return "There was an error when trying to load an ipak file.";
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class IPakLoadException final : public std::exception
|
||||||
|
{
|
||||||
|
std::string m_message;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IPakLoadException(std::string message);
|
||||||
|
|
||||||
|
const std::string& DetailedMessage() const;
|
||||||
|
char const* what() const override;
|
||||||
|
};
|
122
src/ObjLoading/ObjContainer/IPak/IPak.cpp
Normal file
122
src/ObjLoading/ObjContainer/IPak/IPak.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "IPak.h"
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "Exception/IPakLoadException.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
const uint32_t IPak::MAGIC = 'IPAK';
|
||||||
|
const uint32_t IPak::VERSION = 0x50000;
|
||||||
|
|
||||||
|
uint32_t IPak::R_HashString(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (const char* pos = str; *pos; pos++)
|
||||||
|
{
|
||||||
|
hash = 33 * hash ^ (*pos | 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPak::IPak(FileAPI::IFile* file)
|
||||||
|
{
|
||||||
|
m_file = file;
|
||||||
|
m_initialized = false;
|
||||||
|
m_index_section = nullptr;
|
||||||
|
m_data_section = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPak::~IPak()
|
||||||
|
{
|
||||||
|
delete m_index_section;
|
||||||
|
m_index_section = nullptr;
|
||||||
|
|
||||||
|
delete m_data_section;
|
||||||
|
m_data_section = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPak::ReadSection()
|
||||||
|
{
|
||||||
|
IPakSection section{};
|
||||||
|
|
||||||
|
if (m_file->Read(§ion, sizeof section, 1) != sizeof section)
|
||||||
|
throw IPakLoadException("Unexpected eof when trying to load section.");
|
||||||
|
|
||||||
|
switch (section.type)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
m_index_section = new IPakSection(section);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
m_data_section = new IPakSection(section);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPak::ReadHeader()
|
||||||
|
{
|
||||||
|
IPakHeader header{};
|
||||||
|
|
||||||
|
if (m_file->Read(&header, sizeof header, 1) != sizeof header)
|
||||||
|
throw IPakLoadException("Unexpected eof when trying to load header.");
|
||||||
|
|
||||||
|
if (header.magic != MAGIC)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Invalid magic '0x" << std::hex << header.magic << "'.";
|
||||||
|
|
||||||
|
throw IPakLoadException(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(header.version != VERSION)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Unsupported version '" << header.version << "'.";
|
||||||
|
|
||||||
|
throw IPakLoadException(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned section = 0; section < header.sectionCount; section++)
|
||||||
|
{
|
||||||
|
ReadSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_index_section == nullptr)
|
||||||
|
{
|
||||||
|
throw IPakLoadException("IPak does not contain an index section.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_data_section == nullptr)
|
||||||
|
{
|
||||||
|
throw IPakLoadException("IPak does not contain a data section.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPak::Initialize()
|
||||||
|
{
|
||||||
|
if (m_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ReadHeader();
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileAPI::IFile* IPak::GetEntryData(IPakHash nameHash, IPakHash dataHash)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPakHash IPak::HashString(const std::string& str)
|
||||||
|
{
|
||||||
|
return R_HashString(str.c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPakHash IPak::HashData(const void* data, const size_t dataSize)
|
||||||
|
{
|
||||||
|
return crc32(0, static_cast<const Bytef*>(data), dataSize);
|
||||||
|
}
|
37
src/ObjLoading/ObjContainer/IPak/IPak.h
Normal file
37
src/ObjLoading/ObjContainer/IPak/IPak.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Utils/FileAPI.h"
|
||||||
|
#include "ObjContainer/IPak/IPakTypes.h"
|
||||||
|
#include "ObjContainer/ObjContainerReferenceable.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class IPak final : public ObjContainerReferenceable
|
||||||
|
{
|
||||||
|
static const uint32_t MAGIC;
|
||||||
|
static const uint32_t VERSION;
|
||||||
|
|
||||||
|
FileAPI::IFile* m_file;
|
||||||
|
|
||||||
|
bool m_initialized;
|
||||||
|
|
||||||
|
IPakSection* m_index_section;
|
||||||
|
IPakSection* m_data_section;
|
||||||
|
|
||||||
|
std::vector<IPakIndexEntry> m_index_entries;
|
||||||
|
|
||||||
|
static uint32_t R_HashString(const char* str, uint32_t hash);
|
||||||
|
|
||||||
|
void ReadSection();
|
||||||
|
void ReadHeader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IPak(FileAPI::IFile* file);
|
||||||
|
~IPak();
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
FileAPI::IFile* GetEntryData(IPakHash nameHash, IPakHash dataHash);
|
||||||
|
|
||||||
|
static IPakHash HashString(const std::string& str);
|
||||||
|
static IPakHash HashData(const void* data, size_t dataSize);
|
||||||
|
};
|
0
src/ObjLoading/ObjContainer/IWD/IWD.cpp
Normal file
0
src/ObjLoading/ObjContainer/IWD/IWD.cpp
Normal file
0
src/ObjLoading/ObjContainer/IWD/IWD.h
Normal file
0
src/ObjLoading/ObjContainer/IWD/IWD.h
Normal file
52
src/ObjLoading/ObjContainer/ObjContainerRegistry.cpp
Normal file
52
src/ObjLoading/ObjContainer/ObjContainerRegistry.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include "ObjContainerRegistry.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
ObjContainerRegistry g_ObjContainerRegistry;
|
||||||
|
|
||||||
|
IObjContainer* ObjContainerRegistry::GetContainerByName(const std::string& name)
|
||||||
|
{
|
||||||
|
for (auto* container : m_containers)
|
||||||
|
{
|
||||||
|
if (container->GetName() == name)
|
||||||
|
{
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjContainerRegistry::AddContainer(IObjContainer* container)
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<ObjContainerReferenceable*>(container) == nullptr);
|
||||||
|
|
||||||
|
m_containers.push_back(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjContainerRegistry::AddContainerWithReference(ObjContainerReferenceable* container, Zone* referencer)
|
||||||
|
{
|
||||||
|
container->AddReference(referencer);
|
||||||
|
m_containers.push_back(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjContainerRegistry::RemoveContainerReferences(Zone* referencer)
|
||||||
|
{
|
||||||
|
auto iContainer = m_containers.begin();
|
||||||
|
|
||||||
|
while (iContainer != m_containers.end())
|
||||||
|
{
|
||||||
|
auto* container = *iContainer;
|
||||||
|
|
||||||
|
if (auto* referenceableContainer = dynamic_cast<ObjContainerReferenceable*>(container))
|
||||||
|
{
|
||||||
|
if (referenceableContainer->RemoveReference(referencer) && !referenceableContainer->IsReferenced())
|
||||||
|
{
|
||||||
|
delete container;
|
||||||
|
iContainer = m_containers.erase(iContainer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++iContainer;
|
||||||
|
}
|
||||||
|
}
|
22
src/ObjLoading/ObjContainer/ObjContainerRegistry.h
Normal file
22
src/ObjLoading/ObjContainer/ObjContainerRegistry.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ObjContainer/IObjContainer.h"
|
||||||
|
#include "ObjContainer/ObjContainerReferenceable.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class ObjContainerRegistry
|
||||||
|
{
|
||||||
|
std::vector<IObjContainer*> m_containers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void AddContainer(IObjContainer* container);
|
||||||
|
void AddContainerWithReference(ObjContainerReferenceable* container, Zone* referencer);
|
||||||
|
void RemoveContainerReferences(Zone* referencer);
|
||||||
|
|
||||||
|
IObjContainer* GetContainerByName(const std::string& name);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ObjContainerRegistry g_ObjContainerRegistry;
|
38
src/ObjLoading/ObjLoading.cpp
Normal file
38
src/ObjLoading/ObjLoading.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "ObjLoading.h"
|
||||||
|
#include "IObjLoader.h"
|
||||||
|
#include "Game/T6/ObjLoaderT6.h"
|
||||||
|
#include "ObjContainer/ObjContainerRegistry.h"
|
||||||
|
|
||||||
|
IObjLoader* objLoaders[]
|
||||||
|
{
|
||||||
|
new ObjLoaderT6()
|
||||||
|
};
|
||||||
|
|
||||||
|
void ObjLoading::LoadReferencedContainersForZone(Zone* zone)
|
||||||
|
{
|
||||||
|
for (auto* loader : objLoaders)
|
||||||
|
{
|
||||||
|
if (loader->SupportsZone(zone))
|
||||||
|
{
|
||||||
|
loader->LoadReferencedContainersForZone(zone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjLoading::LoadObjDataForZone(Zone* zone)
|
||||||
|
{
|
||||||
|
for (auto* loader : objLoaders)
|
||||||
|
{
|
||||||
|
if (loader->SupportsZone(zone))
|
||||||
|
{
|
||||||
|
loader->LoadObjDataForZone(zone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjLoading::UnloadContainersOfZone(Zone* zone)
|
||||||
|
{
|
||||||
|
g_ObjContainerRegistry.RemoveContainerReferences(zone);
|
||||||
|
}
|
11
src/ObjLoading/ObjLoading.h
Normal file
11
src/ObjLoading/ObjLoading.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
class ObjLoading
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void LoadReferencedContainersForZone(Zone* zone);
|
||||||
|
static void LoadObjDataForZone(Zone* zone);
|
||||||
|
static void UnloadContainersOfZone(Zone* zone);
|
||||||
|
};
|
12
src/ObjLoading/SearchPath/ISearchPath.h
Normal file
12
src/ObjLoading/SearchPath/ISearchPath.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Utils/FileAPI.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ISearchPath
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ISearchPath() = default;
|
||||||
|
|
||||||
|
virtual FileAPI::IFile* Open(const std::string& fileName) = 0;
|
||||||
|
};
|
0
src/ObjLoading/SearchPath/SearchPathFilesystem.cpp
Normal file
0
src/ObjLoading/SearchPath/SearchPathFilesystem.cpp
Normal file
0
src/ObjLoading/SearchPath/SearchPathFilesystem.h
Normal file
0
src/ObjLoading/SearchPath/SearchPathFilesystem.h
Normal file
78
src/ObjLoading/SearchPath/SearchPaths.cpp
Normal file
78
src/ObjLoading/SearchPath/SearchPaths.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "SearchPaths.h"
|
||||||
|
|
||||||
|
SearchPaths::~SearchPaths()
|
||||||
|
{
|
||||||
|
for(auto searchPath : m_search_paths)
|
||||||
|
{
|
||||||
|
delete searchPath;
|
||||||
|
}
|
||||||
|
m_search_paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths::SearchPaths(const SearchPaths& other)
|
||||||
|
: m_search_paths(other.m_search_paths)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths::SearchPaths(SearchPaths&& other) noexcept
|
||||||
|
: m_search_paths(std::move(other.m_search_paths))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths& SearchPaths::operator=(const SearchPaths& other)
|
||||||
|
{
|
||||||
|
m_search_paths = other.m_search_paths;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths& SearchPaths::operator=(SearchPaths&& other) noexcept
|
||||||
|
{
|
||||||
|
m_search_paths = std::move(other.m_search_paths);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileAPI::IFile* SearchPaths::Open(const std::string& fileName)
|
||||||
|
{
|
||||||
|
for(auto searchPath : m_search_paths)
|
||||||
|
{
|
||||||
|
auto* file = searchPath->Open(fileName);
|
||||||
|
|
||||||
|
if(file != nullptr)
|
||||||
|
{
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchPaths::AddSearchPath(ISearchPath* searchPath)
|
||||||
|
{
|
||||||
|
m_search_paths.push_back(searchPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchPaths::RemoveSearchPath(ISearchPath* searchPath)
|
||||||
|
{
|
||||||
|
for(auto i = m_search_paths.begin(); i != m_search_paths.end(); ++i)
|
||||||
|
{
|
||||||
|
if(*i == searchPath)
|
||||||
|
{
|
||||||
|
m_search_paths.erase(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths::iterator SearchPaths::begin()
|
||||||
|
{
|
||||||
|
return m_search_paths.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths::iterator SearchPaths::end()
|
||||||
|
{
|
||||||
|
return m_search_paths.end();
|
||||||
|
}
|
26
src/ObjLoading/SearchPath/SearchPaths.h
Normal file
26
src/ObjLoading/SearchPath/SearchPaths.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISearchPath.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class SearchPaths final : public ISearchPath
|
||||||
|
{
|
||||||
|
std::vector<ISearchPath*> m_search_paths;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator = std::vector<ISearchPath*>::iterator;
|
||||||
|
|
||||||
|
~SearchPaths() override;
|
||||||
|
FileAPI::IFile* Open(const std::string& fileName) override;
|
||||||
|
|
||||||
|
SearchPaths(const SearchPaths& other);
|
||||||
|
SearchPaths(SearchPaths&& other) noexcept;
|
||||||
|
SearchPaths& operator=(const SearchPaths& other);
|
||||||
|
SearchPaths& operator=(SearchPaths&& other) noexcept;
|
||||||
|
|
||||||
|
void AddSearchPath(ISearchPath* searchPath);
|
||||||
|
void RemoveSearchPath(ISearchPath* searchPath);
|
||||||
|
|
||||||
|
iterator begin();
|
||||||
|
iterator end();
|
||||||
|
};
|
@ -1,6 +1,7 @@
|
|||||||
ObjWriting = {}
|
ObjWriting = {}
|
||||||
|
|
||||||
function ObjWriting:include()
|
function ObjWriting:include()
|
||||||
|
ObjCommon:include()
|
||||||
ZoneCommon:include()
|
ZoneCommon:include()
|
||||||
includedirs {
|
includedirs {
|
||||||
path.join(ProjectFolder(), "ObjWriting")
|
path.join(ProjectFolder(), "ObjWriting")
|
||||||
@ -9,7 +10,10 @@ end
|
|||||||
|
|
||||||
function ObjWriting:link()
|
function ObjWriting:link()
|
||||||
Utils:link()
|
Utils:link()
|
||||||
|
ObjCommon:link()
|
||||||
ZoneCommon:link()
|
ZoneCommon:link()
|
||||||
|
minilzo:link()
|
||||||
|
minizip:link()
|
||||||
links {
|
links {
|
||||||
"ObjWriting"
|
"ObjWriting"
|
||||||
}
|
}
|
||||||
@ -41,4 +45,6 @@ function ObjWriting:project()
|
|||||||
|
|
||||||
self:include()
|
self:include()
|
||||||
Utils:include()
|
Utils:include()
|
||||||
|
minilzo:include()
|
||||||
|
minizip:include()
|
||||||
end
|
end
|
||||||
|
0
src/ObjWriting/ObjContainer/IPak/IPakWriter.cpp
Normal file
0
src/ObjWriting/ObjContainer/IPak/IPakWriter.cpp
Normal file
0
src/ObjWriting/ObjContainer/IPak/IPakWriter.h
Normal file
0
src/ObjWriting/ObjContainer/IPak/IPakWriter.h
Normal file
0
src/ObjWriting/ObjContainer/IWD/IWDWriter.cpp
Normal file
0
src/ObjWriting/ObjContainer/IWD/IWDWriter.cpp
Normal file
0
src/ObjWriting/ObjContainer/IWD/IWDWriter.h
Normal file
0
src/ObjWriting/ObjContainer/IWD/IWDWriter.h
Normal file
@ -31,9 +31,11 @@ function Unlinker:project()
|
|||||||
self:include()
|
self:include()
|
||||||
Utils:include()
|
Utils:include()
|
||||||
ZoneLoading:include()
|
ZoneLoading:include()
|
||||||
|
ObjLoading:include()
|
||||||
ObjWriting:include()
|
ObjWriting:include()
|
||||||
|
|
||||||
Utils:link()
|
Utils:link()
|
||||||
ZoneLoading:link()
|
ZoneLoading:link()
|
||||||
|
ObjLoading:link()
|
||||||
ObjWriting:link()
|
ObjWriting:link()
|
||||||
end
|
end
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include "Utils/PathUtils.h"
|
#include "Utils/PathUtils.h"
|
||||||
#include "Utils/FileAPI.h"
|
#include "Utils/FileAPI.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
const CommandLineOption* optionHelp = CommandLineOption::Builder::Create()
|
const CommandLineOption* optionHelp = CommandLineOption::Builder::Create()
|
||||||
.WithShortName("?")
|
.WithShortName("?")
|
||||||
@ -148,6 +148,9 @@ int main(const int argc, const char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjLoading::LoadReferencedContainersForZone(zone);
|
||||||
|
ObjLoading::LoadObjDataForZone(zone);
|
||||||
|
|
||||||
if(!HandleZone(zone, &argumentParser))
|
if(!HandleZone(zone, &argumentParser))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user