mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2025-01-10 23:15:14 +08:00
AWC/XML conversion
This commit is contained in:
parent
a347346f1f
commit
5e46e85b9e
@ -232,7 +232,7 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < StreamCount; i++)
|
for (int i = 0; i < StreamCount; i++)
|
||||||
{
|
{
|
||||||
w.Write((i < (UnkUshorts?.Length ?? 0)) ? UnkUshorts[i] : 0);
|
w.Write((i < (UnkUshorts?.Length ?? 0)) ? UnkUshorts[i] : (ushort)0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ namespace CodeWalker.GameFiles
|
|||||||
if (snode != null)
|
if (snode != null)
|
||||||
{
|
{
|
||||||
var slist = new List<AwcStream>();
|
var slist = new List<AwcStream>();
|
||||||
var inodes = node.SelectNodes("Item");
|
var inodes = snode.SelectNodes("Item");
|
||||||
foreach (XmlNode inode in inodes)
|
foreach (XmlNode inode in inodes)
|
||||||
{
|
{
|
||||||
var stream = new AwcStream(this);
|
var stream = new AwcStream(this);
|
||||||
@ -377,6 +377,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
streaminfo.Chunks = chunkinfos.ToArray();
|
streaminfo.Chunks = chunkinfos.ToArray();
|
||||||
|
streaminfo.ChunkCount = (uint)chunkinfos.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StreamInfos = streaminfos.ToArray();
|
StreamInfos = streaminfos.ToArray();
|
||||||
@ -662,22 +663,32 @@ namespace CodeWalker.GameFiles
|
|||||||
public void WriteXml(StringBuilder sb, int indent, string wavfolder)
|
public void WriteXml(StringBuilder sb, int indent, string wavfolder)
|
||||||
{
|
{
|
||||||
AwcXml.StringTag(sb, indent, "Name", AwcXml.HashString(HashAdjusted));
|
AwcXml.StringTag(sb, indent, "Name", AwcXml.HashString(HashAdjusted));
|
||||||
if (StreamFormatChunk == null)
|
if (StreamFormatChunk == null) //skip the wave file output for multichannel sources
|
||||||
{
|
{
|
||||||
//skip the wave file output for multichannel sources
|
var export = !string.IsNullOrEmpty(wavfolder);
|
||||||
var fname = Name?.Replace("/", "")?.Replace("\\", "");
|
var fname = Name?.Replace("/", "")?.Replace("\\", "") ?? "0x0";
|
||||||
AwcXml.StringTag(sb, indent, "FileName", AwcXml.XmlEscape(fname + ".wav"));
|
byte[] fdata = null;
|
||||||
|
if (MidiChunk != null)
|
||||||
|
{
|
||||||
|
fname += ".midi";
|
||||||
|
fdata = export ? MidiChunk.Data : null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fname += ".wav";
|
||||||
|
fdata = export ? GetWavFile() : null;
|
||||||
|
}
|
||||||
|
AwcXml.StringTag(sb, indent, "FileName", AwcXml.XmlEscape(fname));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(wavfolder))
|
if (export)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(wavfolder))
|
if (!Directory.Exists(wavfolder))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(wavfolder);
|
Directory.CreateDirectory(wavfolder);
|
||||||
}
|
}
|
||||||
var filepath = Path.Combine(wavfolder, (fname ?? "null") + ".wav");
|
var filepath = Path.Combine(wavfolder, fname);
|
||||||
var wav = GetWavFile();
|
File.WriteAllBytes(filepath, fdata);
|
||||||
File.WriteAllBytes(filepath, wav);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -719,15 +730,16 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
StreamFormat = new AwcStreamFormat();
|
StreamFormat = new AwcStreamFormat();
|
||||||
StreamFormat.ReadXml(fnode);
|
StreamFormat.ReadXml(fnode);
|
||||||
|
StreamFormat.Id = Hash;
|
||||||
}
|
}
|
||||||
var cnode = node.SelectSingleNode("Chunks");
|
var cnode = node.SelectSingleNode("Chunks");
|
||||||
if (cnode != null)
|
if (cnode != null)
|
||||||
{
|
{
|
||||||
var clist = new List<AwcChunk>();
|
var clist = new List<AwcChunk>();
|
||||||
var inodes = node.SelectNodes("Item");
|
var inodes = cnode.SelectNodes("Item");
|
||||||
foreach (XmlNode inode in inodes)
|
foreach (XmlNode inode in inodes)
|
||||||
{
|
{
|
||||||
var type = Xml.GetChildEnumInnerText<AwcChunkType>(node, "Type");
|
var type = Xml.GetChildEnumInnerText<AwcChunkType>(inode, "Type");
|
||||||
var info = new AwcChunkInfo() { Type = type };
|
var info = new AwcChunkInfo() { Type = type };
|
||||||
var chunk = CreateChunk(info);
|
var chunk = CreateChunk(info);
|
||||||
chunk?.ReadXml(inode);
|
chunk?.ReadXml(inode);
|
||||||
@ -746,9 +758,15 @@ namespace CodeWalker.GameFiles
|
|||||||
var filepath = Path.Combine(wavfolder, filename);
|
var filepath = Path.Combine(wavfolder, filename);
|
||||||
if (File.Exists(filepath))
|
if (File.Exists(filepath))
|
||||||
{
|
{
|
||||||
var wav = File.ReadAllBytes(filepath);
|
var fdata = File.ReadAllBytes(filepath);
|
||||||
|
if (MidiChunk != null)
|
||||||
ParseWavFile(wav);
|
{
|
||||||
|
MidiChunk.Data = fdata;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ParseWavFile(fdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -927,10 +945,11 @@ namespace CodeWalker.GameFiles
|
|||||||
if ((blkcnt == smblockcount) || (i == totsmblockcount-1))
|
if ((blkcnt == smblockcount) || (i == totsmblockcount-1))
|
||||||
{
|
{
|
||||||
var lgblockind = i / smblockcount;
|
var lgblockind = i / smblockcount;
|
||||||
|
var blkstart = lgblockind * smblockcount;
|
||||||
var blk = streamblocks[lgblockind];
|
var blk = streamblocks[lgblockind];
|
||||||
var chan = new AwcStreamDataChannel();
|
var chan = new AwcStreamDataChannel();
|
||||||
var bytcnt = blkcnt * 2048;
|
var bytcnt = blkcnt * 2048;
|
||||||
var srcoff = i * 2048;
|
var srcoff = blkstart * 2048;
|
||||||
var srccnt = Math.Min(bytcnt, cdlen - srcoff);
|
var srccnt = Math.Min(bytcnt, cdlen - srcoff);
|
||||||
var data = new byte[bytcnt];
|
var data = new byte[bytcnt];
|
||||||
Buffer.BlockCopy(chandata, srcoff, data, 0, srccnt);
|
Buffer.BlockCopy(chandata, srcoff, data, 0, srccnt);
|
||||||
@ -938,7 +957,7 @@ namespace CodeWalker.GameFiles
|
|||||||
chan.SampleOffsets = chansmpoffs.ToArray();
|
chan.SampleOffsets = chansmpoffs.ToArray();
|
||||||
chan.SampleCount = blkcnt * 4088;
|
chan.SampleCount = blkcnt * 4088;
|
||||||
chan.BlockCount = blkcnt;
|
chan.BlockCount = blkcnt;
|
||||||
chan.StartBlock = i;
|
chan.StartBlock = (c * smblockcount);
|
||||||
|
|
||||||
blk.Channels[c] = chan;
|
blk.Channels[c] = chan;
|
||||||
chansmpoffs.Clear();
|
chansmpoffs.Clear();
|
||||||
@ -950,6 +969,8 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
StreamBlocks = streamblocks.ToArray();
|
StreamBlocks = streamblocks.ToArray();
|
||||||
|
|
||||||
|
StreamFormatChunk.BlockCount = (uint)streamblocks.Count;
|
||||||
|
|
||||||
if (SeekTableChunk != null)
|
if (SeekTableChunk != null)
|
||||||
{
|
{
|
||||||
SeekTableChunk.SeekTable = seektable.ToArray();
|
SeekTableChunk.SeekTable = seektable.ToArray();
|
||||||
@ -976,7 +997,7 @@ namespace CodeWalker.GameFiles
|
|||||||
ms.Position = 0;
|
ms.Position = 0;
|
||||||
ms.Read(bytes, 0, (int)ms.Length);
|
ms.Read(bytes, 0, (int)ms.Length);
|
||||||
|
|
||||||
if (DataChunk != null)
|
if (DataChunk == null)
|
||||||
{
|
{
|
||||||
DataChunk = new AwcDataChunk(new AwcChunkInfo() { Type = AwcChunkType.data });
|
DataChunk = new AwcDataChunk(new AwcChunkInfo() { Type = AwcChunkType.data });
|
||||||
}
|
}
|
||||||
@ -1114,10 +1135,10 @@ namespace CodeWalker.GameFiles
|
|||||||
var ms = new MemoryStream(wav);
|
var ms = new MemoryStream(wav);
|
||||||
var r = new DataReader(ms);
|
var r = new DataReader(ms);
|
||||||
|
|
||||||
var RIFF = r.ReadUInt32();
|
var RIFF = r.ReadUInt32(); // 0x46464952
|
||||||
var wavLength = r.ReadInt32();
|
var wavLength = r.ReadInt32();
|
||||||
var WAVE = r.ReadUInt32();
|
var WAVE = r.ReadUInt32(); // 0x45564157
|
||||||
var fmt_ = r.ReadUInt32();
|
var fmt_ = r.ReadUInt32(); // 0x20746D66
|
||||||
var fmtLength = r.ReadInt32();
|
var fmtLength = r.ReadInt32();
|
||||||
var formatcodec = r.ReadInt16();
|
var formatcodec = r.ReadInt16();
|
||||||
var channels = r.ReadInt16();
|
var channels = r.ReadInt16();
|
||||||
@ -1132,8 +1153,8 @@ namespace CodeWalker.GameFiles
|
|||||||
ext2 = r.ReadUInt16();
|
ext2 = r.ReadUInt16();
|
||||||
samplesPerBlock = r.ReadUInt16();
|
samplesPerBlock = r.ReadUInt16();
|
||||||
}
|
}
|
||||||
var hdrlen = fmtLength + 20;
|
var datatag = r.ReadUInt32(); // 0x61746164
|
||||||
var datalen = wavLength - hdrlen;
|
var datalen = r.ReadInt32();
|
||||||
var dataPCM = r.ReadBytes(datalen);
|
var dataPCM = r.ReadBytes(datalen);
|
||||||
|
|
||||||
if (r.Position != r.Length)
|
if (r.Position != r.Length)
|
||||||
@ -1162,7 +1183,7 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
if (StreamFormat != null)
|
if (StreamFormat != null)
|
||||||
{
|
{
|
||||||
StreamFormat.Samples = (uint)sampleCount;
|
//StreamFormat.Samples = (uint)sampleCount;
|
||||||
StreamFormat.SamplesPerSecond = (ushort)sampleRate;
|
StreamFormat.SamplesPerSecond = (ushort)sampleRate;
|
||||||
|
|
||||||
DataChunk = new AwcDataChunk(null);
|
DataChunk = new AwcDataChunk(null);
|
||||||
@ -1173,7 +1194,7 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
if (FormatChunk != null)
|
if (FormatChunk != null)
|
||||||
{
|
{
|
||||||
FormatChunk.Samples = (uint)sampleCount;
|
//FormatChunk.Samples = (uint)sampleCount;
|
||||||
FormatChunk.SamplesPerSecond = (ushort)sampleRate;
|
FormatChunk.SamplesPerSecond = (ushort)sampleRate;
|
||||||
|
|
||||||
if (DataChunk == null) DataChunk = new AwcDataChunk(new AwcChunkInfo() { Type = AwcChunkType.data });
|
if (DataChunk == null) DataChunk = new AwcDataChunk(new AwcChunkInfo() { Type = AwcChunkType.data });
|
||||||
@ -1404,12 +1425,12 @@ namespace CodeWalker.GameFiles
|
|||||||
public override void WriteXml(StringBuilder sb, int indent)
|
public override void WriteXml(StringBuilder sb, int indent)
|
||||||
{
|
{
|
||||||
AwcXml.StringTag(sb, indent, "Type", ChunkInfo?.Type.ToString());
|
AwcXml.StringTag(sb, indent, "Type", ChunkInfo?.Type.ToString());
|
||||||
//AwcXml.ValueTag(sb, indent, "BlockSize", BlockSize.ToString());
|
AwcXml.ValueTag(sb, indent, "BlockSize", BlockSize.ToString());
|
||||||
//this is mostly just a placeholder. in XML, channel format is written with each channel stream
|
//this is mostly just a placeholder. in XML, channel format is written with each channel stream
|
||||||
}
|
}
|
||||||
public override void ReadXml(XmlNode node)
|
public override void ReadXml(XmlNode node)
|
||||||
{
|
{
|
||||||
//BlockSize = Xml.GetChildUIntAttribute(node, "BlockSize");
|
BlockSize = Xml.GetChildUIntAttribute(node, "BlockSize");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -1538,11 +1559,6 @@ namespace CodeWalker.GameFiles
|
|||||||
public override void Write(DataWriter w)
|
public override void Write(DataWriter w)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ClipDict != null)
|
|
||||||
{
|
|
||||||
Data = ResourceBuilder.Build(ClipDict, 46); //ycd is 46...
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write(Data);
|
w.Write(Data);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1563,6 +1579,8 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
ClipDict = new ClipDictionary();
|
ClipDict = new ClipDictionary();
|
||||||
ClipDict.ReadXml(dnode);
|
ClipDict.ReadXml(dnode);
|
||||||
|
|
||||||
|
Data = ResourceBuilder.Build(ClipDict, 46, false); //ycd is 46...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,6 +1614,13 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public override void Write(DataWriter w)
|
public override void Write(DataWriter w)
|
||||||
{
|
{
|
||||||
|
if (Data != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
w.Write(Data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override void WriteXml(StringBuilder sb, int indent)
|
public override void WriteXml(StringBuilder sb, int indent)
|
||||||
{
|
{
|
||||||
|
@ -162,7 +162,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static byte[] Build(ResourceFileBase fileBase, int version)
|
public static byte[] Build(ResourceFileBase fileBase, int version, bool compress = true)
|
||||||
{
|
{
|
||||||
|
|
||||||
fileBase.FilePagesInfo = new ResourcePagesInfo();
|
fileBase.FilePagesInfo = new ResourcePagesInfo();
|
||||||
@ -258,7 +258,7 @@ namespace CodeWalker.GameFiles
|
|||||||
Buffer.BlockCopy(gfxData, 0, tdata, sysDataSize, gfxDataSize);
|
Buffer.BlockCopy(gfxData, 0, tdata, sysDataSize, gfxDataSize);
|
||||||
|
|
||||||
|
|
||||||
var cdata = Compress(tdata);
|
var cdata = compress ? Compress(tdata) : tdata;
|
||||||
|
|
||||||
|
|
||||||
var dataSize = 16 + cdata.Length;// sysDataSize + gfxDataSize;
|
var dataSize = 16 + cdata.Length;// sysDataSize + gfxDataSize;
|
||||||
|
Loading…
Reference in New Issue
Block a user