diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs index 3877ffd..2cf9019 100644 --- a/CodeWalker.Core/GameFiles/GameFileCache.cs +++ b/CodeWalker.Core/GameFiles/GameFileCache.cs @@ -2690,41 +2690,67 @@ namespace CodeWalker.GameFiles { foreach (RpfEntry entry in file.AllEntries) { - try + //try { var n = entry.NameLower; - if (n.EndsWith(".ymap")) + //if (n.EndsWith(".ymap")) + //{ + // UpdateStatus(string.Format(entry.Path)); + // YmapFile ymapfile = RpfMan.GetFile(entry); + // if ((ymapfile != null) && (ymapfile.Meta != null)) + // { + // MetaTypes.EnsureMetaTypes(ymapfile.Meta); + // } + //} + //else if (n.EndsWith(".ytyp")) + //{ + // UpdateStatus(string.Format(entry.Path)); + // YtypFile ytypfile = RpfMan.GetFile(entry); + // if ((ytypfile != null) && (ytypfile.Meta != null)) + // { + // MetaTypes.EnsureMetaTypes(ytypfile.Meta); + // } + //} + //else if (n.EndsWith(".ymt")) + //{ + // UpdateStatus(string.Format(entry.Path)); + // YmtFile ymtfile = RpfMan.GetFile(entry); + // if ((ymtfile != null) && (ymtfile.Meta != null)) + // { + // MetaTypes.EnsureMetaTypes(ymtfile.Meta); + // } + //} + + + if (n.EndsWith(".ymap") || n.EndsWith(".ytyp") || n.EndsWith(".ymt")) { + var rfe = entry as RpfResourceFileEntry; + if (rfe == null) continue; + UpdateStatus(string.Format(entry.Path)); - YmapFile ymapfile = RpfMan.GetFile(entry); - if ((ymapfile != null) && (ymapfile.Meta != null)) - { - MetaTypes.EnsureMetaTypes(ymapfile.Meta); - } - } - else if (n.EndsWith(".ytyp")) - { - UpdateStatus(string.Format(entry.Path)); - YtypFile ytypfile = RpfMan.GetFile(entry); - if ((ytypfile != null) && (ytypfile.Meta != null)) - { - MetaTypes.EnsureMetaTypes(ytypfile.Meta); - } - } - else if (n.EndsWith(".ymt")) - { - UpdateStatus(string.Format(entry.Path)); - YmtFile ymtfile = RpfMan.GetFile(entry); - if ((ymtfile != null) && (ymtfile.Meta != null)) - { - MetaTypes.EnsureMetaTypes(ymtfile.Meta); - } + + var data = rfe.File.ExtractFile(rfe); + ResourceDataReader rd = new ResourceDataReader(rfe, data); + var meta = rd.ReadBlock(); + var xml = MetaXml.GetXml(meta); + var xdoc = new XmlDocument(); + xdoc.LoadXml(xml); + var meta2 = XmlMeta.GetMeta(xdoc); + var xml2 = MetaXml.GetXml(meta2); + + if (xml.Length != xml2.Length) + { } + if ((xml != xml2)&&(!n.EndsWith("srl.ymt") && !n.StartsWith("des_"))) + { } + } + + } - catch (Exception ex) - { - UpdateStatus("Error! " + ex.ToString()); - } + //catch (Exception ex) + //{ + // UpdateStatus("Error! " + ex.ToString()); + //} } } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs index b636eef..df90f1b 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs @@ -929,6 +929,13 @@ namespace CodeWalker.GameFiles public uint PointerDataIndex { get { return (Ptr0 & 0xFFF) - 1; } } public uint PointerDataOffset { get { return ((Ptr0 >> 12) & 0xFFFFF); } } + + public DataBlockPointer(int blockId, int offset) + { + Ptr0 = ((uint)blockId & 0xFFF) | (((uint)offset & 0xFFFFF) << 12); + Ptr1 = 0; + } + public override string ToString() { return "DataBlockPointer: " + Ptr0.ToString() + ", " + Ptr1.ToString(); diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaBuilder.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaBuilder.cs index 155c64c..5833e57 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaBuilder.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaBuilder.cs @@ -27,6 +27,10 @@ namespace CodeWalker.GameFiles } } } + return AddBlock(type); + } + public MetaBuilderBlock AddBlock(MetaName type) + { MetaBuilderBlock b = new MetaBuilderBlock(); b.StructureNameHash = type; b.Index = Blocks.Count; @@ -91,12 +95,7 @@ namespace CodeWalker.GameFiles MetaBuilderBlock block = EnsureBlock(MetaName.STRING); byte[] data = Encoding.ASCII.GetBytes(str); int datalen = data.Length; - int newlen = datalen; - int lenrem = newlen % 16; - if (lenrem != 0) //need to pad the data length up to multiple of 16. - { - newlen += (16 - lenrem); - } + int newlen = datalen + 1; //include null terminator byte[] newdata = new byte[newlen]; Buffer.BlockCopy(data, 0, newdata, 0, datalen); int offs = block.TotalSize; @@ -104,7 +103,7 @@ namespace CodeWalker.GameFiles MetaBuilderPointer r = new MetaBuilderPointer(); r.BlockID = block.Index + 1; r.Offset = offs;// (idx * data.Length); - r.Length = datalen; //actual length of string. + r.Length = datalen; //actual length of string. (not incl null terminator) return r; } @@ -193,6 +192,14 @@ namespace CodeWalker.GameFiles var ptr = AddString(str); return new CharPointer(ptr); } + public DataBlockPointer AddDataBlockPtr(byte[] data, MetaName type) + { + var block = AddBlock(type); + int offs = block.TotalSize;//should always be 0... + int idx = block.AddItem(data); + var ptr = new DataBlockPointer(block.Index + 1, offs); + return ptr; + } public Array_StructurePointer AddPointerArray(MetaPOINTER[] arr) @@ -351,19 +358,35 @@ namespace CodeWalker.GameFiles m.RootBlockIndex = 1; //assume first block is root. todo: make adjustable? - m.StructureInfos = new ResourceSimpleArray(); - foreach (var si in StructureInfos.Values) + if (StructureInfos.Count > 0) { - m.StructureInfos.Add(si); + m.StructureInfos = new ResourceSimpleArray(); + foreach (var si in StructureInfos.Values) + { + m.StructureInfos.Add(si); + } + m.StructureInfosCount = (short)m.StructureInfos.Count; + } + else + { + m.StructureInfos = null; + m.StructureInfosCount = 0; } - m.StructureInfosCount = (short)m.StructureInfos.Count; - m.EnumInfos = new ResourceSimpleArray(); - foreach (var ei in EnumInfos.Values) + if (EnumInfos.Count > 0) { - m.EnumInfos.Add(ei); + m.EnumInfos = new ResourceSimpleArray(); + foreach (var ei in EnumInfos.Values) + { + m.EnumInfos.Add(ei); + } + m.EnumInfosCount = (short)m.EnumInfos.Count; + } + else + { + m.EnumInfos = null; + m.EnumInfosCount = 0; } - m.EnumInfosCount = (short)m.EnumInfos.Count; m.DataBlocks = new ResourceSimpleArray(); foreach (var bb in Blocks) diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs index f52b643..3f354bb 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs @@ -234,10 +234,10 @@ namespace CodeWalker.GameFiles OneLineTag(sb, cind, ename, charStr); break; case MetaStructureEntryDataType.DataBlockPointer: - OpenTag(sb, cind, ename); var dataPtr = MetaTypes.ConvertData(data, eoffset); - ErrorXml(sb, cind + 1, "DataBlockPointer not currently supported here!"); //TODO! ymap occludeModels vertices data is this type! - CloseTag(sb, cind, ename); + //need to just get all the data from that block, since this pointer is referring to the whole block! it should be of type BYTE! + var dblock = cont.Meta.GetBlock((int)dataPtr.PointerDataId); + WriteRawArray(sb, dblock.Data, cind, ename, "ByteArray", FormatHexByte, 32); break; case MetaStructureEntryDataType.Float: var floatVal = BitConverter.ToSingle(data, eoffset); @@ -577,14 +577,14 @@ namespace CodeWalker.GameFiles { Meta = meta; - if (meta.StructureInfos != null) + if (meta.StructureInfos?.Data != null) { foreach (var si in meta.StructureInfos) { structInfos[si.StructureNameHash] = si; } } - if (meta.EnumInfos != null) + if (meta.EnumInfos?.Data != null) { foreach (var ei in meta.EnumInfos) { diff --git a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs index 7ee5150..49f1130 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs @@ -86,11 +86,11 @@ namespace CodeWalker.GameFiles case MetaStructureEntryDataType.ArrayOfChars: { int offset = entry.DataOffset; - var split = Split(cnode.InnerText, 2); + var split = cnode.InnerText;// Split(cnode.InnerText, 1); for (int j = 0; j < split.Length; j++) { - byte val = Convert.ToByte(split[j], 16); + byte val = (byte)split[j];// Convert.ToByte(split[j], 16); data[offset] = val; offset += sizeof(byte); } @@ -128,7 +128,23 @@ namespace CodeWalker.GameFiles case MetaStructureEntryDataType.DataBlockPointer: { - // TODO + var ns = NumberStyles.HexNumber; + var ic = CultureInfo.InvariantCulture; + var sa = new[] { ' ', '\n' }; + var so = StringSplitOptions.RemoveEmptyEntries; + var split = cnode.InnerText.Trim().Split(sa, so); //split = Split(node.InnerText, 2); to read as unsplitted HEX + var bytes = new List(); + for (int j = 0; j < split.Length; j++) + { + byte val;// = Convert.ToByte(split[j], 10); + if (byte.TryParse(split[j].Trim(), ns, ic, out val)) + { + bytes.Add(val); + } + } + var ptr = mb.AddDataBlockPtr(bytes.ToArray(), MetaName.BYTE); + var byt = MetaTypes.ConvertToBytes(ptr); + Buffer.BlockCopy(byt, 0, data, entry.DataOffset, byt.Length); break; } @@ -735,8 +751,13 @@ namespace CodeWalker.GameFiles private static int GetEnumInt(MetaName type, string enumString, MetaStructureEntryDataType dataType) { - var infos = MetaTypes.GetEnumInfo(type); + var intval = 0; + if (int.TryParse(enumString, out intval)) + { + return intval; //it's already an int.... maybe enum not found or has no entries... or original value didn't match anything + } + var infos = MetaTypes.GetEnumInfo(type); if (infos == null) { return 0;