mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Unlinker: Make zone files creators game dependent and in the unlinker project instead of the ObjWriting component
This commit is contained in:
parent
992e9cea30
commit
9572391082
@ -5,26 +5,10 @@
|
|||||||
#include "ObjLoading.h"
|
#include "ObjLoading.h"
|
||||||
#include "Image/Texture.h"
|
#include "Image/Texture.h"
|
||||||
#include "Image/IwiLoader.h"
|
#include "Image/IwiLoader.h"
|
||||||
|
#include "Game/T6/CommonT6.h"
|
||||||
|
|
||||||
const int ObjLoaderT6::IPAK_READ_HASH = Com_HashKey("ipak_read", 64);
|
const int ObjLoaderT6::IPAK_READ_HASH = CommonT6::Com_HashKey("ipak_read", 64);
|
||||||
const int ObjLoaderT6::GLOBAL_HASH = Com_HashKey("GLOBAL", 64);
|
const int ObjLoaderT6::GLOBAL_HASH = CommonT6::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) const
|
bool ObjLoaderT6::SupportsZone(Zone* zone) const
|
||||||
{
|
{
|
||||||
@ -122,7 +106,7 @@ void ObjLoaderT6::LoadCommonIPaks(ISearchPath* searchPath, Zone* zone)
|
|||||||
void ObjLoaderT6::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const
|
void ObjLoaderT6::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const
|
||||||
{
|
{
|
||||||
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(zone->GetPools());
|
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(zone->GetPools());
|
||||||
const int zoneNameHash = Com_HashKey(zone->m_name.c_str(), 64);
|
const int zoneNameHash = CommonT6::Com_HashKey(zone->m_name.c_str(), 64);
|
||||||
|
|
||||||
LoadCommonIPaks(searchPath, zone);
|
LoadCommonIPaks(searchPath, zone);
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ class ObjLoaderT6 final : public IObjLoader
|
|||||||
{
|
{
|
||||||
static const int IPAK_READ_HASH;
|
static const int IPAK_READ_HASH;
|
||||||
static const int GLOBAL_HASH;
|
static const int GLOBAL_HASH;
|
||||||
static int Com_HashKey(const char* str, int maxLen);
|
|
||||||
|
|
||||||
static void LoadIPakForZone(ISearchPath* searchPath, const std::string& ipakName, Zone* zone);
|
static void LoadIPakForZone(ISearchPath* searchPath, const std::string& ipakName, Zone* zone);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Zone/Zone.h"
|
#include "Zone/Zone.h"
|
||||||
#include "Utils/FileAPI.h"
|
|
||||||
|
|
||||||
class IZoneDumper
|
class IZoneDumper
|
||||||
{
|
{
|
||||||
@ -10,5 +9,4 @@ public:
|
|||||||
|
|
||||||
virtual bool CanHandleZone(Zone* zone) const = 0;
|
virtual bool CanHandleZone(Zone* zone) const = 0;
|
||||||
virtual bool DumpZone(Zone* zone, const std::string& basePath) const = 0;
|
virtual bool DumpZone(Zone* zone, const std::string& basePath) const = 0;
|
||||||
virtual bool WriteZoneDefinition(Zone* zone, FileAPI::File* file) const = 0;
|
|
||||||
};
|
};
|
@ -78,9 +78,4 @@ bool ZoneDumperT6::DumpZone(Zone* zone, const std::string& basePath) const
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#undef DUMP_ASSET_POOL
|
#undef DUMP_ASSET_POOL
|
||||||
}
|
|
||||||
|
|
||||||
bool ZoneDumperT6::WriteZoneDefinition(Zone* zone, FileAPI::File* file) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
@ -6,5 +6,4 @@ class ZoneDumperT6 final : public IZoneDumper
|
|||||||
public:
|
public:
|
||||||
bool CanHandleZone(Zone* zone) const override;
|
bool CanHandleZone(Zone* zone) const override;
|
||||||
bool DumpZone(Zone* zone, const std::string& basePath) const override;
|
bool DumpZone(Zone* zone, const std::string& basePath) const override;
|
||||||
bool WriteZoneDefinition(Zone* zone, FileAPI::File* file) const override;
|
|
||||||
};
|
};
|
||||||
|
@ -26,9 +26,4 @@ bool ObjWriting::DumpZone(Zone* zone, const std::string& basePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
bool ObjWriting::WriteZoneDefinition(Zone* zone, FileAPI::File* file)
|
|
||||||
{
|
|
||||||
return file->Printf("// %s", "Insert zone definition here") > 0;
|
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Zone/Zone.h"
|
#include "Zone/Zone.h"
|
||||||
#include "Utils/FileAPI.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class ObjWriting
|
class ObjWriting
|
||||||
@ -18,10 +17,8 @@ public:
|
|||||||
|
|
||||||
bool Verbose = false;
|
bool Verbose = false;
|
||||||
ImageOutputFormat_e ImageOutputFormat = ImageOutputFormat_e::DDS;
|
ImageOutputFormat_e ImageOutputFormat = ImageOutputFormat_e::DDS;
|
||||||
bool MinimalZoneFileOutput = false;
|
|
||||||
|
|
||||||
} Configuration;
|
} Configuration;
|
||||||
|
|
||||||
static bool DumpZone(Zone* zone, const std::string& basePath);
|
static bool DumpZone(Zone* zone, const std::string& basePath);
|
||||||
static bool WriteZoneDefinition(Zone* zone, FileAPI::File* file);
|
|
||||||
};
|
};
|
||||||
|
39
src/Unlinker/ContentLister/ZoneDefWriter.cpp
Normal file
39
src/Unlinker/ContentLister/ZoneDefWriter.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "ZoneDefWriter.h"
|
||||||
|
|
||||||
|
const std::string AbstractZoneDefWriter::META_DATA_KEY_GAME = "game";
|
||||||
|
|
||||||
|
AbstractZoneDefWriter::AbstractZoneDefWriter(Zone* zone, FileAPI::IFile* file)
|
||||||
|
{
|
||||||
|
m_zone = zone;
|
||||||
|
m_file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractZoneDefWriter::EmptyLine() const
|
||||||
|
{
|
||||||
|
m_file->Printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractZoneDefWriter::WriteComment(const std::string& comment) const
|
||||||
|
{
|
||||||
|
m_file->Printf("// %s\n", comment.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractZoneDefWriter::WriteMetaData(const std::string& metaDataKey, const std::string& metaDataValue) const
|
||||||
|
{
|
||||||
|
m_file->Printf(">%s,%s\n", metaDataKey.c_str(), metaDataValue.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractZoneDefWriter::WriteEntry(const std::string& entryKey, const std::string& entryValue) const
|
||||||
|
{
|
||||||
|
m_file->Printf("%s,%s\n", entryKey.c_str(), entryValue.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractZoneDefWriter::WriteContent() const
|
||||||
|
{
|
||||||
|
auto zoneContent = m_zone->GetPools()->GetContent();
|
||||||
|
|
||||||
|
for(const auto& asset : zoneContent.m_assets)
|
||||||
|
{
|
||||||
|
WriteEntry(asset.m_asset_type_name, asset.m_asset_name);
|
||||||
|
}
|
||||||
|
}
|
30
src/Unlinker/ContentLister/ZoneDefWriter.h
Normal file
30
src/Unlinker/ContentLister/ZoneDefWriter.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Utils/FileAPI.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
class AbstractZoneDefWriter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Zone* m_zone;
|
||||||
|
FileAPI::IFile* m_file;
|
||||||
|
|
||||||
|
static const std::string META_DATA_KEY_GAME;
|
||||||
|
|
||||||
|
void EmptyLine() const;
|
||||||
|
void WriteComment(const std::string& comment) const;
|
||||||
|
void WriteMetaData(const std::string& metaDataKey, const std::string& metaDataValue) const;
|
||||||
|
void WriteEntry(const std::string& entryKey, const std::string& entryValue) const;
|
||||||
|
void WriteContent() const;
|
||||||
|
|
||||||
|
AbstractZoneDefWriter(Zone* zone, FileAPI::IFile* file);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void WriteZoneDef() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IZoneDefWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool CanHandleZone(Zone* zone) const = 0;
|
||||||
|
virtual void WriteZoneDef(Zone* zone, FileAPI::IFile* file) const = 0;
|
||||||
|
};
|
91
src/Unlinker/Game/T6/ZoneDefWriterT6.cpp
Normal file
91
src/Unlinker/Game/T6/ZoneDefWriterT6.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "ZoneDefWriterT6.h"
|
||||||
|
#include "Game/T6/GameT6.h"
|
||||||
|
#include "Game/T6/CommonT6.h"
|
||||||
|
#include "Game/T6/GameAssetPoolT6.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
class ZoneDefWriterT6Impl final : public AbstractZoneDefWriter
|
||||||
|
{
|
||||||
|
class KnownKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string m_key;
|
||||||
|
int m_hash;
|
||||||
|
|
||||||
|
explicit KnownKey(std::string key)
|
||||||
|
{
|
||||||
|
m_key = std::move(key);
|
||||||
|
m_hash = CommonT6::Com_HashKey(m_key.c_str(), 64);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static const KnownKey KNOWN_KEYS[]
|
||||||
|
{
|
||||||
|
KnownKey("ipak_read"),
|
||||||
|
KnownKey("ipak_write"),
|
||||||
|
KnownKey("initial_xmodels"),
|
||||||
|
KnownKey("initial_materials"),
|
||||||
|
};
|
||||||
|
|
||||||
|
void WriteKeyValuePair(KeyValuePair* kvp) const
|
||||||
|
{
|
||||||
|
for (const auto& knownKey : KNOWN_KEYS)
|
||||||
|
{
|
||||||
|
if(knownKey.m_hash == kvp->keyHash)
|
||||||
|
{
|
||||||
|
WriteMetaData("level." + knownKey.m_key, kvp->value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "level.@" << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << kvp->keyHash;
|
||||||
|
WriteMetaData(str.str(), kvp->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneDefWriterT6Impl(Zone* zone, FileAPI::IFile* file)
|
||||||
|
: AbstractZoneDefWriter(zone, file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteZoneDef() override
|
||||||
|
{
|
||||||
|
WriteComment("Call Of Duty: Black Ops II");
|
||||||
|
WriteMetaData(META_DATA_KEY_GAME, "t6");
|
||||||
|
EmptyLine();
|
||||||
|
|
||||||
|
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(m_zone->GetPools());
|
||||||
|
|
||||||
|
if(assetPoolT6 && !assetPoolT6->m_key_value_pairs->m_asset_lookup.empty())
|
||||||
|
{
|
||||||
|
for (auto kvpAsset : *assetPoolT6->m_key_value_pairs)
|
||||||
|
{
|
||||||
|
KeyValuePairs* keyValuePairs = kvpAsset->Asset();
|
||||||
|
for(int varIndex = 0; varIndex < keyValuePairs->numVariables; varIndex++)
|
||||||
|
{
|
||||||
|
WriteKeyValuePair(&keyValuePairs->keyValuePairs[varIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteContent();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ZoneDefWriterT6::CanHandleZone(Zone* zone) const
|
||||||
|
{
|
||||||
|
return zone->m_game == &g_GameT6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneDefWriterT6::WriteZoneDef(Zone* zone, FileAPI::IFile* file) const
|
||||||
|
{
|
||||||
|
ZoneDefWriterT6Impl writer(zone, file);
|
||||||
|
writer.WriteZoneDef();
|
||||||
|
}
|
10
src/Unlinker/Game/T6/ZoneDefWriterT6.h
Normal file
10
src/Unlinker/Game/T6/ZoneDefWriterT6.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ContentLister/ZoneDefWriter.h"
|
||||||
|
|
||||||
|
class ZoneDefWriterT6 final : public IZoneDefWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool CanHandleZone(Zone* zone) const override;
|
||||||
|
void WriteZoneDef(Zone* zone, FileAPI::IFile* file) const override;
|
||||||
|
};
|
@ -3,12 +3,14 @@
|
|||||||
#include "Utils/Arguments/ArgumentParser.h"
|
#include "Utils/Arguments/ArgumentParser.h"
|
||||||
#include "ZoneLoading.h"
|
#include "ZoneLoading.h"
|
||||||
#include "ObjWriting.h"
|
#include "ObjWriting.h"
|
||||||
#include "ContentPrinter.h"
|
#include "ContentLister/ContentPrinter.h"
|
||||||
#include "Utils/PathUtils.h"
|
#include "Utils/PathUtils.h"
|
||||||
#include "Utils/FileAPI.h"
|
#include "Utils/FileAPI.h"
|
||||||
#include "ObjLoading.h"
|
#include "ObjLoading.h"
|
||||||
#include "SearchPath/SearchPaths.h"
|
#include "SearchPath/SearchPaths.h"
|
||||||
#include "SearchPath/SearchPathFilesystem.h"
|
#include "SearchPath/SearchPathFilesystem.h"
|
||||||
|
#include "ContentLister/ZoneDefWriter.h"
|
||||||
|
#include "Game/T6/ZoneDefWriterT6.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
@ -16,6 +18,11 @@
|
|||||||
#include "ObjContainer/IWD/IWD.h"
|
#include "ObjContainer/IWD/IWD.h"
|
||||||
#include "UnlinkerArgs.h"
|
#include "UnlinkerArgs.h"
|
||||||
|
|
||||||
|
const IZoneDefWriter* const ZONE_DEF_WRITERS[]
|
||||||
|
{
|
||||||
|
new ZoneDefWriterT6()
|
||||||
|
};
|
||||||
|
|
||||||
class Unlinker::Impl
|
class Unlinker::Impl
|
||||||
{
|
{
|
||||||
UnlinkerArgs m_args;
|
UnlinkerArgs m_args;
|
||||||
@ -158,7 +165,14 @@ class Unlinker::Impl
|
|||||||
|
|
||||||
if (zoneDefinitionFile.IsOpen())
|
if (zoneDefinitionFile.IsOpen())
|
||||||
{
|
{
|
||||||
ObjWriting::WriteZoneDefinition(zone, &zoneDefinitionFile);
|
for (auto zoneDefWriter : ZONE_DEF_WRITERS)
|
||||||
|
{
|
||||||
|
if (zoneDefWriter->CanHandleZone(zone))
|
||||||
|
{
|
||||||
|
zoneDefWriter->WriteZoneDef(zone, &zoneDefinitionFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
ObjWriting::DumpZone(zone, outputFolderPath);
|
ObjWriting::DumpZone(zone, outputFolderPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -206,7 +206,7 @@ bool UnlinkerArgs::ParseArgs(const int argc, const char** argv)
|
|||||||
SetVerbose(m_argument_parser.IsOptionSpecified(OPTION_VERBOSE));
|
SetVerbose(m_argument_parser.IsOptionSpecified(OPTION_VERBOSE));
|
||||||
|
|
||||||
// -min; --minimal-zone
|
// -min; --minimal-zone
|
||||||
ObjWriting::Configuration.MinimalZoneFileOutput = m_argument_parser.IsOptionSpecified(OPTION_MINIMAL_ZONE_FILE);
|
m_minimal_zone_def = m_argument_parser.IsOptionSpecified(OPTION_MINIMAL_ZONE_FILE);
|
||||||
|
|
||||||
// -l; --list
|
// -l; --list
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_LIST))
|
if (m_argument_parser.IsOptionSpecified(OPTION_LIST))
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
|
|
||||||
ProcessingTask m_task;
|
ProcessingTask m_task;
|
||||||
std::string m_output_folder;
|
std::string m_output_folder;
|
||||||
|
bool m_minimal_zone_def;
|
||||||
|
|
||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
|
|
||||||
|
18
src/ZoneCommon/Game/T6/CommonT6.cpp
Normal file
18
src/ZoneCommon/Game/T6/CommonT6.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "CommonT6.h"
|
||||||
|
|
||||||
|
int CommonT6::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);
|
||||||
|
}
|
7
src/ZoneCommon/Game/T6/CommonT6.h
Normal file
7
src/ZoneCommon/Game/T6/CommonT6.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CommonT6
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int Com_HashKey(const char* str, int maxLen);
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user