HD textures (WIP), vehicles.meta gtxd loading

This commit is contained in:
dexy
2019-01-06 05:04:33 +11:00
Unverified
parent e4c2dddf10
commit 9dde38c930
14 changed files with 515 additions and 316 deletions
+11 -11
View File
@@ -15,7 +15,7 @@ namespace CodeWalker.GameFiles
public RbfFile Rbf { get; set; }
public Dictionary<string, string> CMapParentTxds { get; set; }
public Dictionary<string, string> TxdRelationships { get; set; }
@@ -46,7 +46,7 @@ namespace CodeWalker.GameFiles
if (rbfstruct.Name == "CMapParentTxds")
{
LoadMapParentTxds(rbfstruct);
LoadTxdRelationships(rbfstruct);
}
Loaded = true;
@@ -68,7 +68,7 @@ namespace CodeWalker.GameFiles
xml = xml.Remove(0, bom.Length);
}
LoadMapParentTxds(xml);
LoadTxdRelationships(xml);
Loaded = true;
}
@@ -76,10 +76,10 @@ namespace CodeWalker.GameFiles
}
private void LoadMapParentTxds(RbfStructure rbfstruct)
private void LoadTxdRelationships(RbfStructure rbfstruct)
{
CMapParentTxds = new Dictionary<string, string>();
TxdRelationships = new Dictionary<string, string>();
//StringBuilder sblist = new StringBuilder();
foreach (var child in rbfstruct.Children)
{
@@ -118,9 +118,9 @@ namespace CodeWalker.GameFiles
}
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
{
if (!CMapParentTxds.ContainsKey(childstr))
if (!TxdRelationships.ContainsKey(childstr))
{
CMapParentTxds.Add(childstr, parentstr);
TxdRelationships.Add(childstr, parentstr);
}
else
{
@@ -140,13 +140,13 @@ namespace CodeWalker.GameFiles
private void LoadMapParentTxds(string xml)
private void LoadTxdRelationships(string xml)
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml); //maybe better load xml.ToLower() and use "cmapparenttxds/txdrelationships/item" as xpath?
XmlNodeList items = xmldoc.SelectNodes("CMapParentTxds/txdRelationships/Item | CMapParentTxds/txdRelationships/item");
CMapParentTxds = new Dictionary<string, string>();
TxdRelationships = new Dictionary<string, string>();
for (int i = 0; i < items.Count; i++)
{
string parentstr = Xml.GetChildInnerText(items[i], "parent");
@@ -154,9 +154,9 @@ namespace CodeWalker.GameFiles
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
{
if (!CMapParentTxds.ContainsKey(childstr))
if (!TxdRelationships.ContainsKey(childstr))
{
CMapParentTxds.Add(childstr, parentstr);
TxdRelationships.Add(childstr, parentstr);
}
}
}
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker.GameFiles
{
public class VehiclesFile : GameFile, PackedFile
{
public RbfFile Rbf { get; set; }
public Dictionary<string, string> TxdRelationships { get; set; }
public VehiclesFile() : base(null, GameFileType.Vehicles)
{
}
public VehiclesFile(RpfFileEntry entry) : base(entry, GameFileType.Vehicles)
{
}
public void Load(byte[] data, RpfFileEntry entry)
{
RpfFileEntry = entry;
Name = entry.Name;
FilePath = Name;
if (entry.NameLower.EndsWith(".meta"))
{
//required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta
string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
string xml = Encoding.UTF8.GetString(data);
if (xml.StartsWith(bom, StringComparison.Ordinal))
{
xml = xml.Remove(0, bom.Length);
}
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
LoadVehicles(xmldoc);
LoadTxdRelationships(xmldoc);
Loaded = true;
}
}
private void LoadVehicles(XmlDocument xmldoc)
{
XmlNodeList items = xmldoc.SelectNodes("CVehicleModelInfo__InitDataList/InitDatas/Item | CVehicleModelInfo__InitDataList/InitDatas/item");
for (int i = 0; i < items.Count; i++)
{
//TODO...
}
}
private void LoadTxdRelationships(XmlDocument xmldoc)
{
XmlNodeList items = xmldoc.SelectNodes("CVehicleModelInfo__InitDataList/txdRelationships/Item | CVehicleModelInfo__InitDataList/txdRelationships/item");
TxdRelationships = new Dictionary<string, string>();
for (int i = 0; i < items.Count; i++)
{
string parentstr = Xml.GetChildInnerText(items[i], "parent");
string childstr = Xml.GetChildInnerText(items[i], "child");
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
{
if (!TxdRelationships.ContainsKey(childstr))
{
TxdRelationships.Add(childstr, parentstr);
}
}
}
}
}
}
+1
View File
@@ -70,6 +70,7 @@ namespace CodeWalker.GameFiles
Ywr = 14,
Yvr = 15,
Gtxd = 16,
Vehicles = 17,
}
+71 -65
View File
@@ -27,7 +27,8 @@ namespace CodeWalker.GameFiles
private volatile bool archetypesLoaded = false;
private Dictionary<uint, Archetype> archetypeDict = new Dictionary<uint, Archetype>();
private Dictionary<uint, RpfFileEntry> textureLookup = new Dictionary<uint, RpfFileEntry>();
private Dictionary<uint, uint> textureParents;
private Dictionary<MetaHash, MetaHash> textureParents;
private Dictionary<MetaHash, MetaHash> hdtexturelookup;
private object updateSyncRoot = new object();
private object requestSyncRoot = new object();
@@ -132,6 +133,7 @@ namespace CodeWalker.GameFiles
mainCache.Clear();
textureLookup.Clear();
GameFile queueclear;
while (requestQueue.TryPop(out queueclear))
{ } //empty the old queue out...
@@ -958,6 +960,7 @@ namespace CodeWalker.GameFiles
private void InitManifestDicts()
{
AllManifests = new List<YmfFile>();
hdtexturelookup = new Dictionary<MetaHash, MetaHash>();
foreach (RpfFile file in ActiveMapRpfFiles.Values) //RpfMan.BaseRpfs)
{
if (file.AllEntries == null) continue;
@@ -985,6 +988,19 @@ namespace CodeWalker.GameFiles
{ }
else
{ }
if (ymffile.HDTxdAssetBindings != null)
{
for (int i = 0; i < ymffile.HDTxdAssetBindings.Length; i++)
{
var b = ymffile.HDTxdAssetBindings[i];
var targetasset = JenkHash.GenHash(b.targetAsset.ToString().ToLowerInvariant());
var hdtxd = JenkHash.GenHash(b.HDTxd.ToString().ToLowerInvariant());
hdtexturelookup[targetasset] = hdtxd;
}
}
}
}
@@ -996,70 +1012,49 @@ namespace CodeWalker.GameFiles
private void InitGtxds()
{
Dictionary<uint, uint> parentTxds = new Dictionary<uint, uint>();
var parentTxds = new Dictionary<MetaHash, MetaHash>();
IEnumerable<RpfFile> rpfs = PreloadedMode ? AllRpfs : (IEnumerable<RpfFile>)ActiveMapRpfFiles.Values;
foreach (RpfFile file in rpfs)
var addTxdRelationships = new Action<Dictionary<string, string>>((from) =>
{
if (file.AllEntries == null) continue;
foreach (RpfEntry entry in file.AllEntries)
foreach (var kvp in from)
{
try
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
if (!parentTxds.ContainsKey(chash))
{
if ((entry.NameLower == "gtxd.ymt") || (entry.NameLower == "gtxd.meta"))
{
GtxdFile ymt = RpfMan.GetFile<GtxdFile>(entry);
if (ymt.CMapParentTxds != null)
{
foreach (var kvp in ymt.CMapParentTxds)
{
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
if (!parentTxds.ContainsKey(chash))
{
parentTxds.Add(chash, phash);
}
else
{
}
}
}
}
parentTxds.Add(chash, phash);
}
catch (Exception ex)
else
{
string errstr = entry.Path + "\n" + ex.ToString();
ErrorLog(errstr);
}
}
}
});
if (EnableDlc)
var addRpfTxdRelationships = new Action<IEnumerable<RpfFile>>((from) =>
{
foreach (var dlcfile in DlcActiveRpfs)
foreach (RpfFile file in from)
{
foreach (RpfEntry entry in dlcfile.AllEntries)
if (file.AllEntries == null) continue;
foreach (RpfEntry entry in file.AllEntries)
{
try
{
if (entry.NameLower == "gtxd.meta")
if ((entry.NameLower == "gtxd.ymt") || (entry.NameLower == "gtxd.meta"))
{
GtxdFile ymt = RpfMan.GetFile<GtxdFile>(entry);
if (ymt.CMapParentTxds != null)
if (ymt.TxdRelationships != null)
{
foreach (var kvp in ymt.CMapParentTxds)
{
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
if (!parentTxds.ContainsKey(chash))
{
parentTxds.Add(chash, phash);
}
else
{
}
}
addTxdRelationships(ymt.TxdRelationships);
}
}
else if (entry.NameLower == "vehicles.meta")
{
VehiclesFile vf = RpfMan.GetFile<VehiclesFile>(entry);
if (vf.TxdRelationships != null)
{
addTxdRelationships(vf.TxdRelationships);
}
}
}
@@ -1070,6 +1065,16 @@ namespace CodeWalker.GameFiles
}
}
}
});
addRpfTxdRelationships(rpfs);
if (EnableDlc)
{
addRpfTxdRelationships(DlcActiveRpfs);
}
@@ -1078,7 +1083,7 @@ namespace CodeWalker.GameFiles
//ensure global texture dicts:
//ensure resident global texture dicts:
YtdFile ytd1 = new YtdFile(GetYtdEntry(JenkHash.GenHash("mapdetail")));
LoadFile(ytd1);
AddTextureLookups(ytd1);
@@ -1087,17 +1092,6 @@ namespace CodeWalker.GameFiles
LoadFile(ytd2);
AddTextureLookups(ytd2);
YtdFile ytd3 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_worn")));
LoadFile(ytd3);
AddTextureLookups(ytd3);
YtdFile ytd4 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_army")));
LoadFile(ytd4);
AddTextureLookups(ytd4);
YtdFile ytd5 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_truck")));
LoadFile(ytd5);
AddTextureLookups(ytd5);
}
@@ -1435,7 +1429,7 @@ namespace CodeWalker.GameFiles
{
lock (updateSyncRoot)
{
lock (textureSyncRoot)
//lock (textureSyncRoot)
{
SelectedDlc = dlc;
EnableDlc = enable;
@@ -1459,7 +1453,7 @@ namespace CodeWalker.GameFiles
{
lock (updateSyncRoot)
{
lock (textureSyncRoot)
//lock (textureSyncRoot)
{
EnableMods = enable;
RpfMan.EnableMods = enable;
@@ -1901,7 +1895,7 @@ namespace CodeWalker.GameFiles
break;
case GameFileType.Ytd:
req.Loaded = LoadFile(req as YtdFile);
if (req.Loaded) AddTextureLookups(req as YtdFile);
//if (req.Loaded) AddTextureLookups(req as YtdFile);
break;
case GameFileType.Ymap:
YmapFile y = req as YmapFile;
@@ -1983,7 +1977,7 @@ namespace CodeWalker.GameFiles
}
public YtdFile TryGetParentYtd(uint hash)
{
uint phash;
MetaHash phash;
if(textureParents.TryGetValue(hash, out phash))
{
return GetYtd(phash);
@@ -1992,19 +1986,31 @@ namespace CodeWalker.GameFiles
}
public uint TryGetParentYtdHash(uint hash)
{
uint phash = 0;
MetaHash phash = 0;
textureParents.TryGetValue(hash, out phash);
return phash;
}
public uint TryGetHDTextureHash(uint txdhash)
{
MetaHash hdhash = 0;
if (hdtexturelookup?.TryGetValue(txdhash, out hdhash) ?? false)
{
return hdhash;
}
return txdhash;
}
public Texture TryFindTextureInParent(uint texhash, uint txdhash)
{
Texture tex = null;
var ytd = TryGetParentYtd(txdhash);
while ((ytd != null) && (ytd.Loaded) && (ytd.TextureDict != null) && (tex == null))
while ((ytd != null) && (tex == null))
{
tex = ytd.TextureDict.Lookup(texhash);
if (ytd.Loaded && (ytd.TextureDict != null))
{
tex = ytd.TextureDict.Lookup(texhash);
}
if (tex == null)
{
ytd = TryGetParentYtd(ytd.Key.Hash);
+17 -16
View File
@@ -29,6 +29,7 @@ namespace CodeWalker.GameFiles
public ResourcePointerList64<Texture> Textures { get; set; }
public Dictionary<uint, Texture> Dict { get; set; }
public long MemoryUsage
{
get
@@ -81,7 +82,7 @@ namespace CodeWalker.GameFiles
dict[hash] = tex;
}
}
Dict = new Dictionary<uint, Texture>(dict);
Dict = dict;// new Dictionary<uint, Texture>(dict);
}
/// <summary>
@@ -108,21 +109,6 @@ namespace CodeWalker.GameFiles
};
}
public Dictionary<uint, Texture> GetDictionary()
{
Dictionary<uint, Texture> td = new Dictionary<uint, Texture>();
if ((Textures != null) && (Textures.data_items != null))
{
var texs = Textures.data_items;
var hashes = TextureNameHashes;
for (int i = 0; (i < texs.Length) && (i < hashes.Length); i++)
{
td.Add(hashes[i], texs[i]);
}
}
return td;
}
public Texture Lookup(uint hash)
{
Texture tex = null;
@@ -132,6 +118,21 @@ namespace CodeWalker.GameFiles
}
return tex;
}
//public Dictionary<uint, Texture> GetDictionary()
//{
// Dictionary<uint, Texture> td = new Dictionary<uint, Texture>();
// if ((Textures != null) && (Textures.data_items != null))
// {
// var texs = Textures.data_items;
// var hashes = TextureNameHashes;
// for (int i = 0; (i < texs.Length) && (i < hashes.Length); i++)
// {
// td.Add(hashes[i], texs[i]);
// }
// }
// return td;
//}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class TextureBase : ResourceSystemBlock