YVR/XML and YWR/XML conversions

This commit is contained in:
dexy 2022-02-01 02:46:36 +11:00
parent 4e8f789cf8
commit d367dbebe5
9 changed files with 443 additions and 48 deletions

View File

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker.GameFiles
{
@ -58,4 +60,51 @@ namespace CodeWalker.GameFiles
}
public class YvrXml : MetaXmlBase
{
public static string GetXml(YvrFile yvr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(XmlHeader);
if (yvr?.Records != null)
{
VehicleRecordList.WriteXmlNode(yvr.Records, sb, 0);
}
return sb.ToString();
}
}
public class XmlYvr
{
public static YvrFile GetYvr(string xml, string inputFolder = "")
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
return GetYvr(doc, inputFolder);
}
public static YvrFile GetYvr(XmlDocument doc, string inputFolder = "")
{
YvrFile r = new YvrFile();
var node = doc.DocumentElement;
if (node != null)
{
r.Records = VehicleRecordList.ReadXmlNode(node);
}
r.Name = Path.GetFileName(inputFolder);
return r;
}
}
}

View File

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker.GameFiles
{
@ -58,4 +60,52 @@ namespace CodeWalker.GameFiles
}
public class YwrXml : MetaXmlBase
{
public static string GetXml(YwrFile ywr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(XmlHeader);
if (ywr?.Waypoints != null)
{
WaypointRecordList.WriteXmlNode(ywr.Waypoints, sb, 0);
}
return sb.ToString();
}
}
public class XmlYwr
{
public static YwrFile GetYwr(string xml, string inputFolder = "")
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
return GetYwr(doc, inputFolder);
}
public static YwrFile GetYwr(XmlDocument doc, string inputFolder = "")
{
YwrFile r = new YwrFile();
var node = doc.DocumentElement;
if (node != null)
{
r.Waypoints = WaypointRecordList.ReadXmlNode(node);
}
r.Name = Path.GetFileName(inputFolder);
return r;
}
}
}

View File

@ -212,6 +212,8 @@ namespace CodeWalker.GameFiles
//TestYfts();
//TestYpts();
//TestYnvs();
//TestYvrs();
//TestYwrs();
//TestYmaps();
//TestMrfs();
//TestPlacements();
@ -3518,7 +3520,6 @@ namespace CodeWalker.GameFiles
YedFile yed = new YedFile(rfe);
RpfMan.LoadFile(yed, rfe);
var data1 = entry.File.ExtractFile(rfe);
var xml = YedXml.GetXml(yed);
var yed2 = XmlYed.GetYed(xml);
var data2 = yed2.Save();
@ -4406,6 +4407,100 @@ namespace CodeWalker.GameFiles
if (errorfiles.Count > 0)
{ }
}
public void TestYvrs()
{
var exceptions = new List<Exception>();
foreach (RpfFile file in AllRpfs)
{
foreach (RpfEntry entry in file.AllEntries)
{
#if !DEBUG
try
#endif
{
var rfe = entry as RpfFileEntry;
if (rfe == null) continue;
if (rfe.NameLower.EndsWith(".yvr"))
{
UpdateStatus(string.Format(entry.Path));
YvrFile yvr = new YvrFile(rfe);
RpfMan.LoadFile(yvr, rfe);
var xml = YvrXml.GetXml(yvr);
var yvr2 = XmlYvr.GetYvr(xml);
var data2 = yvr2.Save();
var yvr3 = new YvrFile();
RpfFile.LoadResourceFile(yvr3, data2, 1);//full roundtrip
var xml2 = YvrXml.GetXml(yvr3);
if (xml != xml2)
{ }
}
}
#if !DEBUG
catch (Exception ex)
{
UpdateStatus("Error! " + ex.ToString());
exceptions.Add(ex);
}
#endif
}
}
if (exceptions.Count > 0)
{ }
}
public void TestYwrs()
{
var exceptions = new List<Exception>();
foreach (RpfFile file in AllRpfs)
{
foreach (RpfEntry entry in file.AllEntries)
{
#if !DEBUG
try
#endif
{
var rfe = entry as RpfFileEntry;
if (rfe == null) continue;
if (rfe.NameLower.EndsWith(".ywr"))
{
UpdateStatus(string.Format(entry.Path));
YwrFile ywr = new YwrFile(rfe);
RpfMan.LoadFile(ywr, rfe);
var xml = YwrXml.GetXml(ywr);
var ywr2 = XmlYwr.GetYwr(xml);
var data2 = ywr2.Save();
var ywr3 = new YwrFile();
RpfFile.LoadResourceFile(ywr3, data2, 1);//full roundtrip
var xml2 = YwrXml.GetXml(ywr3);
if (xml != xml2)
{ }
}
}
#if !DEBUG
catch (Exception ex)
{
UpdateStatus("Error! " + ex.ToString());
exceptions.Add(ex);
}
#endif
}
}
if (exceptions.Count > 0)
{ }
}
public void TestYmaps()
{
foreach (RpfFile file in AllRpfs)

View File

@ -112,6 +112,16 @@ namespace CodeWalker.GameFiles
YedFile yed = RpfFile.GetFile<YedFile>(e, data);
return GetXml(yed, out filename);
}
else if (fnl.EndsWith(".ywr"))
{
YwrFile ywr = RpfFile.GetFile<YwrFile>(e, data);
return GetXml(ywr, out filename);
}
else if (fnl.EndsWith(".yvr"))
{
YvrFile yvr = RpfFile.GetFile<YvrFile>(e, data);
return GetXml(yvr, out filename);
}
else if (fnl.EndsWith(".awc"))
{
AwcFile awc = RpfFile.GetFile<AwcFile>(e, data);
@ -252,6 +262,18 @@ namespace CodeWalker.GameFiles
filename = fn + ".xml";
return YedXml.GetXml(yed);
}
public static string GetXml(YwrFile ywr, out string filename)
{
var fn = (ywr?.Name) ?? "";
filename = fn + ".xml";
return YwrXml.GetXml(ywr);
}
public static string GetXml(YvrFile yvr, out string filename)
{
var fn = (yvr?.Name) ?? "";
filename = fn + ".xml";
return YvrXml.GetXml(yvr);
}
public static string GetXml(AwcFile awc, out string filename, string outputfolder)
{
var fn = (awc?.Name) ?? "";
@ -2181,8 +2203,10 @@ namespace CodeWalker.GameFiles
Ypt = 14,
Yld = 15,
Yed = 16,
Awc = 17,
Heightmap = 18,
Ywr = 17,
Yvr = 18,
Awc = 19,
Heightmap = 20,
}
}

View File

@ -1,8 +1,10 @@
using System;
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker.GameFiles
{
@ -11,7 +13,7 @@ namespace CodeWalker.GameFiles
{
public override long BlockLength => 0x20;
public ResourceSimpleList64<VehicleRecordEntry> Entries;
public ResourceSimpleList64<VehicleRecordEntry> Entries { get; set; }
public VehicleRecordList()
{
@ -24,13 +26,68 @@ namespace CodeWalker.GameFiles
this.Entries = reader.ReadBlock<ResourceSimpleList64<VehicleRecordEntry>>();
}
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
base.Write(writer, parameters);
writer.WriteBlock(this.Entries);
}
public void WriteXml(StringBuilder sb, int indent)
{
if (Entries?.data_items != null)
{
foreach (var e in Entries.data_items)
{
YvrXml.OpenTag(sb, indent, "Item");
e.WriteXml(sb, indent + 1);
YvrXml.CloseTag(sb, indent, "Item");
}
}
}
public void ReadXml(XmlNode node)
{
var entries = new List<VehicleRecordEntry>();
var inodes = node.SelectNodes("Item");
if (inodes != null)
{
foreach (XmlNode inode in inodes)
{
var e = new VehicleRecordEntry();
e.ReadXml(inode);
entries.Add(e);
}
}
Entries = new ResourceSimpleList64<VehicleRecordEntry>();
Entries.data_items = entries.ToArray();
}
public static void WriteXmlNode(VehicleRecordList l, StringBuilder sb, int indent, string name = "VehicleRecordList")
{
if (l == null) return;
if ((l.Entries?.data_items == null) || (l.Entries.data_items.Length == 0))
{
YvrXml.SelfClosingTag(sb, indent, name);
}
else
{
YvrXml.OpenTag(sb, indent, name);
l.WriteXml(sb, indent + 1);
YvrXml.CloseTag(sb, indent, name);
}
}
public static VehicleRecordList ReadXmlNode(XmlNode node)
{
if (node == null) return null;
var l = new VehicleRecordList();
l.ReadXml(node);
return l;
}
public override Tuple<long, IResourceBlock>[] GetParts()
{
@ -63,9 +120,7 @@ namespace CodeWalker.GameFiles
public byte GasPedalPower;
public byte BrakePedalPower;
public byte HandbrakeUsed;
public float PositionX;
public float PositionY;
public float PositionZ;
public Vector3 Position;
public override void Read(ResourceDataReader reader, params object[] parameters)
{
@ -84,11 +139,8 @@ namespace CodeWalker.GameFiles
this.GasPedalPower = reader.ReadByte();
this.BrakePedalPower = reader.ReadByte();
this.HandbrakeUsed = reader.ReadByte();
this.PositionX = reader.ReadSingle();
this.PositionY = reader.ReadSingle();
this.PositionZ = reader.ReadSingle();
this.Position = reader.ReadVector3();
}
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
// write structure data
@ -96,20 +148,49 @@ namespace CodeWalker.GameFiles
writer.Write(this.VelocityX);
writer.Write(this.VelocityY);
writer.Write(this.VelocityZ);
writer.Write(this.RightX);
writer.Write(this.RightY);
writer.Write(this.RightZ);
writer.Write(this.TopX);
writer.Write(this.TopY);
writer.Write(this.TopZ);
writer.Write((byte)this.RightX);
writer.Write((byte)this.RightY);
writer.Write((byte)this.RightZ);
writer.Write((byte)this.TopX);
writer.Write((byte)this.TopY);
writer.Write((byte)this.TopZ);
writer.Write(this.SteeringAngle);
writer.Write(this.GasPedalPower);
writer.Write(this.BrakePedalPower);
writer.Write(this.HandbrakeUsed);
writer.Write(this.PositionX);
writer.Write(this.PositionY);
writer.Write(this.PositionZ);
writer.Write(this.Position);
}
public void WriteXml(StringBuilder sb, int indent)
{
YvrXml.ValueTag(sb, indent, "Time", Time.ToString());
YvrXml.SelfClosingTag(sb, indent, "Position " + FloatUtil.GetVector3XmlString(Position));
YvrXml.SelfClosingTag(sb, indent, "Velocity " + string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\"", VelocityX.ToString(), VelocityY.ToString(), VelocityZ.ToString()));
YvrXml.SelfClosingTag(sb, indent, "Right " + string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\"", RightX.ToString(), RightY.ToString(), RightZ.ToString()));
YvrXml.SelfClosingTag(sb, indent, "Top " + string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\"", TopX.ToString(), TopY.ToString(), TopZ.ToString()));
YvrXml.ValueTag(sb, indent, "SteeringAngle", SteeringAngle.ToString());
YvrXml.ValueTag(sb, indent, "GasPedalPower", GasPedalPower.ToString());
YvrXml.ValueTag(sb, indent, "BrakePedalPower", BrakePedalPower.ToString());
YvrXml.ValueTag(sb, indent, "HandbrakeUsed", HandbrakeUsed.ToString());
}
public void ReadXml(XmlNode node)
{
Time = Xml.GetChildUIntAttribute(node, "Time", "value");
Position = Xml.GetChildVector3Attributes(node, "Position");
VelocityX = (short)Xml.GetChildIntAttribute(node, "Velocity", "x");
VelocityY = (short)Xml.GetChildIntAttribute(node, "Velocity", "y");
VelocityZ = (short)Xml.GetChildIntAttribute(node, "Velocity", "z");
RightX = (sbyte)Xml.GetChildIntAttribute(node, "Right", "x");
RightY = (sbyte)Xml.GetChildIntAttribute(node, "Right", "y");
RightZ = (sbyte)Xml.GetChildIntAttribute(node, "Right", "z");
TopX = (sbyte)Xml.GetChildIntAttribute(node, "Top", "x");
TopY = (sbyte)Xml.GetChildIntAttribute(node, "Top", "y");
TopZ = (sbyte)Xml.GetChildIntAttribute(node, "Top", "z");
SteeringAngle = (byte)Xml.GetChildUIntAttribute(node, "SteeringAngle", "value");
GasPedalPower = (byte)Xml.GetChildUIntAttribute(node, "GasPedalPower", "value");
BrakePedalPower = (byte)Xml.GetChildUIntAttribute(node, "BrakePedalPower", "value");
HandbrakeUsed = (byte)Xml.GetChildUIntAttribute(node, "HandbrakeUsed", "value");
}
}

View File

@ -1,8 +1,10 @@
using System;
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker.GameFiles
{
@ -38,7 +40,6 @@ namespace CodeWalker.GameFiles
this.EntriesCount
);
}
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
base.Write(writer, parameters);
@ -56,6 +57,61 @@ namespace CodeWalker.GameFiles
writer.Write(this.Unknown_28h);
writer.Write(this.Unknown_2Ch);
}
public void WriteXml(StringBuilder sb, int indent)
{
if (Entries?.Data != null)
{
foreach (var e in Entries.Data)
{
YwrXml.OpenTag(sb, indent, "Item");
e.WriteXml(sb, indent + 1);
YwrXml.CloseTag(sb, indent, "Item");
}
}
}
public void ReadXml(XmlNode node)
{
var entries = new List<WaypointRecordEntry>();
var inodes = node.SelectNodes("Item");
if (inodes != null)
{
foreach (XmlNode inode in inodes)
{
var e = new WaypointRecordEntry();
e.ReadXml(inode);
entries.Add(e);
}
}
Entries = new ResourceSimpleArray<WaypointRecordEntry>();
Entries.Data = entries;
}
public static void WriteXmlNode(WaypointRecordList l, StringBuilder sb, int indent, string name = "WaypointRecordList")
{
if (l == null) return;
if ((l.Entries?.Data == null) || (l.Entries.Data.Count == 0))
{
YwrXml.SelfClosingTag(sb, indent, name);
}
else
{
YwrXml.OpenTag(sb, indent, name);
l.WriteXml(sb, indent + 1);
YwrXml.CloseTag(sb, indent, name);
}
}
public static WaypointRecordList ReadXmlNode(XmlNode node)
{
if (node == null) return null;
var l = new WaypointRecordList();
l.ReadXml(node);
return l;
}
public override IResourceBlock[] GetReferences()
{
@ -70,9 +126,7 @@ namespace CodeWalker.GameFiles
{
public override long BlockLength => 20;
public float PositionX;
public float PositionY;
public float PositionZ;
public Vector3 Position;
public ushort Unk0;
public ushort Unk1;
public ushort Unk2;
@ -81,26 +135,38 @@ namespace CodeWalker.GameFiles
public override void Read(ResourceDataReader reader, params object[] parameters)
{
// read structure data
this.PositionX = reader.ReadSingle();
this.PositionY = reader.ReadSingle();
this.PositionZ = reader.ReadSingle();
this.Position = reader.ReadVector3();
this.Unk0 = reader.ReadUInt16();
this.Unk1 = reader.ReadUInt16();
this.Unk2 = reader.ReadUInt16();
this.Unk3 = reader.ReadUInt16();
}
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
// write structure data
writer.Write(this.PositionX);
writer.Write(this.PositionY);
writer.Write(this.PositionZ);
writer.Write(this.Position);
writer.Write(this.Unk0);
writer.Write(this.Unk1);
writer.Write(this.Unk2);
writer.Write(this.Unk3);
}
public void WriteXml(StringBuilder sb, int indent)
{
YwrXml.SelfClosingTag(sb, indent, "Position " + FloatUtil.GetVector3XmlString(Position));
YwrXml.ValueTag(sb, indent, "Unk0", Unk0.ToString());
YwrXml.ValueTag(sb, indent, "Unk1", Unk1.ToString());
YwrXml.ValueTag(sb, indent, "Unk2", Unk2.ToString());
YwrXml.ValueTag(sb, indent, "Unk3", Unk3.ToString());
}
public void ReadXml(XmlNode node)
{
Position = Xml.GetChildVector3Attributes(node, "Position");
Unk0 = (ushort)Xml.GetChildUIntAttribute(node, "Unk0", "value");
Unk1 = (ushort)Xml.GetChildUIntAttribute(node, "Unk1", "value");
Unk2 = (ushort)Xml.GetChildUIntAttribute(node, "Unk2", "value");
Unk3 = (ushort)Xml.GetChildUIntAttribute(node, "Unk3", "value");
}
}

View File

@ -276,8 +276,8 @@ namespace CodeWalker
InitFileType(".gfx", "Scaleform Flash", 7);
InitFileType(".ynd", "Path Nodes", 8, FileTypeAction.ViewYnd, true);
InitFileType(".ynv", "Nav Mesh", 9, FileTypeAction.ViewModel, true);
InitFileType(".yvr", "Vehicle Record", 9, FileTypeAction.ViewYvr);
InitFileType(".ywr", "Waypoint Record", 9, FileTypeAction.ViewYwr);
InitFileType(".yvr", "Vehicle Record", 9, FileTypeAction.ViewYvr, true);
InitFileType(".ywr", "Waypoint Record", 9, FileTypeAction.ViewYwr, true);
InitFileType(".fxc", "Compiled Shaders", 9, FileTypeAction.ViewFxc);
InitFileType(".yed", "Expression Dictionary", 9, FileTypeAction.ViewYed, true);
InitFileType(".yld", "Cloth Dictionary", 9, FileTypeAction.ViewYld, true);
@ -2745,6 +2745,14 @@ namespace CodeWalker
{
mformat = MetaFormat.Yed;
}
if (fnamel.EndsWith(".ywr.xml"))
{
mformat = MetaFormat.Ywr;
}
if (fnamel.EndsWith(".yvr.xml"))
{
mformat = MetaFormat.Yvr;
}
if (fnamel.EndsWith(".awc.xml"))
{
mformat = MetaFormat.Awc;
@ -2939,6 +2947,28 @@ namespace CodeWalker
data = yed.Save();
break;
}
case MetaFormat.Ywr:
{
var ywr = XmlYwr.GetYwr(doc, fpathin);
if (ywr.Waypoints == null)
{
MessageBox.Show(fname + ": Schema not supported.", "Cannot import YWR XML");
continue;
}
data = ywr.Save();
break;
}
case MetaFormat.Yvr:
{
var yvr = XmlYvr.GetYvr(doc, fpathin);
if (yvr.Records == null)
{
MessageBox.Show(fname + ": Schema not supported.", "Cannot import YVR XML");
continue;
}
data = yvr.Save();
break;
}
case MetaFormat.Awc:
{
var awc = XmlAwc.GetAwc(doc, fpathin);

View File

@ -69,11 +69,11 @@ namespace CodeWalker.Forms
sb.AppendLine("PositionX, PositionY, PositionZ, Time, VelocityX, VelocityY, VelocityZ, RightX, RightY, RightZ, TopX, TopY, TopZ, SteeringAngle, GasPedalPower, BrakePedalPower, HandbrakeUsed");
foreach (var entry in yvr.Records.Entries.data_items)
{
sb.Append(FloatUtil.ToString(entry.PositionX));
sb.Append(FloatUtil.ToString(entry.Position.X));
sb.Append(", ");
sb.Append(FloatUtil.ToString(entry.PositionY));
sb.Append(FloatUtil.ToString(entry.Position.Y));
sb.Append(", ");
sb.Append(FloatUtil.ToString(entry.PositionZ));
sb.Append(FloatUtil.ToString(entry.Position.Z));
sb.Append(", ");
sb.Append(entry.Time.ToString());
sb.Append(", ");
@ -114,9 +114,9 @@ namespace CodeWalker.Forms
{
string[] row =
{
FloatUtil.ToString(entry.PositionX),
FloatUtil.ToString(entry.PositionY),
FloatUtil.ToString(entry.PositionZ),
FloatUtil.ToString(entry.Position.X),
FloatUtil.ToString(entry.Position.Y),
FloatUtil.ToString(entry.Position.Z),
entry.Time.ToString(),
entry.VelocityX.ToString(),
entry.VelocityY.ToString(),

View File

@ -72,11 +72,11 @@ namespace CodeWalker.Forms
sb.AppendLine("PositionX, PositionY, PositionZ, Unk0, Unk1, Unk2, Unk3");
foreach (var entry in ywr.Waypoints.Entries)
{
sb.Append(FloatUtil.ToString(entry.PositionX));
sb.Append(FloatUtil.ToString(entry.Position.X));
sb.Append(", ");
sb.Append(FloatUtil.ToString(entry.PositionY));
sb.Append(FloatUtil.ToString(entry.Position.Y));
sb.Append(", ");
sb.Append(FloatUtil.ToString(entry.PositionZ));
sb.Append(FloatUtil.ToString(entry.Position.Z));
sb.Append(", ");
sb.Append(entry.Unk0.ToString());
sb.Append(", ");
@ -97,9 +97,9 @@ namespace CodeWalker.Forms
{
string[] row =
{
FloatUtil.ToString(entry.PositionX),
FloatUtil.ToString(entry.PositionY),
FloatUtil.ToString(entry.PositionZ),
FloatUtil.ToString(entry.Position.X),
FloatUtil.ToString(entry.Position.Y),
FloatUtil.ToString(entry.Position.Z),
entry.Unk0.ToString(),
entry.Unk1.ToString(),
entry.Unk2.ToString(),