Fixed bugs in RSC Meta/XML conversion

This commit is contained in:
dexy 2019-01-28 23:51:52 +11:00
parent 43f6acda7a
commit 75748ad3d0
5 changed files with 130 additions and 53 deletions

View File

@ -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<YmapFile>(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<YtypFile>(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<YmtFile>(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<YmapFile>(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<YtypFile>(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<YmtFile>(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<Meta>();
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());
//}
}
}

View File

@ -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();

View File

@ -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<MetaStructureInfo>();
foreach (var si in StructureInfos.Values)
if (StructureInfos.Count > 0)
{
m.StructureInfos.Add(si);
m.StructureInfos = new ResourceSimpleArray<MetaStructureInfo>();
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<MetaEnumInfo>();
foreach (var ei in EnumInfos.Values)
if (EnumInfos.Count > 0)
{
m.EnumInfos.Add(ei);
m.EnumInfos = new ResourceSimpleArray<MetaEnumInfo>();
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<MetaDataBlock>();
foreach (var bb in Blocks)

View File

@ -234,10 +234,10 @@ namespace CodeWalker.GameFiles
OneLineTag(sb, cind, ename, charStr);
break;
case MetaStructureEntryDataType.DataBlockPointer:
OpenTag(sb, cind, ename);
var dataPtr = MetaTypes.ConvertData<DataBlockPointer>(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)
{

View File

@ -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<byte>();
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;