[ZoneBuilder] Enumerate XAssetEntries instead of logging them

This commit is contained in:
momo5502 2017-05-01 13:08:34 +02:00
parent 70d7312472
commit 2c9a051aad
9 changed files with 134 additions and 45 deletions

View File

@ -142,29 +142,30 @@ namespace Assets
replacementFound = false; replacementFound = false;
// Find correct sortkey by comparing techsets // Find correct sortkey by comparing techsets
Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_MATERIAL, [](Game::XAssetHeader header, void* data) Game::DB_EnumXAssetEntries(Game::XAssetType::ASSET_TYPE_MATERIAL, [asset](Game::XAssetEntry* entry)
{ {
if (!replacementFound) if (!replacementFound)
{ {
Game::Material* material = reinterpret_cast<Game::Material*>(data); Game::XAssetHeader header = entry->asset.header;
const char* name = material->techniqueSet->name;
const char* name = asset->techniqueSet->name;
if (name[0] == ',') ++name; if (name[0] == ',') ++name;
if (std::string(name) == header.material->techniqueSet->name) if (std::string(name) == header.material->techniqueSet->name)
{ {
material->sortKey = header.material->sortKey; asset->sortKey = header.material->sortKey;
// This is temp, as nobody has time to fix materials // This is temp, as nobody has time to fix materials
material->stateBitsCount = header.material->stateBitsCount; asset->stateBitsCount = header.material->stateBitsCount;
material->stateBitTable = header.material->stateBitTable; asset->stateBitTable = header.material->stateBitTable;
std::memcpy(material->stateBitsEntry, header.material->stateBitsEntry, 48); std::memcpy(asset->stateBitsEntry, header.material->stateBitsEntry, 48);
material->constantCount = header.material->constantCount; asset->constantCount = header.material->constantCount;
material->constantTable = header.material->constantTable; asset->constantTable = header.material->constantTable;
replacementFound = true; replacementFound = true;
} }
} }
}, asset, false); }, false, false);
if (!replacementFound && asset->techniqueSet) if (!replacementFound && asset->techniqueSet)
{ {

View File

@ -696,6 +696,16 @@ namespace Components
Dvar::Var("isDlcInstalled_All").setRaw(hasAllDlcs ? 1 : 0); Dvar::Var("isDlcInstalled_All").setRaw(hasAllDlcs ? 1 : 0);
} }
Game::XAssetEntry* Maps::GetAssetEntryPool()
{
if(Maps::EntryPool.empty())
{
return reinterpret_cast<Game::XAssetEntry*>(0x134CAD8);
}
return Maps::EntryPool.data();
}
void Maps::reallocateEntryPool() void Maps::reallocateEntryPool()
{ {
AssertSize(Game::XAssetEntry, 16); AssertSize(Game::XAssetEntry, 16);

View File

@ -67,6 +67,8 @@ namespace Components
static UserMapContainer* GetUserMap(); static UserMapContainer* GetUserMap();
static unsigned int GetUsermapHash(std::string map); static unsigned int GetUsermapHash(std::string map);
static Game::XAssetEntry* GetAssetEntryPool();
private: private:
class DLC class DLC
{ {

View File

@ -555,13 +555,13 @@ namespace Components
if (type == Game::ASSET_TYPE_TECHNIQUE_SET) if (type == Game::ASSET_TYPE_TECHNIQUE_SET)
{ {
Utils::IO::CreateDir("userraw/techsets"); Utils::IO::CreateDir("userraw/techsets");
Utils::Stream* buffer = new Utils::Stream(0x1000); Utils::Stream buffer(0x1000);
Game::MaterialTechniqueSet* dest = buffer->dest<Game::MaterialTechniqueSet>(); Game::MaterialTechniqueSet* dest = buffer.dest<Game::MaterialTechniqueSet>();
buffer->save(asset.techniqueSet); buffer.save(asset.techniqueSet);
if (asset.techniqueSet->name) if (asset.techniqueSet->name)
{ {
buffer->saveString(asset.techniqueSet->name); buffer.saveString(asset.techniqueSet->name);
Utils::Stream::ClearPointer(&dest->name); Utils::Stream::ClearPointer(&dest->name);
} }
@ -575,15 +575,15 @@ namespace Components
if (!dest->techniques) if (!dest->techniques)
{ {
// Size-check is obsolete, as the structure is dynamic // Size-check is obsolete, as the structure is dynamic
buffer->align(Utils::Stream::ALIGN_4); buffer.align(Utils::Stream::ALIGN_4);
//storePointer(technique, buffer->); //storePointer(technique, buffer->);
Game::MaterialTechnique* destTechnique = buffer->dest<Game::MaterialTechnique>(); Game::MaterialTechnique* destTechnique = buffer.dest<Game::MaterialTechnique>();
buffer->save(technique, 8); buffer.save(technique, 8);
// Save_MaterialPassArray // Save_MaterialPassArray
Game::MaterialPass* destPasses = buffer->dest<Game::MaterialPass>(); Game::MaterialPass* destPasses = buffer.dest<Game::MaterialPass>();
buffer->saveArray(technique->passArray, technique->passCount); buffer.saveArray(technique->passArray, technique->passCount);
for (short j = 0; j < technique->passCount; ++j) for (short j = 0; j < technique->passCount; ++j)
{ {
@ -599,15 +599,15 @@ namespace Components
if (pass->args) if (pass->args)
{ {
buffer->align(Utils::Stream::ALIGN_4); buffer.align(Utils::Stream::ALIGN_4);
buffer->saveArray(pass->args, pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount); buffer.saveArray(pass->args, pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount);
Utils::Stream::ClearPointer(&destPass->args); Utils::Stream::ClearPointer(&destPass->args);
} }
} }
if (technique->name) if (technique->name)
{ {
buffer->saveString(technique->name); buffer.saveString(technique->name);
Utils::Stream::ClearPointer(&destTechnique->name); Utils::Stream::ClearPointer(&destTechnique->name);
} }

View File

@ -7,8 +7,6 @@ namespace Components
std::string ZoneBuilder::TraceZone; std::string ZoneBuilder::TraceZone;
std::vector<std::pair<Game::XAssetType, std::string>> ZoneBuilder::TraceAssets; std::vector<std::pair<Game::XAssetType, std::string>> ZoneBuilder::TraceAssets;
std::vector<std::pair<Game::XAssetType, std::string>> ZoneBuilder::CommonAssets;
ZoneBuilder::Zone::Zone(std::string name) : indexStart(0), externalSize(0), ZoneBuilder::Zone::Zone(std::string name) : indexStart(0), externalSize(0),
// Reserve 100MB by default. // Reserve 100MB by default.
@ -749,21 +747,25 @@ namespace Components
if (type >= 0 && type < Game::XAssetType::ASSET_TYPE_COUNT) if (type >= 0 && type < Game::XAssetType::ASSET_TYPE_COUNT)
{ {
for (auto& asset : ZoneBuilder::CommonAssets) int zoneIndex = Game::DB_GetZoneIndex("common_mp");
if (zoneIndex > 0)
{ {
if (asset.first == type && asset.second == name) Game::DB_EnumXAssetEntries(type, [&](Game::XAssetEntry* entry)
{ {
// Allocate an empty asset (filled with zeros) if (!header.data && entry->zoneIndex == zoneIndex && Game::DB_GetXAssetName(&entry->asset) == name)
header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]()); {
// Allocate an empty asset (filled with zeros)
header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]());
// Set the name to the original name, so it can be stored // Set the name to the original name, so it can be stored
Game::DB_SetXAssetNameHandlers[type](&header, name.data()); Game::DB_SetXAssetNameHandlers[type](&header, name.data());
AssetHandler::StoreTemporaryAsset(type, header); AssetHandler::StoreTemporaryAsset(type, header);
// Set the name to the empty name // Set the name to the empty name
Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name)); Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name));
break; }
} }, true, true);
} }
} }
@ -853,12 +855,6 @@ namespace Components
AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader /*asset*/, std::string name, bool* /*restrict*/) AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader /*asset*/, std::string name, bool* /*restrict*/)
{ {
// This is used to track which assets can be stored as empty assets
if (FastFiles::Current() == "common_mp")
{
ZoneBuilder::CommonAssets.push_back({ type, name });
}
if (!ZoneBuilder::TraceZone.empty() && ZoneBuilder::TraceZone == FastFiles::Current()) if (!ZoneBuilder::TraceZone.empty() && ZoneBuilder::TraceZone == FastFiles::Current())
{ {
ZoneBuilder::TraceAssets.push_back({ type, name }); ZoneBuilder::TraceAssets.push_back({ type, name });
@ -998,7 +994,6 @@ namespace Components
ZoneBuilder::~ZoneBuilder() ZoneBuilder::~ZoneBuilder()
{ {
assert(ZoneBuilder::MemAllocator.empty()); assert(ZoneBuilder::MemAllocator.empty());
ZoneBuilder::CommonAssets.clear();
} }
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)

View File

@ -105,8 +105,6 @@ namespace Components
static std::string TraceZone; static std::string TraceZone;
static std::vector<std::pair<Game::XAssetType, std::string>> TraceAssets; static std::vector<std::pair<Game::XAssetType, std::string>> TraceAssets;
static std::vector<std::pair<Game::XAssetType, std::string>> CommonAssets;
static void BeginAssetTrace(std::string zone); static void BeginAssetTrace(std::string zone);
static std::vector<std::pair<Game::XAssetType, std::string>> EndAssetTrace(); static std::vector<std::pair<Game::XAssetType, std::string>> EndAssetTrace();

View File

@ -363,6 +363,9 @@ namespace Game
infoParm_t* infoParams = reinterpret_cast<infoParm_t*>(0x79D260); // Count 0x1E infoParm_t* infoParams = reinterpret_cast<infoParm_t*>(0x79D260); // Count 0x1E
XZone* g_zones = reinterpret_cast<XZone*>(0x14C0F80);
unsigned short* db_hashTable = reinterpret_cast<unsigned short*>(0x12412B0);
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize) XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
{ {
int elSize = DB_GetXAssetSizeHandlers[type](); int elSize = DB_GetXAssetSizeHandlers[type]();
@ -476,6 +479,19 @@ namespace Game
return ASSET_TYPE_INVALID; return ASSET_TYPE_INVALID;
} }
int DB_GetZoneIndex(std::string name)
{
for (int i = 0; i < 32; ++i)
{
if (Game::g_zones[i].name == name)
{
return i;
}
}
return -1;
}
bool DB_IsZoneLoaded(const char* zone) bool DB_IsZoneLoaded(const char* zone)
{ {
int zoneCount = Utils::Hook::Get<int>(0x1261BCC); int zoneCount = Utils::Hook::Get<int>(0x1261BCC);
@ -495,6 +511,48 @@ namespace Game
return false; return false;
} }
void DB_EnumXAssetEntries(XAssetType type, std::function<void(XAssetEntry*)> callback, bool overrides, bool lock)
{
volatile long* lockVar = reinterpret_cast<volatile long*>(0x16B8A54);
if (lock) InterlockedIncrement(lockVar);
while (lock && *reinterpret_cast<volatile long*>(0x16B8A58)) std::this_thread::sleep_for(1ms);
unsigned int index = 0;
do
{
unsigned short hashIndex = db_hashTable[index];
if (hashIndex)
{
do
{
XAssetEntry* asset = &Components::Maps::GetAssetEntryPool()[hashIndex];
hashIndex = asset->nextHash;
if (asset->asset.type == type)
{
callback(asset);
if (overrides)
{
unsigned short overrideIndex = asset->nextOverride;
if (asset->nextOverride)
{
do
{
asset = &Components::Maps::GetAssetEntryPool()[overrideIndex];
callback(asset);
overrideIndex = asset->nextOverride;
} while (overrideIndex);
}
}
}
} while (hashIndex);
}
++index;
} while (index < 74000);
if(lock) InterlockedDecrement(lockVar);
}
__declspec(naked) XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType /*type*/) __declspec(naked) XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType /*type*/)
{ {
__asm __asm

View File

@ -758,6 +758,9 @@ namespace Game
extern infoParm_t* infoParams; extern infoParm_t* infoParams;
extern XZone* g_zones;
extern unsigned short* db_hashTable;
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize); XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_t* item); void Menu_FreeItemMemory(Game::itemDef_t* item);
const char* TableLookup(StringTable* stringtable, int row, int column); const char* TableLookup(StringTable* stringtable, int row, int column);
@ -767,7 +770,9 @@ namespace Game
const char *DB_GetXAssetName(XAsset *asset); const char *DB_GetXAssetName(XAsset *asset);
XAssetType DB_GetXAssetNameType(const char* name); XAssetType DB_GetXAssetNameType(const char* name);
int DB_GetZoneIndex(std::string name);
bool DB_IsZoneLoaded(const char* zone); bool DB_IsZoneLoaded(const char* zone);
void DB_EnumXAssetEntries(XAssetType type, std::function<void(XAssetEntry*)> callback, bool overrides, bool lock);
XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType type); XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType type);
XAssetEntry* DB_FindXAssetEntry(XAssetType type, const char* name); XAssetEntry* DB_FindXAssetEntry(XAssetType type, const char* name);

View File

@ -3674,7 +3674,7 @@ namespace Game
{ {
XAsset asset; XAsset asset;
char zoneIndex; char zoneIndex;
bool inuse; volatile char inuse;
unsigned __int16 nextHash; unsigned __int16 nextHash;
unsigned __int16 nextOverride; unsigned __int16 nextOverride;
unsigned __int16 usageFrame; unsigned __int16 usageFrame;
@ -3755,6 +3755,26 @@ namespace Game
XAssetList assetList; XAssetList assetList;
}; };
struct XZoneMemory
{
XBlock blocks[MAX_XFILE_COUNT];
char *lockedVertexData;
char *lockedIndexData;
void *vertexBuffer;
void *indexBuffer;
};
struct XZone
{
int unk;
char name[64];
int flags;
int allocType;
XZoneMemory mem;
int fileSize;
char modZone;
};
struct XNKID struct XNKID
{ {
char ab[8]; char ab[8];