[ZoneBuilder] Optimize nested asset writing
This commit is contained in:
parent
21a55d949a
commit
39f9c73a38
@ -400,7 +400,7 @@ namespace Components
|
||||
AssetHandler::RegisterInterface(new Assets::ILoadedSound());
|
||||
AssetHandler::RegisterInterface(new Assets::IPhysCollmap());
|
||||
AssetHandler::RegisterInterface(new Assets::IStringTable());
|
||||
//AssetHandler::RegisterInterface(new Assets::IXModelSurfs());
|
||||
AssetHandler::RegisterInterface(new Assets::IXModelSurfs());
|
||||
AssetHandler::RegisterInterface(new Assets::ILocalizeEntry());
|
||||
AssetHandler::RegisterInterface(new Assets::Isnd_alias_list_t());
|
||||
AssetHandler::RegisterInterface(new Assets::IMaterialPixelShader());
|
||||
|
@ -49,7 +49,7 @@ namespace Assets
|
||||
{
|
||||
if (visuals->xmodel)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -69,7 +69,7 @@ namespace Assets
|
||||
{
|
||||
if (visuals->effectDef)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_FX, visuals->effectDef);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, visuals->effectDef);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -79,7 +79,7 @@ namespace Assets
|
||||
{
|
||||
if (visuals->material)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -104,12 +104,12 @@ namespace Assets
|
||||
{
|
||||
if (elemDef->visuals.markArray[j].data[0])
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[0]);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[0]);
|
||||
}
|
||||
|
||||
if (elemDef->visuals.markArray[j].data[1])
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[1]);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,17 +132,17 @@ namespace Assets
|
||||
|
||||
if (elemDef->effectOnImpact)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnImpact);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnImpact);
|
||||
}
|
||||
|
||||
if (elemDef->effectOnDeath)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnDeath);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnDeath);
|
||||
}
|
||||
|
||||
if (elemDef->effectEmitted)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectEmitted);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectEmitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,9 +164,20 @@ namespace Assets
|
||||
{
|
||||
for (unsigned int i = 0; i < asset->glassSys.defCount; ++i)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->glassSys.defs[i].physPreset);
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].material);
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].materialShattered);
|
||||
if (asset->glassSys.defs[i].physPreset)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->glassSys.defs[i].physPreset);
|
||||
}
|
||||
|
||||
if (asset->glassSys.defs[i].material)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].material);
|
||||
}
|
||||
|
||||
if (asset->glassSys.defs[i].materialShattered)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].materialShattered);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace Assets
|
||||
{
|
||||
for (unsigned int i = 0; i < asset->worldDraw.reflectionProbeCount; ++i)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.reflectionImages[i]);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.reflectionImages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,34 +28,34 @@ namespace Assets
|
||||
{
|
||||
if (asset->worldDraw.lightmaps[i].primary)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.lightmaps[i].primary);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.lightmaps[i].primary);
|
||||
}
|
||||
|
||||
if (asset->worldDraw.lightmaps[i].secondary)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.lightmaps[i].secondary);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.lightmaps[i].secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->worldDraw.skyImage)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.skyImage);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.skyImage);
|
||||
}
|
||||
|
||||
if (asset->worldDraw.outdoorImage)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.outdoorImage);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->worldDraw.outdoorImage);
|
||||
}
|
||||
|
||||
if (asset->sun.spriteMaterial)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->sun.spriteMaterial);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->sun.spriteMaterial);
|
||||
}
|
||||
|
||||
if (asset->sun.flareMaterial)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->sun.flareMaterial);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->sun.flareMaterial);
|
||||
}
|
||||
|
||||
if (asset->skies)
|
||||
@ -64,7 +64,7 @@ namespace Assets
|
||||
{
|
||||
if (asset->skies[i].skyImage)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->skies[i].skyImage);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->skies[i].skyImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,14 +75,14 @@ namespace Assets
|
||||
{
|
||||
if (asset->materialMemory[i].material)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materialMemory[i].material);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materialMemory[i].material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->unknownImage)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->unknownImage);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->unknownImage);
|
||||
}
|
||||
|
||||
if (asset->dpvs.surfaces)
|
||||
@ -91,7 +91,7 @@ namespace Assets
|
||||
{
|
||||
if (asset->dpvs.surfaces[i].material)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->dpvs.surfaces[i].material);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->dpvs.surfaces[i].material);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ namespace Assets
|
||||
{
|
||||
if (asset->dpvs.smodelDrawInsts[i].model)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->dpvs.smodelDrawInsts[i].model);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->dpvs.smodelDrawInsts[i].model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ namespace Assets
|
||||
|
||||
if (asset->techniqueSet)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_TECHSET, asset->techniqueSet);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_TECHSET, asset->techniqueSet);
|
||||
}
|
||||
|
||||
if (asset->textureTable)
|
||||
@ -181,12 +181,12 @@ namespace Assets
|
||||
{
|
||||
if (asset->textureTable[i].info.water->image)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->textureTable[i].info.water->image);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->textureTable[i].info.water->image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->textureTable[i].info.image);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_IMAGE, asset->textureTable[i].info.image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,17 +18,17 @@ namespace Assets
|
||||
|
||||
if (pass->vertexDecl)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_VERTEXDECL, pass->vertexDecl);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_VERTEXDECL, pass->vertexDecl);
|
||||
}
|
||||
|
||||
if (pass->vertexShader)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, pass->vertexShader);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, pass->vertexShader);
|
||||
}
|
||||
|
||||
if (pass->pixelShader)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_PIXELSHADER, pass->pixelShader);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PIXELSHADER, pass->pixelShader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ namespace Assets
|
||||
surf->surfaces = builder->getAllocator()->allocateArray<Game::XSurface>(model->numSurfaces);
|
||||
surf->numSurfaces = model->numSurfaces;
|
||||
|
||||
// Store surfs for later writing
|
||||
Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, { surf });
|
||||
|
||||
// Reset surfaces in remaining lods
|
||||
for (unsigned int i = 1; i < 4; ++i)
|
||||
{
|
||||
@ -195,7 +198,7 @@ namespace Assets
|
||||
{
|
||||
if (asset->materials[i])
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,21 +207,18 @@ namespace Assets
|
||||
{
|
||||
if (asset->lods[i].surfaces)
|
||||
{
|
||||
// We're not supposed to include xmodelsurfs as standalone asset
|
||||
//builder->markAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name);
|
||||
|
||||
IXModelSurfs().mark({ asset->lods[i].surfaces }, builder);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->physPreset)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset);
|
||||
}
|
||||
|
||||
if (asset->physCollmap)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,16 +319,7 @@ namespace Assets
|
||||
{
|
||||
if (asset->lods[i].surfaces)
|
||||
{
|
||||
// Requiring this asset is not possible, it has to be loaded as part of the model
|
||||
//dest->lods[i].surfaces = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces).surfaces;
|
||||
|
||||
buffer->pushBlock(Game::XFILE_BLOCK_TEMP);
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
|
||||
IXModelSurfs().save({ asset->lods[i].surfaces }, builder);
|
||||
Utils::Stream::ClearPointer(&dest->lods[i].surfaces);
|
||||
|
||||
buffer->popBlock();
|
||||
dest->lods[i].surfaces = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces).surfaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,7 +521,10 @@ namespace Assets
|
||||
for (int i = 0; i < asset->numStaticModels; ++i)
|
||||
{
|
||||
Game::XModel* m = asset->staticModelList[i].xmodel;
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_XMODEL, m);
|
||||
if (m)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, m);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
@ -532,21 +535,21 @@ namespace Assets
|
||||
{
|
||||
if (def[i].xModel)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def[i].xModel);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def[i].xModel);
|
||||
}
|
||||
|
||||
if (def[i].destroyFx)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_FX, def[i].destroyFx);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, def[i].destroyFx);
|
||||
}
|
||||
|
||||
if (def[i].physPreset)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, def[i].physPreset);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, def[i].physPreset);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset);
|
||||
}
|
||||
|
||||
void IclipMap_t::load(Game::XAssetHeader* /*header*/, std::string name, Components::ZoneBuilder::Zone* /*builder*/)
|
||||
|
@ -12,12 +12,12 @@ namespace Assets
|
||||
|
||||
if (alias->soundFile && alias->soundFile->type == Game::snd_alias_type_t::SAT_LOADED)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, alias->soundFile->data.loaded);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, alias->soundFile->data.loaded);
|
||||
}
|
||||
|
||||
if (alias->volumeFalloffCurve)
|
||||
{
|
||||
builder->markAsset(Game::XAssetType::ASSET_TYPE_SNDCURVE, alias->volumeFalloffCurve);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_SNDCURVE, alias->volumeFalloffCurve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->loadAsset(this->dataMap.getElementAt(i, 0), this->dataMap.getElementAt(i, 1)))
|
||||
if (!this->loadAsset(this->dataMap.getElementAt(i, 0), this->dataMap.getElementAt(i, 1), false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -131,16 +131,22 @@ namespace Components
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneBuilder::Zone::loadAsset(Game::XAssetType type, std::string name)
|
||||
bool ZoneBuilder::Zone::loadAsset(Game::XAssetType type, void* data, bool isSubAsset)
|
||||
{
|
||||
return this->loadAsset(Game::DB_GetXAssetTypeName(type), name);
|
||||
Game::XAsset asset{ type, { data } };
|
||||
return this->loadAsset(type, Game::DB_GetXAssetName(&asset), isSubAsset);
|
||||
}
|
||||
|
||||
bool ZoneBuilder::Zone::loadAsset(std::string typeName, std::string name)
|
||||
bool ZoneBuilder::Zone::loadAsset(Game::XAssetType type, std::string name, bool isSubAsset)
|
||||
{
|
||||
return this->loadAsset(Game::DB_GetXAssetTypeName(type), name, isSubAsset);
|
||||
}
|
||||
|
||||
bool ZoneBuilder::Zone::loadAsset(std::string typeName, std::string name, bool isSubAsset)
|
||||
{
|
||||
Game::XAssetType type = Game::DB_GetXAssetNameType(typeName.data());
|
||||
|
||||
if (this->findAsset(type, name) != -1) return true;
|
||||
if (this->findAsset(type, name) != -1 || this->findSubAsset(type, name).data) return true;
|
||||
|
||||
if (type == Game::XAssetType::ASSET_TYPE_INVALID || type >= Game::XAssetType::ASSET_TYPE_COUNT)
|
||||
{
|
||||
@ -149,7 +155,6 @@ namespace Components
|
||||
}
|
||||
|
||||
Game::XAssetHeader assetHeader = AssetHandler::FindAssetForZone(type, name, this);
|
||||
|
||||
if (!assetHeader.data)
|
||||
{
|
||||
Logger::Error("Error: Missing asset '%s' of type '%s'\n", name.data(), Game::DB_GetXAssetTypeName(type));
|
||||
@ -160,7 +165,14 @@ namespace Components
|
||||
asset.type = type;
|
||||
asset.header = assetHeader;
|
||||
|
||||
this->loadedAssets.push_back(asset);
|
||||
if (isSubAsset)
|
||||
{
|
||||
this->loadedSubAssets.push_back(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->loadedAssets.push_back(asset);
|
||||
}
|
||||
|
||||
// Handle script strings
|
||||
AssetHandler::ZoneMark(asset, this);
|
||||
@ -176,7 +188,7 @@ namespace Components
|
||||
|
||||
if (asset->type != type) continue;
|
||||
|
||||
const char* assetName = DB_GetXAssetName(asset);
|
||||
const char* assetName = Game::DB_GetXAssetName(asset);
|
||||
|
||||
if (name == assetName)
|
||||
{
|
||||
@ -187,6 +199,25 @@ namespace Components
|
||||
return -1;
|
||||
}
|
||||
|
||||
Game::XAssetHeader ZoneBuilder::Zone::findSubAsset(Game::XAssetType type, std::string name)
|
||||
{
|
||||
for (unsigned int i = 0; i < this->loadedSubAssets.size(); ++i)
|
||||
{
|
||||
Game::XAsset* asset = &this->loadedSubAssets[i];
|
||||
|
||||
if (asset->type != type) continue;
|
||||
|
||||
const char* assetName = Game::DB_GetXAssetName(asset);
|
||||
|
||||
if (name == assetName)
|
||||
{
|
||||
return asset->header;
|
||||
}
|
||||
}
|
||||
|
||||
return { 0 };
|
||||
}
|
||||
|
||||
Game::XAsset* ZoneBuilder::Zone::getAsset(int index)
|
||||
{
|
||||
if (static_cast<uint32_t>(index) < this->loadedAssets.size())
|
||||
@ -204,67 +235,52 @@ namespace Components
|
||||
offset.offset = (this->indexStart + (index * sizeof(Game::XAsset)) + 4);
|
||||
return offset.getPackedOffset();
|
||||
}
|
||||
/*
|
||||
void ZoneBuilder::Zone::pushAliasBase()
|
||||
{
|
||||
this->aliasBaseStack.push_back(this->buffer.getBlockSize(Game::XFILE_BLOCK_VIRTUAL));
|
||||
}
|
||||
|
||||
void ZoneBuilder::Zone::popAliasBase()
|
||||
bool ZoneBuilder::Zone::hasAlias(Game::XAsset asset)
|
||||
{
|
||||
if (!this->aliasBaseStack.empty())
|
||||
{
|
||||
this->aliasBaseStack.pop_back();
|
||||
}
|
||||
return this->getAlias(asset) != 0;
|
||||
}
|
||||
|
||||
unsigned int ZoneBuilder::Zone::getAliasBase()
|
||||
{
|
||||
return this->aliasBaseStack.back();
|
||||
}
|
||||
*/
|
||||
|
||||
Game::XAssetHeader ZoneBuilder::Zone::saveSubAsset(Game::XAssetType type, void* ptr)
|
||||
{
|
||||
Game::XAssetHeader header;
|
||||
header.data = ptr;
|
||||
Game::XAssetHeader header { ptr };
|
||||
Game::XAsset asset { type, header };
|
||||
std::string name = Game::DB_GetXAssetName(&asset);
|
||||
|
||||
int assetIndex = this->findAsset(type, Game::DB_GetXAssetNameHandlers[type](&header));
|
||||
int assetIndex = this->findAsset(type, name);
|
||||
if (assetIndex == -1) // nested asset
|
||||
{
|
||||
const auto& cmp = header.data;
|
||||
|
||||
// already written. find alias and store in ptr
|
||||
if(std::find_if(this->savedAssets.begin(), this->savedAssets.end(), [&cmp] (const Game::XAssetHeader& s) { return cmp == s.data; } ) != this->savedAssets.end())
|
||||
if(this->hasAlias(asset))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
//Components::Logger::Print("Using alias for (%s): %s\n", Game::DB_GetXAssetTypeName(asset->type), Game::DB_GetXAssetName(asset));
|
||||
#endif
|
||||
Utils::Stream::Offset off;
|
||||
off.block = Game::XFILE_BLOCK_VIRTUAL;
|
||||
off.offset = this->getAlias(ptr);
|
||||
header.data = reinterpret_cast<void*>(off.getPackedOffset());
|
||||
header.data = reinterpret_cast<void*>(this->getAlias(asset));
|
||||
}
|
||||
else
|
||||
{
|
||||
asset.header = this->findSubAsset(type, name);
|
||||
if (!asset.header.data)
|
||||
{
|
||||
Logger::Error("Missing required asset '%s' (%s). Export failed!", name, Game::DB_GetXAssetTypeName(type));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
Components::Logger::Print("Saving Require (%s): %s\n", Game::DB_GetXAssetTypeName(type), Game::DB_GetXAssetNameHandlers[type](&header));
|
||||
Components::Logger::Print("Saving require (%s): %s\n", Game::DB_GetXAssetTypeName(type), Game::DB_GetXAssetNameHandlers[type](&header));
|
||||
#endif
|
||||
Game::XAsset assetToSave;
|
||||
assetToSave.header = header;
|
||||
assetToSave.type = type;
|
||||
|
||||
this->buffer.pushBlock(Game::XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
// we alias the next 4 (aligned) bytes of the stream b/c DB_InsertPointer gives us a nice pointer to use as the alias
|
||||
// otherwise it would be a fuckfest trying to figure out where the alias is in the stream
|
||||
this->buffer.align(Utils::Stream::ALIGN_4);
|
||||
this->storeAlias(ptr, this->buffer.getBlockSize(Game::XFILE_BLOCK_VIRTUAL));
|
||||
|
||||
this->storeAlias(asset);
|
||||
this->buffer.increaseBlockSize(Game::XFILE_BLOCK_VIRTUAL, 4);
|
||||
|
||||
this->buffer.pushBlock(Game::XFILE_BLOCK_TEMP);
|
||||
AssetHandler::ZoneSave(assetToSave, this);
|
||||
this->buffer.popBlock();
|
||||
this->savedAssets.push_back(header);
|
||||
|
||||
this->buffer.pushBlock(Game::XFILE_BLOCK_TEMP);
|
||||
AssetHandler::ZoneSave(asset, this);
|
||||
this->buffer.popBlock();
|
||||
|
||||
header.data = reinterpret_cast<void*>(-2); // DB_InsertPointer marker
|
||||
}
|
||||
}
|
||||
@ -279,13 +295,8 @@ namespace Components
|
||||
|
||||
void ZoneBuilder::Zone::markAsset(Game::XAssetType type, void* ptr)
|
||||
{
|
||||
Game::XAsset asset;
|
||||
asset.header.data = ptr;
|
||||
asset.type = type;
|
||||
|
||||
const auto& cmp = asset.header.data;
|
||||
|
||||
if(std::find_if(this->markedAssets.begin(), this->markedAssets.end(), [&cmp] (const Game::XAsset& s) { return cmp == s.header.data; } ) != this->markedAssets.end())
|
||||
Game::XAsset asset { type, { ptr } };
|
||||
if(std::find_if(this->markedAssets.begin(), this->markedAssets.end(), [&] (const Game::XAsset& s) { return (asset.header.data == s.header.data && asset.type == s.type); } ) != this->markedAssets.end())
|
||||
{
|
||||
return; // don't re-mark assets
|
||||
}
|
||||
@ -323,7 +334,7 @@ namespace Components
|
||||
Utils::IO::WriteFile(outFile, outBuffer);
|
||||
|
||||
Logger::Print("done.\n");
|
||||
Logger::Print("Zone '%s' written with %d assets and %d script strings\n", outFile.data(), this->savedAssets.size(), this->scriptStrings.size());
|
||||
Logger::Print("Zone '%s' written with %d assets and %d script strings\n", outFile.data(), (this->aliasList.size() + this->loadedAssets.size()), this->scriptStrings.size());
|
||||
}
|
||||
|
||||
void ZoneBuilder::Zone::saveData()
|
||||
@ -383,18 +394,6 @@ namespace Components
|
||||
// Assets
|
||||
for (auto asset : this->loadedAssets)
|
||||
{
|
||||
/*
|
||||
const auto& cmp = asset.header.data;
|
||||
|
||||
if(std::find_if(this->savedAssets.begin(), this->savedAssets.end(), [&cmp] (const Game::XAsset& s) { return cmp == s.header.data; } ) != this->savedAssets.end())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Components::Logger::Print("Skipping (%s): %s\n", Game::DB_GetXAssetTypeName(asset.type), Game::DB_GetXAssetNameHandlers[type](header));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
this->buffer.pushBlock(Game::XFILE_BLOCK_TEMP);
|
||||
this->buffer.align(Utils::Stream::ALIGN_4);
|
||||
|
||||
@ -405,8 +404,6 @@ namespace Components
|
||||
this->store(asset.header);
|
||||
AssetHandler::ZoneSave(asset, this);
|
||||
|
||||
savedAssets.push_back(asset.header);
|
||||
|
||||
this->buffer.popBlock();
|
||||
}
|
||||
|
||||
@ -464,18 +461,26 @@ namespace Components
|
||||
this->pointerMap[pointer] = this->buffer.getPackedOffset();
|
||||
}
|
||||
|
||||
void ZoneBuilder::Zone::storeAlias(const void* ptr, unsigned int alias)
|
||||
void ZoneBuilder::Zone::storeAlias(Game::XAsset asset)
|
||||
{
|
||||
this->aliasMap[ptr] = alias;
|
||||
if (!this->hasAlias(asset))
|
||||
{
|
||||
this->aliasList.push_back({ asset, this->buffer.getPackedOffset() });
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ZoneBuilder::Zone::getAlias(const void* ptr)
|
||||
unsigned int ZoneBuilder::Zone::getAlias(Game::XAsset asset)
|
||||
{
|
||||
if((this->aliasMap.find(ptr) != this->aliasMap.end()))
|
||||
std::string name = Game::DB_GetXAssetName(&asset);
|
||||
|
||||
for (auto& entry : this->aliasList)
|
||||
{
|
||||
return this->aliasMap[ptr];
|
||||
if (asset.type == entry.first.type && name == Game::DB_GetXAssetName(&entry.first))
|
||||
{
|
||||
return entry.second;
|
||||
}
|
||||
}
|
||||
Logger::Print("Warning: Missing Alias for pointer! Export will almost certainly fail!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,6 @@
|
||||
#define XFILE_VERSION 276
|
||||
#define XFILE_VERSION_IW4X 0x78345749 // 'IW4x'
|
||||
|
||||
#define GET_ALIAS_OFFSET(_s, _m) offsetof((_s), (_m))
|
||||
#define GET_ALIAS_OFFSET_ARRAY(_s, _m, _loop) (offsetof((_s), (_m)) + (sizeof(_s) * (_loop)))
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class ZoneBuilder : public Component
|
||||
@ -23,16 +20,19 @@ namespace Components
|
||||
|
||||
bool hasPointer(const void* pointer);
|
||||
void storePointer(const void* pointer);
|
||||
void storePointer(const void* pointer, Utils::Stream::Offset offset);
|
||||
|
||||
template<typename T>
|
||||
inline T* getPointer(const T* pointer) { return reinterpret_cast<T*>(this->safeGetPointer(pointer)); }
|
||||
|
||||
int findAsset(Game::XAssetType type, std::string name);
|
||||
Game::XAssetHeader findSubAsset(Game::XAssetType type, std::string name);
|
||||
Game::XAsset* getAsset(int index);
|
||||
uint32_t getAssetTableOffset(int index);
|
||||
|
||||
bool hasAlias(Game::XAsset asset);
|
||||
Game::XAssetHeader saveSubAsset(Game::XAssetType type, void* ptr);
|
||||
bool loadAsset(Game::XAssetType type, std::string name);
|
||||
bool loadAsset(Game::XAssetType type, std::string name, bool isSubAsset = true);
|
||||
bool loadAsset(Game::XAssetType type, void* data, bool isSubAsset = true);
|
||||
void markAsset(Game::XAssetType type, void* ptr);
|
||||
|
||||
int addScriptString(unsigned short gameIndex);
|
||||
@ -52,13 +52,13 @@ namespace Components
|
||||
void loadFastFiles();
|
||||
|
||||
bool loadAssets();
|
||||
bool loadAsset(std::string type, std::string name);
|
||||
bool loadAsset(std::string type, std::string name, bool isSubAsset = true);
|
||||
|
||||
void saveData();
|
||||
void writeZone();
|
||||
|
||||
unsigned int getAlias(const void* pointer);
|
||||
void storeAlias(const void* pointer, unsigned int alias);
|
||||
unsigned int getAlias(Game::XAsset asset);
|
||||
void storeAlias(Game::XAsset asset);
|
||||
|
||||
void addBranding();
|
||||
|
||||
@ -74,13 +74,15 @@ namespace Components
|
||||
Utils::Memory::Allocator memAllocator;
|
||||
|
||||
std::vector<Game::XAsset> loadedAssets;
|
||||
std::vector<Game::XAssetHeader> savedAssets;
|
||||
std::vector<Game::XAsset> markedAssets;
|
||||
std::vector<Game::XAsset> loadedSubAssets;
|
||||
std::vector<std::string> scriptStrings;
|
||||
std::map<unsigned short, unsigned int> scriptStringMap;
|
||||
|
||||
std::map<std::string, std::string> renameMap[Game::XAssetType::ASSET_TYPE_COUNT];
|
||||
|
||||
std::map<const void*, uint32_t> pointerMap;
|
||||
std::map<const void*, uint32_t> aliasMap;
|
||||
std::vector<std::pair<Game::XAsset, uint32_t>> aliasList;
|
||||
|
||||
Game::RawFile branding;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user