mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2024-11-27 17:00:53 +01:00
First work for CPK archives
This commit is contained in:
parent
e3aa58f135
commit
3cc98ff257
@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcbEditor", "Source\AcbEdit
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbEditor", "Source\CsbEditor\CsbEditor.csproj", "{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbBuilder", "Source\CsbBuilder\CsbBuilder.csproj", "{4CF49665-3DFD-4A5C-B231-B97842F091B9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -32,6 +34,10 @@ Global
|
||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
6
Source/CsbBuilder/App.config
Normal file
6
Source/CsbBuilder/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
48
Source/CsbBuilder/CriTableAax.cs
Normal file
48
Source/CsbBuilder/CriTableAax.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[CriSerializable("AAX")]
|
||||
[Serializable]
|
||||
public class CriTableAax
|
||||
{
|
||||
public enum EnumLoopFlag
|
||||
{
|
||||
Intro = 0,
|
||||
Loop = 1,
|
||||
};
|
||||
|
||||
private byte[] _data = new byte[0];
|
||||
private EnumLoopFlag _lpflg = EnumLoopFlag.Intro;
|
||||
|
||||
[CriField("data", 0)]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
set
|
||||
{
|
||||
_data = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("lpflg", 1)]
|
||||
public byte LoopFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)_lpflg;
|
||||
}
|
||||
set
|
||||
{
|
||||
_lpflg = (EnumLoopFlag)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
Source/CsbBuilder/CriTableAisac.cs
Normal file
90
Source/CsbBuilder/CriTableAisac.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLISC")]
|
||||
public class CriTableAisac
|
||||
{
|
||||
private string _name = string.Empty;
|
||||
private string _ptname = string.Empty;
|
||||
private byte _type = 0;
|
||||
private byte _rndrng = 0;
|
||||
|
||||
[CriField("name", 0)]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("ptname", 1)]
|
||||
public string PathName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ptname;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ptname = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("type", 2)]
|
||||
public byte Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
set
|
||||
{
|
||||
_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriIgnore]
|
||||
public List<CriTableAisacGraph> GraphList { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
[CriField("grph", 3)]
|
||||
public byte[] Graph
|
||||
{
|
||||
get
|
||||
{
|
||||
return CriTableSerializer.Serialize(GraphList, CriTableWriterSettings.AdxSettings);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
GraphList = CriTableSerializer.Deserialize<CriTableAisacGraph>(value);
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("rndrng", 4)]
|
||||
public byte RandomRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return _rndrng;
|
||||
}
|
||||
set
|
||||
{
|
||||
_rndrng = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
104
Source/CsbBuilder/CriTableAisacGraph.cs
Normal file
104
Source/CsbBuilder/CriTableAisacGraph.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLIGR")]
|
||||
public class CriTableAisacGraph
|
||||
{
|
||||
private byte _type = 0;
|
||||
private float _imax = 0;
|
||||
private float _imin = 0;
|
||||
private float _omax = 0;
|
||||
private float _omin = 0;
|
||||
|
||||
[CriField("type", 0)]
|
||||
public byte Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
set
|
||||
{
|
||||
_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("imax", 1)]
|
||||
public float InMaximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _imax;
|
||||
}
|
||||
set
|
||||
{
|
||||
_imax = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("imin", 2)]
|
||||
public float InMinimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _imin;
|
||||
}
|
||||
set
|
||||
{
|
||||
_imin = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("omax", 3)]
|
||||
public float OutMaximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _omax;
|
||||
}
|
||||
set
|
||||
{
|
||||
_omax = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("omin", 4)]
|
||||
public float OutMinimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _omin;
|
||||
}
|
||||
set
|
||||
{
|
||||
_omin = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriIgnore]
|
||||
public List<CriTableAisacPoint> PointsList { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
[CriField("points", 5)]
|
||||
public byte[] Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return CriTableSerializer.Serialize(PointsList, CriTableWriterSettings.AdxSettings);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
PointsList = CriTableSerializer.Deserialize<CriTableAisacPoint>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
Source/CsbBuilder/CriTableAisacPoint.cs
Normal file
42
Source/CsbBuilder/CriTableAisacPoint.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLIPT")]
|
||||
public class CriTableAisacPoint
|
||||
{
|
||||
private ushort _in = 0;
|
||||
private ushort _out = 0;
|
||||
|
||||
[CriField("in", 0)]
|
||||
public ushort In
|
||||
{
|
||||
get
|
||||
{
|
||||
return _in;
|
||||
}
|
||||
set
|
||||
{
|
||||
_in = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("out", 1)]
|
||||
public ushort Out
|
||||
{
|
||||
get
|
||||
{
|
||||
return _out;
|
||||
}
|
||||
set
|
||||
{
|
||||
_out = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
84
Source/CsbBuilder/CriTableCue.cs
Normal file
84
Source/CsbBuilder/CriTableCue.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLCUE")]
|
||||
public class CriTableCue
|
||||
{
|
||||
private string _name = string.Empty;
|
||||
private uint _id = 0;
|
||||
private string _synth = string.Empty;
|
||||
private string _udata = string.Empty;
|
||||
private byte _flags = 0;
|
||||
|
||||
[CriField("name", 0)]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("id", 1)]
|
||||
public uint Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("synth", 2)]
|
||||
public string Synth
|
||||
{
|
||||
get
|
||||
{
|
||||
return _synth;
|
||||
}
|
||||
set
|
||||
{
|
||||
_synth = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("udata", 3)]
|
||||
public string UserData
|
||||
{
|
||||
get
|
||||
{
|
||||
return _udata;
|
||||
}
|
||||
set
|
||||
{
|
||||
_udata = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("flags", 4)]
|
||||
public byte Flags
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flags;
|
||||
}
|
||||
set
|
||||
{
|
||||
_flags = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
134
Source/CsbBuilder/CriTableCueSheet.cs
Normal file
134
Source/CsbBuilder/CriTableCueSheet.cs
Normal file
@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
using System.Linq;
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLCSB")]
|
||||
public class CriTableCueSheet
|
||||
{
|
||||
public enum EnumTableType
|
||||
{
|
||||
None = 0,
|
||||
Cue = 1,
|
||||
Synth = 2,
|
||||
SoundElement = 4,
|
||||
Aisac = 5,
|
||||
VoiceLimitGroup = 6,
|
||||
VersionInfo = 7,
|
||||
};
|
||||
|
||||
private string _name = string.Empty;
|
||||
private EnumTableType _ttype = EnumTableType.None;
|
||||
|
||||
[CriField("name", 0)]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("ttype", 1)]
|
||||
public byte TableType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)_ttype;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ttype = (EnumTableType)value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriIgnore]
|
||||
[XmlArray]
|
||||
[XmlArrayItem(typeof(CriTableCue))]
|
||||
[XmlArrayItem(typeof(CriTableSynth))]
|
||||
[XmlArrayItem(typeof(CriTableSoundElement))]
|
||||
[XmlArrayItem(typeof(CriTableAisac))]
|
||||
[XmlArrayItem(typeof(CriTableVoiceLimitGroup))]
|
||||
[XmlArrayItem(typeof(CriTableVersionInfo))]
|
||||
public ArrayList DataList { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
[CriField("utf", 2)]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (_ttype)
|
||||
{
|
||||
case EnumTableType.None:
|
||||
return new byte[0];
|
||||
|
||||
case EnumTableType.Cue:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableCue>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
|
||||
case EnumTableType.Synth:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableSynth>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
|
||||
case EnumTableType.SoundElement:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableSoundElement>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
|
||||
case EnumTableType.Aisac:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableAisac>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
|
||||
case EnumTableType.VoiceLimitGroup:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableVoiceLimitGroup>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
|
||||
case EnumTableType.VersionInfo:
|
||||
return CriTableSerializer.Serialize(DataList.OfType<CriTableVersionInfo>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Unknown table type {_ttype}, please report the error with the file.", "_ttype");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (_ttype)
|
||||
{
|
||||
case EnumTableType.Cue:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableCue));
|
||||
break;
|
||||
|
||||
case EnumTableType.Synth:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableSynth));
|
||||
break;
|
||||
|
||||
case EnumTableType.SoundElement:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableSoundElement));
|
||||
break;
|
||||
|
||||
case EnumTableType.Aisac:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableAisac));
|
||||
break;
|
||||
|
||||
case EnumTableType.VoiceLimitGroup:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableVoiceLimitGroup));
|
||||
break;
|
||||
|
||||
case EnumTableType.VersionInfo:
|
||||
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableVersionInfo));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unknown table type {_ttype}, please report the error with the file.", "_ttype");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
130
Source/CsbBuilder/CriTableSoundElement.cs
Normal file
130
Source/CsbBuilder/CriTableSoundElement.cs
Normal file
@ -0,0 +1,130 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLSDL")]
|
||||
public class CriTableSoundElement
|
||||
{
|
||||
public enum EnumFormat
|
||||
{
|
||||
Adx = 0,
|
||||
Dsp = 4,
|
||||
};
|
||||
|
||||
public enum EnumStreamFlag
|
||||
{
|
||||
Internal = 0,
|
||||
External = 1,
|
||||
};
|
||||
|
||||
private string _name = string.Empty;
|
||||
private EnumFormat _fmt = EnumFormat.Adx;
|
||||
private byte _nch = 0;
|
||||
private EnumStreamFlag _stmflg = EnumStreamFlag.Internal;
|
||||
private uint _sfreq = 0;
|
||||
private uint _nsmpl = 0;
|
||||
|
||||
[CriField("name", 0)]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriIgnore]
|
||||
public List<CriTableAax> DataList { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
[CriField("data", 1)]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return CriTableSerializer.Serialize(DataList, CriTableWriterSettings.AdxSettings);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
DataList = CriTableSerializer.Deserialize<CriTableAax>(value);
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("fmt", 2)]
|
||||
public byte Format
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)_fmt;
|
||||
}
|
||||
set
|
||||
{
|
||||
_fmt = (EnumFormat)value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("nch", 3)]
|
||||
public byte NumberChannels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nch;
|
||||
}
|
||||
set
|
||||
{
|
||||
_nch = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("stmflg", 4)]
|
||||
public byte StreamFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)_stmflg;
|
||||
}
|
||||
set
|
||||
{
|
||||
_stmflg = (EnumStreamFlag)value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("sfreq", 5)]
|
||||
public uint SoundFrequence
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sfreq;
|
||||
}
|
||||
set
|
||||
{
|
||||
_sfreq = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("nsmpl", 6)]
|
||||
public uint NumberSamples
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nsmpl;
|
||||
}
|
||||
set
|
||||
{
|
||||
_nsmpl = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1328
Source/CsbBuilder/CriTableSynth.cs
Normal file
1328
Source/CsbBuilder/CriTableSynth.cs
Normal file
File diff suppressed because it is too large
Load Diff
42
Source/CsbBuilder/CriTableVersionInfo.cs
Normal file
42
Source/CsbBuilder/CriTableVersionInfo.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBL_INFO")]
|
||||
public class CriTableVersionInfo
|
||||
{
|
||||
private uint _DataFmtVer = 0x940000;
|
||||
private uint _ExtSize = 0;
|
||||
|
||||
[CriField("DataFmtVer", 0)]
|
||||
public uint DataFormatVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DataFmtVer;
|
||||
}
|
||||
set
|
||||
{
|
||||
_DataFmtVer = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("ExtSize", 1)]
|
||||
public uint ExtensionSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ExtSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ExtSize = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
Source/CsbBuilder/CriTableVoiceLimitGroup.cs
Normal file
42
Source/CsbBuilder/CriTableVoiceLimitGroup.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
[Serializable]
|
||||
[CriSerializable("TBLVLG")]
|
||||
public class CriTableVoiceLimitGroup
|
||||
{
|
||||
private string _vlgname = string.Empty;
|
||||
private uint _vlgnvoice = 0;
|
||||
|
||||
[CriField("vlgname", 0)]
|
||||
public string VoiceLimitGroupName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _vlgname;
|
||||
}
|
||||
set
|
||||
{
|
||||
_vlgname = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CriField("vlgnvoice", 1)]
|
||||
public uint VoiceLimitGroupNum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _vlgnvoice;
|
||||
}
|
||||
set
|
||||
{
|
||||
_vlgnvoice = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
88
Source/CsbBuilder/CsbBuilder.csproj
Normal file
88
Source/CsbBuilder/CsbBuilder.csproj
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{4CF49665-3DFD-4A5C-B231-B97842F091B9}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CsbBuilder</RootNamespace>
|
||||
<AssemblyName>CsbBuilder</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CriTableAax.cs" />
|
||||
<Compile Include="CriTableAisac.cs" />
|
||||
<Compile Include="CriTableAisacGraph.cs" />
|
||||
<Compile Include="CriTableAisacPoint.cs" />
|
||||
<Compile Include="CriTableCue.cs" />
|
||||
<Compile Include="CriTableCueSheet.cs" />
|
||||
<Compile Include="CriTableSoundElement.cs" />
|
||||
<Compile Include="CriTableSynth.cs" />
|
||||
<Compile Include="CriTableVersionInfo.cs" />
|
||||
<Compile Include="CriTableVoiceLimitGroup.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SonicAudioLib\SonicAudioLib.csproj">
|
||||
<Project>{63138773-1f47-474c-9345-15eb6183ecc6}</Project>
|
||||
<Name>SonicAudioLib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
73
Source/CsbBuilder/Program.cs
Normal file
73
Source/CsbBuilder/Program.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using SonicAudioLib.CriMw;
|
||||
using SonicAudioLib.CriMw.Serialization;
|
||||
using SonicAudioLib.IO;
|
||||
using SonicAudioLib.Archive;
|
||||
|
||||
using System.Globalization;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CsbBuilder
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Console.WriteLine(Properties.Resources.Description);
|
||||
Console.ReadLine();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (args[0].EndsWith(".csb"))
|
||||
{
|
||||
List<CriTableCueSheet> cueSheets = CriTableSerializer.Deserialize<CriTableCueSheet>(args[0]);
|
||||
//CriTableSerializer.Serialize(args[0] + ".new", cueSheets, CriTableWriterSettings.AdxSettings);
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(List<CriTableCueSheet>));
|
||||
using (Stream dest = File.Create(Path.GetFileNameWithoutExtension(args[0]) + ".xml"))
|
||||
{
|
||||
serializer.Serialize(dest, cueSheets);
|
||||
}
|
||||
}
|
||||
|
||||
else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory))
|
||||
{
|
||||
}
|
||||
|
||||
else if (args[0].EndsWith(".xml"))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(List<CriTableCueSheet>));
|
||||
using (Stream dest = File.OpenRead(args[0]))
|
||||
{
|
||||
CriTableSerializer.Serialize(Path.GetFileNameWithoutExtension(args[0]) + ".csb", (List<CriTableCueSheet>)serializer.Deserialize(dest), CriTableWriterSettings.AdxSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception exception)
|
||||
{
|
||||
//MessageBox.Show($"{exception.Message}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadAdx(FileInfo fileInfo, out uint sampleRate, out byte numberChannels)
|
||||
{
|
||||
using (Stream source = fileInfo.OpenRead())
|
||||
{
|
||||
source.Seek(7, SeekOrigin.Begin);
|
||||
numberChannels = EndianStream.ReadByte(source);
|
||||
sampleRate = EndianStream.ReadUInt32BE(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
Source/CsbBuilder/Properties/AssemblyInfo.cs
Normal file
36
Source/CsbBuilder/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CsbBuilder")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CsbBuilder")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("91f6b6a6-5d95-4c7a-b22e-a35bd32db67a")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
72
Source/CsbBuilder/Properties/Resources.Designer.cs
generated
Normal file
72
Source/CsbBuilder/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CsbBuilder.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CsbBuilder.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to placeholder.
|
||||
/// </summary>
|
||||
internal static string Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
Source/CsbBuilder/Properties/Resources.resx
Normal file
123
Source/CsbBuilder/Properties/Resources.resx
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>placeholder</value>
|
||||
</data>
|
||||
</root>
|
@ -20,24 +20,48 @@ namespace SonicAudioCmd
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args[0].EndsWith(".cpk"))
|
||||
{
|
||||
CriCpkArchive archive = new CriCpkArchive();
|
||||
archive.Load(args[0]);
|
||||
archive.Print();
|
||||
|
||||
foreach (CriCpkEntry entry in archive)
|
||||
{
|
||||
using (Stream source = File.OpenRead(args[0]), substream = entry.Open(source))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(Path.Combine(Path.GetFileNameWithoutExtension(args[0]), entry.DirectoryName, entry.Name));
|
||||
FileInfo fileInfo = new FileInfo(Path.Combine(Path.GetFileNameWithoutExtension(args[0]), entry.DirectoryName != null ? entry.DirectoryName : "", entry.Name != null ? entry.Name : entry.Id.ToString() + ".bin"));
|
||||
fileInfo.Directory.Create();
|
||||
using (Stream destination = fileInfo.Create())
|
||||
{
|
||||
substream.CopyTo(destination);
|
||||
}
|
||||
fileInfo.LastWriteTime = entry.UpdateDateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.ReadLine();
|
||||
else
|
||||
{
|
||||
CriCpkArchive archive = new CriCpkArchive();
|
||||
archive.Align = 16;
|
||||
archive.Mode = CriCpkMode.FileName;
|
||||
|
||||
uint id = 0;
|
||||
foreach (string file in Directory.GetFiles(args[0], "*", SearchOption.AllDirectories))
|
||||
{
|
||||
CriCpkEntry entry = new CriCpkEntry();
|
||||
entry.Id = id;
|
||||
entry.Name = Path.GetFileName(file);
|
||||
entry.DirectoryName = Path.GetDirectoryName(file.Replace(args[0] + "\\", ""));
|
||||
entry.FilePath = new FileInfo(file);
|
||||
archive.Add(entry);
|
||||
id++;
|
||||
}
|
||||
|
||||
archive.Save(args[0] + ".cpk");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using SonicAudioLib.IO;
|
||||
using SonicAudioLib.Module;
|
||||
@ -106,5 +107,29 @@ namespace SonicAudioLib.Archive
|
||||
{
|
||||
return entries.GetEnumerator();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public void Print()
|
||||
{
|
||||
Type archiveType = GetType();
|
||||
Console.WriteLine("{0}:", archiveType.Name);
|
||||
|
||||
foreach (PropertyInfo property in archiveType.GetProperties().Where(p => p.GetIndexParameters().Length == 0))
|
||||
{
|
||||
Console.WriteLine(" {0}: {1}", property.Name, property.GetValue(this));
|
||||
}
|
||||
|
||||
foreach (T entry in entries)
|
||||
{
|
||||
Type entryType = entry.GetType();
|
||||
|
||||
Console.WriteLine("{0}:", entryType.Name);
|
||||
foreach (PropertyInfo property in entryType.GetProperties().Where(p => p.GetIndexParameters().Length == 0))
|
||||
{
|
||||
Console.WriteLine(" {0}: {1}", property.Name, property.GetValue(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -11,31 +11,114 @@ namespace SonicAudioLib.Archive
|
||||
{
|
||||
public class CriCpkEntry : EntryBase
|
||||
{
|
||||
private DateTime updateDateTime;
|
||||
|
||||
public string DirectoryName { get; set; }
|
||||
public string Name { get; set; }
|
||||
public uint Index { get; set; }
|
||||
public uint Id { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public bool IsCompressed { get; set; }
|
||||
|
||||
public DateTime UpdateDateTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FilePath != null)
|
||||
{
|
||||
return FilePath.LastWriteTime;
|
||||
}
|
||||
|
||||
return updateDateTime;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
updateDateTime = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CriCpkMode
|
||||
{
|
||||
None = -1,
|
||||
FileNameIdAndGroup = 5,
|
||||
IdAndGroup = 4,
|
||||
FileNameAndGroup = 3,
|
||||
FileNameAndId = 2,
|
||||
FileName = 1,
|
||||
Id = 0,
|
||||
}
|
||||
|
||||
public class CriCpkArchive : ArchiveBase<CriCpkEntry>
|
||||
{
|
||||
private ushort align = 1;
|
||||
private CriCpkMode mode = CriCpkMode.FileName;
|
||||
|
||||
public ushort Align
|
||||
{
|
||||
get
|
||||
{
|
||||
return align;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
value = 1;
|
||||
}
|
||||
|
||||
align = value;
|
||||
}
|
||||
}
|
||||
|
||||
public CriCpkMode Mode
|
||||
{
|
||||
get
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Comment { get; set; }
|
||||
|
||||
public override void Read(Stream source)
|
||||
{
|
||||
using (CriTableReader reader = CriCpkSection.Open(source, source.Position))
|
||||
{
|
||||
reader.Read();
|
||||
|
||||
if (reader.GetUInt32("CpkMode") != 1)
|
||||
#if DEBUG
|
||||
for (int i = 0; i < reader.NumberOfFields; i++)
|
||||
{
|
||||
throw new Exception("Unsupported CPK type! Only TOC CPKs are supported for now.");
|
||||
Console.WriteLine("{0} ({1}): {2}", reader.GetFieldName(i), reader.GetFieldFlag(i), reader.GetValue(i));
|
||||
}
|
||||
#endif
|
||||
|
||||
mode = (CriCpkMode)reader.GetUInt32("CpkMode");
|
||||
|
||||
// No need to waste time, stop right there.
|
||||
if (mode == CriCpkMode.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long tocPosition = (long)reader.GetUInt64("TocOffset");
|
||||
long itocPosition = (long)reader.GetUInt64("ItocOffset");
|
||||
long etocPosition = (long)reader.GetUInt64("EtocOffset");
|
||||
long contentPosition = (long)reader.GetUInt64("ContentOffset");
|
||||
ushort align = reader.GetUInt16("Align");
|
||||
|
||||
align = reader.GetUInt16("Align");
|
||||
|
||||
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
using (CriTableReader tocReader = CriCpkSection.Open(source, tocPosition))
|
||||
using (CriTableReader etocReader = CriCpkSection.Open(source, etocPosition))
|
||||
{
|
||||
while (tocReader.Read())
|
||||
{
|
||||
@ -44,7 +127,7 @@ namespace SonicAudioLib.Archive
|
||||
entry.Name = tocReader.GetString("FileName");
|
||||
entry.Length = tocReader.GetUInt32("FileSize");
|
||||
entry.Position = (long)tocReader.GetUInt64("FileOffset");
|
||||
entry.Index = tocReader.GetUInt32("ID");
|
||||
entry.Id = tocReader.GetUInt32("ID");
|
||||
entry.Comment = tocReader.GetString("UserString");
|
||||
|
||||
if (entry.Length != tocReader.GetUInt32("ExtractSize"))
|
||||
@ -67,17 +150,398 @@ namespace SonicAudioLib.Archive
|
||||
entry.Position++;
|
||||
}
|
||||
|
||||
etocReader.MoveToRow(tocReader.CurrentRow);
|
||||
entry.UpdateDateTime = DateTimeFromCpkDateTime(etocReader.GetUInt64("UpdateDateTime"));
|
||||
|
||||
entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
using (CriTableReader itocReader = CriCpkSection.Open(source, itocPosition))
|
||||
{
|
||||
while (itocReader.Read())
|
||||
{
|
||||
entries[itocReader.GetInt32("TocIndex")].Id = (uint)itocReader.GetInt32("ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (mode == CriCpkMode.Id)
|
||||
{
|
||||
long currentPosition = contentPosition;
|
||||
|
||||
using (CriTableReader itocReader = CriCpkSection.Open(source, itocPosition))
|
||||
{
|
||||
while (itocReader.Read())
|
||||
{
|
||||
if (itocReader.GetUInt32("FilesL") > 0)
|
||||
{
|
||||
using (CriTableReader dataReader = itocReader.GetCriTableReader("DataL"))
|
||||
{
|
||||
while (dataReader.Read())
|
||||
{
|
||||
CriCpkEntry entry = new CriCpkEntry();
|
||||
entry.Id = dataReader.GetUInt16("ID");
|
||||
entry.Length = dataReader.GetUInt16("FileSize");
|
||||
|
||||
if (entry.Length != dataReader.GetUInt16("ExtractSize"))
|
||||
{
|
||||
entry.IsCompressed = true;
|
||||
}
|
||||
|
||||
while ((currentPosition % align) != 0)
|
||||
{
|
||||
currentPosition++;
|
||||
}
|
||||
|
||||
entry.Position = currentPosition;
|
||||
entries.Add(entry);
|
||||
|
||||
Console.WriteLine(Path.Combine(entry.DirectoryName, entry.Name));
|
||||
currentPosition += entry.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itocReader.GetUInt32("FilesH") > 0)
|
||||
{
|
||||
using (CriTableReader dataReader = itocReader.GetCriTableReader("DataH"))
|
||||
{
|
||||
while (dataReader.Read())
|
||||
{
|
||||
CriCpkEntry entry = new CriCpkEntry();
|
||||
entry.Id = dataReader.GetUInt16("ID");
|
||||
entry.Length = dataReader.GetUInt32("FileSize");
|
||||
|
||||
if (entry.Length != dataReader.GetUInt32("ExtractSize"))
|
||||
{
|
||||
entry.IsCompressed = true;
|
||||
}
|
||||
|
||||
while ((currentPosition % align) != 0)
|
||||
{
|
||||
currentPosition++;
|
||||
}
|
||||
|
||||
entry.Position = currentPosition;
|
||||
entries.Add(entry);
|
||||
|
||||
currentPosition += entry.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw new Exception($"This CPK mode ({mode}) needs to be implemented. Please report this error with the file.");
|
||||
}
|
||||
|
||||
Comment = reader.GetString("Comment");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(Stream destination)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// FIXME: Alignment support (ugh same thing for AFS2 archives)
|
||||
VldPool vldPool = new VldPool();
|
||||
|
||||
using (CriCpkSection cpkSection = new CriCpkSection(destination, "CPK "))
|
||||
{
|
||||
cpkSection.Writer.WriteStartTable("CpkHeader");
|
||||
|
||||
cpkSection.Writer.WriteField("UpdateDateTime", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("FileSize", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("ContentOffset", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("ContentSize", typeof(ulong));
|
||||
|
||||
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
cpkSection.Writer.WriteField("TocOffset", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("TocSize", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("TocCrc", typeof(uint), null);
|
||||
cpkSection.Writer.WriteField("EtocOffset", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("EtocSize", typeof(ulong));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
cpkSection.Writer.WriteField("TocOffset", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("TocSize", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("TocCrc", typeof(uint), null);
|
||||
cpkSection.Writer.WriteField("EtocOffset", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("EtocSize", typeof(ulong), null);
|
||||
}
|
||||
|
||||
if (mode == CriCpkMode.Id || mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
cpkSection.Writer.WriteField("ItocOffset", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("ItocSize", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
cpkSection.Writer.WriteField("ItocOffset", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("ItocSize", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null);
|
||||
}
|
||||
|
||||
cpkSection.Writer.WriteField("GtocOffset", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("GtocSize", typeof(ulong), null);
|
||||
cpkSection.Writer.WriteField("GtocCrc", typeof(uint), null);
|
||||
|
||||
cpkSection.Writer.WriteField("EnabledPackedSize", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("EnabledDataSize", typeof(ulong));
|
||||
cpkSection.Writer.WriteField("TotalDataSize", typeof(ulong), null);
|
||||
|
||||
cpkSection.Writer.WriteField("Tocs", typeof(uint), null);
|
||||
cpkSection.Writer.WriteField("Files", typeof(uint));
|
||||
cpkSection.Writer.WriteField("Groups", typeof(uint));
|
||||
cpkSection.Writer.WriteField("Attrs", typeof(uint));
|
||||
cpkSection.Writer.WriteField("TotalFiles", typeof(uint), null);
|
||||
cpkSection.Writer.WriteField("Directories", typeof(uint), null);
|
||||
cpkSection.Writer.WriteField("Updates", typeof(uint), null);
|
||||
|
||||
cpkSection.Writer.WriteField("Version", typeof(ushort));
|
||||
cpkSection.Writer.WriteField("Revision", typeof(ushort));
|
||||
cpkSection.Writer.WriteField("Align", typeof(ushort));
|
||||
cpkSection.Writer.WriteField("Sorted", typeof(ushort));
|
||||
cpkSection.Writer.WriteField("EID", typeof(ushort), null);
|
||||
|
||||
cpkSection.Writer.WriteField("CpkMode", typeof(uint));
|
||||
cpkSection.Writer.WriteField("Tvers", typeof(string));
|
||||
|
||||
if (!string.IsNullOrEmpty(Comment))
|
||||
{
|
||||
cpkSection.Writer.WriteField("Comment", typeof(string));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
cpkSection.Writer.WriteField("Comment", typeof(string), null);
|
||||
}
|
||||
|
||||
cpkSection.Writer.WriteField("Codec", typeof(uint));
|
||||
cpkSection.Writer.WriteField("DpkItoc", typeof(uint));
|
||||
|
||||
MemoryStream tocMemoryStream = null;
|
||||
MemoryStream itocMemoryStream = null;
|
||||
MemoryStream etocMemoryStream = null;
|
||||
|
||||
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
tocMemoryStream = new MemoryStream();
|
||||
etocMemoryStream = new MemoryStream();
|
||||
|
||||
using (CriCpkSection tocSection = new CriCpkSection(tocMemoryStream, "TOC "))
|
||||
using (CriCpkSection etocSection = new CriCpkSection(etocMemoryStream, "ETOC"))
|
||||
{
|
||||
tocSection.Writer.WriteStartTable("CpkTocInfo");
|
||||
|
||||
tocSection.Writer.WriteField("DirName", typeof(string));
|
||||
tocSection.Writer.WriteField("FileName", typeof(string));
|
||||
tocSection.Writer.WriteField("FileSize", typeof(uint));
|
||||
tocSection.Writer.WriteField("ExtractSize", typeof(uint));
|
||||
tocSection.Writer.WriteField("FileOffset", typeof(ulong));
|
||||
tocSection.Writer.WriteField("ID", typeof(uint));
|
||||
tocSection.Writer.WriteField("UserString", typeof(string));
|
||||
|
||||
etocSection.Writer.WriteStartTable("CpkEtocInfo");
|
||||
|
||||
etocSection.Writer.WriteField("UpdateDateTime", typeof(ulong));
|
||||
etocSection.Writer.WriteField("LocalDir", typeof(string));
|
||||
|
||||
foreach (CriCpkEntry entry in entries)
|
||||
{
|
||||
tocSection.Writer.WriteRow(true, entry.DirectoryName, entry.Name, Convert.ToUInt32(entry.Length), Convert.ToUInt32(entry.Length), Convert.ToUInt64(vldPool.Put(entry.FilePath)), entry.Id, entry.Comment);
|
||||
etocSection.Writer.WriteRow(true, CpkDateTimeFromDateTime(entry.UpdateDateTime), entry.DirectoryName);
|
||||
}
|
||||
|
||||
tocSection.Writer.WriteEndTable();
|
||||
etocSection.Writer.WriteEndTable();
|
||||
}
|
||||
|
||||
if (mode == CriCpkMode.FileNameAndId)
|
||||
{
|
||||
itocMemoryStream = new MemoryStream();
|
||||
|
||||
using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC"))
|
||||
{
|
||||
itocSection.Writer.WriteStartTable("CpkExtendId");
|
||||
|
||||
itocSection.Writer.WriteField("ID", typeof(int));
|
||||
itocSection.Writer.WriteField("TocIndex", typeof(int));
|
||||
|
||||
foreach (CriCpkEntry entry in entries)
|
||||
{
|
||||
itocSection.Writer.WriteRow(true, Convert.ToInt32(entry.Id), entries.IndexOf(entry));
|
||||
}
|
||||
|
||||
itocSection.Writer.WriteEndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (mode == CriCpkMode.Id)
|
||||
{
|
||||
itocMemoryStream = new MemoryStream();
|
||||
|
||||
using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC"))
|
||||
{
|
||||
itocSection.Writer.WriteStartTable("CpkItocInfo");
|
||||
|
||||
itocSection.Writer.WriteField("FilesL", typeof(uint));
|
||||
itocSection.Writer.WriteField("FilesH", typeof(uint));
|
||||
itocSection.Writer.WriteField("DataL", typeof(byte[]));
|
||||
itocSection.Writer.WriteField("DataH", typeof(byte[]));
|
||||
|
||||
List<CriCpkEntry> filesL = entries.Where(entry => entry.Length < ushort.MaxValue).ToList();
|
||||
List<CriCpkEntry> filesH = entries.Where(entry => entry.Length > ushort.MaxValue).ToList();
|
||||
|
||||
ushort id = 0;
|
||||
|
||||
itocSection.Writer.WriteStartRow();
|
||||
|
||||
using (MemoryStream dataMemoryStream = new MemoryStream())
|
||||
using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream))
|
||||
{
|
||||
dataWriter.WriteStartTable("CpkItocL");
|
||||
|
||||
dataWriter.WriteField("ID", typeof(ushort));
|
||||
dataWriter.WriteField("FileSize", typeof(ushort));
|
||||
dataWriter.WriteField("ExtractSize", typeof(ushort));
|
||||
|
||||
foreach (CriCpkEntry entry in filesL)
|
||||
{
|
||||
dataWriter.WriteRow(true, id, Convert.ToUInt16(entry.Length), Convert.ToUInt16(entry.Length));
|
||||
vldPool.Put(entry.FilePath);
|
||||
id++;
|
||||
}
|
||||
|
||||
dataWriter.WriteEndTable();
|
||||
|
||||
itocSection.Writer.WriteValue("DataL", dataMemoryStream.ToArray());
|
||||
}
|
||||
|
||||
using (MemoryStream dataMemoryStream = new MemoryStream())
|
||||
using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream))
|
||||
{
|
||||
dataWriter.WriteStartTable("CpkItocH");
|
||||
|
||||
dataWriter.WriteField("ID", typeof(ushort));
|
||||
dataWriter.WriteField("FileSize", typeof(uint));
|
||||
dataWriter.WriteField("ExtractSize", typeof(uint));
|
||||
|
||||
foreach (CriCpkEntry entry in filesH)
|
||||
{
|
||||
dataWriter.WriteRow(true, id, Convert.ToUInt32(entry.Length), Convert.ToUInt32(entry.Length));
|
||||
vldPool.Put(entry.FilePath);
|
||||
id++;
|
||||
}
|
||||
|
||||
dataWriter.WriteEndTable();
|
||||
|
||||
itocSection.Writer.WriteValue("DataH", dataMemoryStream.ToArray());
|
||||
}
|
||||
|
||||
itocSection.Writer.WriteValue("FilesL", (uint)filesL.Count);
|
||||
itocSection.Writer.WriteValue("FilesH", (uint)filesH.Count);
|
||||
itocSection.Writer.WriteEndRow();
|
||||
itocSection.Writer.WriteEndTable();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw new Exception($"This CPK mode ({mode}) isn't implemented yet! Please choose another mode.");
|
||||
}
|
||||
|
||||
cpkSection.Writer.WriteStartRow();
|
||||
cpkSection.Writer.WriteValue("UpdateDateTime", CpkDateTimeFromDateTime(DateTime.Now));
|
||||
|
||||
cpkSection.Writer.WriteValue("ContentOffset", Convert.ToUInt64(2048));
|
||||
cpkSection.Writer.WriteValue("ContentSize", Convert.ToUInt64(vldPool.Length));
|
||||
|
||||
if (tocMemoryStream != null)
|
||||
{
|
||||
cpkSection.Writer.WriteValue("TocOffset", Convert.ToUInt64(2048 + vldPool.Put(tocMemoryStream)));
|
||||
cpkSection.Writer.WriteValue("TocSize", Convert.ToUInt64(tocMemoryStream.Length));
|
||||
}
|
||||
|
||||
if (itocMemoryStream != null)
|
||||
{
|
||||
cpkSection.Writer.WriteValue("ItocOffset", Convert.ToUInt64(2048 + vldPool.Put(itocMemoryStream)));
|
||||
cpkSection.Writer.WriteValue("ItocSize", Convert.ToUInt64(itocMemoryStream.Length));
|
||||
}
|
||||
|
||||
if (etocMemoryStream != null)
|
||||
{
|
||||
cpkSection.Writer.WriteValue("EtocOffset", Convert.ToUInt64(2048 + vldPool.Put(etocMemoryStream)));
|
||||
cpkSection.Writer.WriteValue("EtocSize", Convert.ToUInt64(etocMemoryStream.Length));
|
||||
}
|
||||
|
||||
uint totalDataSize = 0;
|
||||
foreach (CriCpkEntry entry in entries)
|
||||
{
|
||||
totalDataSize += (uint)entry.Length;
|
||||
}
|
||||
|
||||
cpkSection.Writer.WriteValue("EnabledPackedSize", totalDataSize);
|
||||
cpkSection.Writer.WriteValue("EnabledDataSize", totalDataSize);
|
||||
|
||||
cpkSection.Writer.WriteValue("Files", Convert.ToUInt32(entries.Count));
|
||||
|
||||
cpkSection.Writer.WriteValue("Version", (ushort)7);
|
||||
cpkSection.Writer.WriteValue("Revision", (ushort)2);
|
||||
cpkSection.Writer.WriteValue("Align", (ushort)1);
|
||||
cpkSection.Writer.WriteValue("Sorted", (ushort)1);
|
||||
|
||||
cpkSection.Writer.WriteValue("CpkMode", (uint)mode);
|
||||
cpkSection.Writer.WriteValue("Tvers", "SonicAudioLib");
|
||||
cpkSection.Writer.WriteValue("Comment", Comment);
|
||||
|
||||
cpkSection.Writer.WriteValue("FileSize", Convert.ToUInt64(2048 + (ulong)vldPool.Length));
|
||||
|
||||
cpkSection.Writer.WriteEndRow();
|
||||
cpkSection.Writer.WriteEndTable();
|
||||
}
|
||||
|
||||
while ((destination.Position % 2042) != 0)
|
||||
{
|
||||
destination.WriteByte(0);
|
||||
}
|
||||
|
||||
EndianStream.WriteCString(destination, "(c)CRI", 6);
|
||||
|
||||
vldPool.Write(destination);
|
||||
}
|
||||
|
||||
private DateTime DateTimeFromCpkDateTime(ulong dateTime)
|
||||
{
|
||||
if (dateTime == 0)
|
||||
{
|
||||
return new DateTime();
|
||||
}
|
||||
|
||||
return new DateTime(
|
||||
(int)(uint)(dateTime >> 32) >> 16, // year
|
||||
(int)(uint)(dateTime >> 32) >> 8 & byte.MaxValue, // month
|
||||
(int)(uint)(dateTime >> 32) & byte.MaxValue, // day
|
||||
(int)(uint)dateTime >> 24, // hour
|
||||
(int)(uint)dateTime >> 16 & byte.MaxValue, // minute
|
||||
(int)(uint)dateTime >> 8 & byte.MaxValue // second
|
||||
);
|
||||
}
|
||||
|
||||
private ulong CpkDateTimeFromDateTime(DateTime dateTime)
|
||||
{
|
||||
return ((((ulong)dateTime.Year * 0x100 + (uint)dateTime.Month) * 0x100 + (uint)dateTime.Day) * 0x100000000) +
|
||||
((((ulong)dateTime.Hour * 0x100 + (uint)dateTime.Minute) * 0x100 + (uint)dateTime.Second) * 0x100);
|
||||
}
|
||||
|
||||
private class CriCpkSection : IDisposable
|
||||
@ -100,7 +564,7 @@ namespace SonicAudioLib.Archive
|
||||
writer.Dispose();
|
||||
|
||||
long position = destination.Position;
|
||||
uint length = (uint)(position - (headerPosition - 8));
|
||||
uint length = (uint)(position - (headerPosition) - 16);
|
||||
|
||||
destination.Seek(headerPosition + 8, SeekOrigin.Begin);
|
||||
EndianStream.WriteUInt32(destination, length);
|
||||
@ -117,9 +581,17 @@ namespace SonicAudioLib.Archive
|
||||
uint tableLength = EndianStream.ReadUInt32(source);
|
||||
uint unknown = EndianStream.ReadUInt32(source);
|
||||
|
||||
try
|
||||
{
|
||||
return CriTableReader.Create(new Substream(source, source.Position, tableLength));
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
throw new Exception("CPK file decryption needs to be implemented or it's an unknown error. Please report this error with the file.");
|
||||
}
|
||||
}
|
||||
|
||||
public CriCpkSection(Stream destination, string signature)
|
||||
{
|
||||
this.destination = destination;
|
||||
@ -127,9 +599,9 @@ namespace SonicAudioLib.Archive
|
||||
|
||||
EndianStream.WriteCString(destination, signature, 4);
|
||||
EndianStream.WriteUInt32(destination, byte.MaxValue);
|
||||
destination.Seek(8, SeekOrigin.Begin);
|
||||
destination.Seek(8, SeekOrigin.Current);
|
||||
|
||||
writer = CriTableWriter.Create(destination);
|
||||
writer = CriTableWriter.Create(destination, new CriTableWriterSettings() { LeaveOpen = true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,9 +101,23 @@ namespace SonicAudioLib.CriMw
|
||||
writer.WriteStartFieldCollection();
|
||||
foreach (CriField criField in fields)
|
||||
{
|
||||
if (!rows.Any(row => row[criField] != criField.DefaultValue))
|
||||
bool useDefaultValue = false;
|
||||
object defaultValue = null;
|
||||
|
||||
if (rows.Count > 1)
|
||||
{
|
||||
writer.WriteField(criField.FieldName, criField.FieldType, criField.DefaultValue);
|
||||
useDefaultValue = true;
|
||||
defaultValue = rows[0][criField];
|
||||
|
||||
if (rows.Any(row => !row[criField].Equals(defaultValue)))
|
||||
{
|
||||
useDefaultValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (useDefaultValue)
|
||||
{
|
||||
writer.WriteField(criField.FieldName, criField.FieldType, defaultValue);
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -166,14 +166,14 @@ namespace SonicAudioLib.CriMw
|
||||
return fields[fieldIndex].Value;
|
||||
}
|
||||
|
||||
public byte GetFieldFlag(string fieldName)
|
||||
internal CriFieldFlag GetFieldFlag(string fieldName)
|
||||
{
|
||||
return (byte)fields[fieldName].Flag;
|
||||
return fields[fieldName].Flag;
|
||||
}
|
||||
|
||||
public byte GetFieldFlag(int fieldIndex)
|
||||
internal CriFieldFlag GetFieldFlag(int fieldIndex)
|
||||
{
|
||||
return (byte)fields[fieldIndex].Flag;
|
||||
return fields[fieldIndex].Flag;
|
||||
}
|
||||
|
||||
public object GetFieldValue(string fieldName)
|
||||
@ -438,6 +438,16 @@ namespace SonicAudioLib.CriMw
|
||||
return GetData(fields.IndexOf(fieldName));
|
||||
}
|
||||
|
||||
public CriTableReader GetCriTableReader(string fieldName)
|
||||
{
|
||||
return new CriTableReader(GetSubstream(fieldName), false);
|
||||
}
|
||||
|
||||
public CriTableReader GetCriTableReader(int fieldIndex)
|
||||
{
|
||||
return new CriTableReader(GetSubstream(fieldIndex), false);
|
||||
}
|
||||
|
||||
public uint GetLength(int fieldIndex)
|
||||
{
|
||||
if (fieldIndex < 0 || fieldIndex >= fields.Count)
|
||||
@ -583,7 +593,7 @@ namespace SonicAudioLib.CriMw
|
||||
if (strResult == "<NULL>" ||
|
||||
(strResult == header.TableName && stringPosition == 0))
|
||||
{
|
||||
return null;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return strResult;
|
||||
|
@ -28,7 +28,6 @@ namespace SonicAudioLib.CriMw
|
||||
private VldPool vldPool;
|
||||
private StringPool stringPool;
|
||||
private uint headerPosition;
|
||||
private uint endPosition;
|
||||
|
||||
private Status status = Status.Begin;
|
||||
|
||||
@ -115,6 +114,8 @@ namespace SonicAudioLib.CriMw
|
||||
destination.WriteByte(0);
|
||||
}
|
||||
|
||||
long previousPosition = destination.Position;
|
||||
|
||||
header.Length = (uint)destination.Position - headerPosition;
|
||||
|
||||
header.FirstBoolean = false;
|
||||
@ -131,7 +132,7 @@ namespace SonicAudioLib.CriMw
|
||||
WriteUInt16(header.NumberOfFields);
|
||||
WriteUInt16(header.RowLength);
|
||||
WriteUInt32(header.NumberOfRows);
|
||||
destination.Seek(0, SeekOrigin.End);
|
||||
destination.Seek(previousPosition, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public void WriteStartFieldCollection()
|
||||
@ -269,7 +270,7 @@ namespace SonicAudioLib.CriMw
|
||||
|
||||
public void WriteValue(string fieldName, object rowValue)
|
||||
{
|
||||
WriteValue(fields.IndexOf(fieldName));
|
||||
WriteValue(fields.IndexOf(fieldName), rowValue);
|
||||
}
|
||||
|
||||
private void GoToValue(int fieldIndex)
|
||||
@ -654,7 +655,7 @@ namespace SonicAudioLib.CriMw
|
||||
|
||||
set
|
||||
{
|
||||
leaveOpen = true;
|
||||
leaveOpen = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,7 +691,7 @@ namespace SonicAudioLib.CriMw
|
||||
{
|
||||
return new CriTableWriterSettings()
|
||||
{
|
||||
Align = 4,
|
||||
Align = 8,
|
||||
PutBlankString = true,
|
||||
RemoveDuplicateStrings = true,
|
||||
};
|
||||
|
@ -14,6 +14,28 @@ namespace SonicAudioLib.CriMw.Serialization
|
||||
{
|
||||
public static class CriTableSerializer
|
||||
{
|
||||
public static byte[] Serialize<T>(List<T> objects, CriTableWriterSettings settings)
|
||||
{
|
||||
using (MemoryStream destination = new MemoryStream())
|
||||
{
|
||||
Serialize(destination, objects, settings);
|
||||
return destination.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Serialize<T>(string destinationFileName, List<T> objects, CriTableWriterSettings settings)
|
||||
{
|
||||
using (Stream destination = File.Create(destinationFileName))
|
||||
{
|
||||
Serialize(destination, objects, settings);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Serialize<T>(Stream destination, List<T> objects, CriTableWriterSettings settings)
|
||||
{
|
||||
Serialize(destination, typeof(T), objects, settings);
|
||||
}
|
||||
|
||||
public static void Serialize(Stream destination, Type type, ICollection objects, CriTableWriterSettings settings)
|
||||
{
|
||||
ArrayList arrayList = null;
|
||||
@ -45,7 +67,7 @@ namespace SonicAudioLib.CriMw.Serialization
|
||||
continue;
|
||||
}
|
||||
|
||||
// Also ignore the properties that are not supportable (except FileInfo, Stream and ICollection<>)
|
||||
// Also ignore the properties that are not supportable (except FileInfo and Stream)
|
||||
if (propertyInfo.PropertyType != typeof(FileInfo) &&
|
||||
propertyInfo.PropertyType != typeof(Stream) &&
|
||||
!CriField.FieldTypes.Contains(propertyInfo.PropertyType))
|
||||
@ -94,25 +116,32 @@ namespace SonicAudioLib.CriMw.Serialization
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if all the rows have the same value for this field
|
||||
bool useDefaultValue = true;
|
||||
bool useDefaultValue = false;
|
||||
|
||||
if (arrayList != null && arrayList.Count > 0)
|
||||
if (arrayList != null && arrayList.Count > 1)
|
||||
{
|
||||
useDefaultValue = true;
|
||||
|
||||
foreach (object obj in arrayList)
|
||||
defaultValue = propertyInfo.GetValue(arrayList[0]);
|
||||
|
||||
for (int i = 1; i < arrayList.Count; i++)
|
||||
{
|
||||
if (propertyInfo.GetValue(obj) != propertyInfo.GetValue(arrayList[0]))
|
||||
object objectValue = propertyInfo.GetValue(arrayList[i]);
|
||||
if (defaultValue != null)
|
||||
{
|
||||
if (!defaultValue.Equals(objectValue))
|
||||
{
|
||||
useDefaultValue = false;
|
||||
defaultValue = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (useDefaultValue)
|
||||
else if (objectValue != null)
|
||||
{
|
||||
defaultValue = propertyInfo.GetValue(arrayList[0]);
|
||||
useDefaultValue = false;
|
||||
defaultValue = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,6 +184,37 @@ namespace SonicAudioLib.CriMw.Serialization
|
||||
tableWriter.Dispose();
|
||||
}
|
||||
|
||||
public static List<T> Deserialize<T>(byte[] sourceByteArray)
|
||||
{
|
||||
return Deserialize(sourceByteArray, typeof(T)).OfType<T>().ToList();
|
||||
}
|
||||
|
||||
public static List<T> Deserialize<T>(string sourceFileName)
|
||||
{
|
||||
return Deserialize(sourceFileName, typeof(T)).OfType<T>().ToList();
|
||||
}
|
||||
|
||||
public static List<T> Deserialize<T>(Stream source)
|
||||
{
|
||||
return Deserialize(source, typeof(T)).OfType<T>().ToList();
|
||||
}
|
||||
|
||||
public static ArrayList Deserialize(byte[] sourceByteArray, Type type)
|
||||
{
|
||||
using (MemoryStream source = new MemoryStream(sourceByteArray))
|
||||
{
|
||||
return Deserialize(source, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList Deserialize(string sourceFileName, Type type)
|
||||
{
|
||||
using (Stream source = File.OpenRead(sourceFileName))
|
||||
{
|
||||
return Deserialize(source, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList Deserialize(Stream source, Type type)
|
||||
{
|
||||
ArrayList arrayList = new ArrayList();
|
||||
@ -185,6 +245,11 @@ namespace SonicAudioLib.CriMw.Serialization
|
||||
if (fieldName == fieldNameMatch)
|
||||
{
|
||||
object value = tableReader.GetValue(i);
|
||||
if (propertyInfo.PropertyType == typeof(byte[]) && value is Substream)
|
||||
{
|
||||
value = ((Substream)value).ToArray();
|
||||
}
|
||||
|
||||
propertyInfo.SetValue(obj, value);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user