Support for Sonic Forces

This commit is contained in:
Skyth 2017-09-17 13:02:44 +03:00
parent 218f1b8f37
commit 86a218f630
7 changed files with 299 additions and 326 deletions

Binary file not shown.

View File

@ -99,9 +99,28 @@ namespace AcbEditor
cpkMode = false; cpkMode = false;
using (SubStream extAfs2Stream = acbReader.GetSubStream("StreamAwbAfs2Header")) using (SubStream extAfs2Stream = acbReader.GetSubStream("StreamAwbAfs2Header"))
{
bool utfMode = DataStream.ReadCString(extAfs2Stream, 4) == "@UTF";
extAfs2Stream.Seek(0, SeekOrigin.Begin);
if (utfMode)
{
using (CriTableReader utfAfs2HeaderReader = CriTableReader.Create(extAfs2Stream))
{
utfAfs2HeaderReader.Read();
using (SubStream extAfs2HeaderStream = utfAfs2HeaderReader.GetSubStream("Header"))
{
extAfs2Archive.Read(extAfs2HeaderStream);
}
}
}
else
{ {
extAfs2Archive.Read(extAfs2Stream); extAfs2Archive.Read(extAfs2Stream);
} }
}
if (!found) if (!found)
{ {
@ -303,9 +322,23 @@ namespace AcbEditor
else else
{ {
extAfs2Archive.Save(awbPath, Settings.Default.BufferSize); extAfs2Archive.Save(awbPath, Settings.Default.BufferSize);
if (Encoding.UTF8.GetString(streamAwbAfs2Header, 0, 4) == "@UTF")
{
CriTable headerTable = new CriTable();
headerTable.Load(streamAwbAfs2Header);
headerTable.Rows[0]["Header"] = extAfs2Archive.Header;
headerTable.WriterSettings = CriTableWriterSettings.Adx2Settings;
acbFile.Rows[0]["StreamAwbAfs2Header"] = headerTable.Save();
}
else
{
acbFile.Rows[0]["StreamAwbAfs2Header"] = extAfs2Archive.Header; acbFile.Rows[0]["StreamAwbAfs2Header"] = extAfs2Archive.Header;
} }
} }
}
acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings; acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings;
acbFile.Save(acbPath, Settings.Default.BufferSize); acbFile.Save(acbPath, Settings.Default.BufferSize);

View File

@ -17,16 +17,6 @@ namespace CsbBuilder.Audio
/// </summary> /// </summary>
public const string DllName = "vgmstream.dll"; public const string DllName = "vgmstream.dll";
/// <summary>
/// Size of VGMSTREAM structure.
/// </summary>
public const int SizeOfVgmStream = 152;
/// <summary>
/// Size of VGMSTREAMCHANNEL structure.
/// </summary>
public const int SizeOfVgmStreamChannel = 552;
#region VGMStream Exports #region VGMStream Exports
/// <summary> /// <summary>
/// Initializes a VGMSTREAM from source file name by doing format detection and returns a usable pointer /// Initializes a VGMSTREAM from source file name by doing format detection and returns a usable pointer
@ -165,14 +155,7 @@ namespace CsbBuilder.Audio
/// Gets a pointer to the array of supported formats. /// Gets a pointer to the array of supported formats.
/// </summary> /// </summary>
[DllImport(DllName, EntryPoint = "vgmstream_get_formats", CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, EntryPoint = "vgmstream_get_formats", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetFormatsPtr(); public static extern IntPtr GetFormatsPtr(out int count);
/// <summary>
/// Gets the length of the format array.
/// </summary>
/// <returns></returns>
[DllImport(DllName, EntryPoint = "vgmstream_get_formats_length", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetFormatsLength();
[DllImport(DllName, EntryPoint = "get_vgmstream_coding_description", CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, EntryPoint = "get_vgmstream_coding_description", CallingConvention = CallingConvention.Cdecl)]
public static extern string GetCodingDescription(int codingEnumCode); public static extern string GetCodingDescription(int codingEnumCode);
@ -189,28 +172,22 @@ namespace CsbBuilder.Audio
/// Gets the sample count of a VGMSTREAM. /// Gets the sample count of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetSampleCount(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_sample_count", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetSampleCount(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream);
}
/// <summary> /// <summary>
/// Gets the sample rate of a VGMSTREAM. /// Gets the sample rate of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetSampleRate(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_sample_rate", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetSampleRate(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 4);
}
/// <summary> /// <summary>
/// Gets the channel count of a VGMSTREAM. /// Gets the channel count of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetChannelCount(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_channels", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetChannelCount(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 8);
}
/// <summary> /// <summary>
/// Gets the absolute sample count of a VGMSTREAM. /// Gets the absolute sample count of a VGMSTREAM.
@ -226,69 +203,50 @@ namespace CsbBuilder.Audio
/// Gets the loop flag of a VGMSTREAM. /// Gets the loop flag of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static bool GetLoopFlag(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_loop_flag", CallingConvention = CallingConvention.Cdecl)]
{ public static extern bool GetLoopFlag(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 28) != 0;
}
/// <summary> /// <summary>
/// Sets the loop flag of a VGMSTREAM. /// Sets the loop flag of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static void SetLoopFlag(IntPtr vgmstream, bool value) [DllImport(DllName, EntryPoint = "set_vgmstream_loop_flag", CallingConvention = CallingConvention.Cdecl)]
{ public static extern void SetLoopFlag(IntPtr vgmstream, bool value);
if (value && !GetLoopFlag(vgmstream))
{
Marshal.WriteIntPtr(vgmstream, 48, Marshal.AllocHGlobal(GetChannelCount(vgmstream) * SizeOfVgmStreamChannel));
}
Marshal.WriteInt32(vgmstream, 28, value ? 1 : 0);
}
/// <summary> /// <summary>
/// Gets the loop start sample of a VGMSTREAM. /// Gets the loop start sample of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetLoopStartSample(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_loop_start_sample", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetLoopStartSample(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 32);
}
/// <summary> /// <summary>
/// Sets the loop start sample of a VGMSTREAM. /// Sets the loop start sample of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static void SetLoopStartSample(IntPtr vgmstream, int value) [DllImport(DllName, EntryPoint = "set_vgmstream_loop_start_sample", CallingConvention = CallingConvention.Cdecl)]
{ public static extern void SetLoopStartSample(IntPtr vgmstream, int value);
Marshal.WriteInt32(vgmstream, 32, value);
}
/// <summary> /// <summary>
/// Gets the loop end sample of a VGMSTREAM. /// Gets the loop end sample of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetLoopEndSample(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_loop_end_sample", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetLoopEndSample(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 36);
}
/// <summary> /// <summary>
/// Sets the loop end sample of a VGMSTREAM. /// Sets the loop end sample of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static void SetLoopEndSample(IntPtr vgmstream, int value) [DllImport(DllName, EntryPoint = "set_vgmstream_loop_end_sample", CallingConvention = CallingConvention.Cdecl)]
{ public static extern void SetLoopEndSample(IntPtr vgmstream, int value);
Marshal.WriteInt32(vgmstream, 36, value);
}
/// <summary> /// <summary>
/// Gets the current sample of a VGMSTREAM. /// Gets the current sample of a VGMSTREAM.
/// </summary> /// </summary>
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static int GetCurrentSample(IntPtr vgmstream) [DllImport(DllName, EntryPoint = "get_vgmstream_current_sample", CallingConvention = CallingConvention.Cdecl)]
{ public static extern int GetCurrentSample(IntPtr vgmstream);
return Marshal.ReadInt32(vgmstream, 52);
}
/// <summary> /// <summary>
/// Gets an array of supported formats. /// Gets an array of supported formats.
@ -296,9 +254,9 @@ namespace CsbBuilder.Audio
/// <param name="vgmstream">Pointer to VGMSTREAM.</param> /// <param name="vgmstream">Pointer to VGMSTREAM.</param>
public static string[] GetFormats() public static string[] GetFormats()
{ {
string[] formats = new string[GetFormatsLength()]; IntPtr ptr = GetFormatsPtr(out int count);
string[] formats = new string[count];
IntPtr ptr = GetFormatsPtr();
for (int i = 0; i < formats.Length; i++) for (int i = 0; i < formats.Length; i++)
{ {
IntPtr stringPtr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size); IntPtr stringPtr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size);

View File

@ -47,7 +47,11 @@ namespace CsbBuilder
private static void OnException(object sender, ThreadExceptionEventArgs e) private static void OnException(object sender, ThreadExceptionEventArgs e)
{ {
new ExceptionForm(e.Exception).ShowDialog(); new ExceptionForm(e.Exception).ShowDialog();
if (MessageBox.Show("Do you want to continue?", "CSB Builder", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.OK)
{
Application.Exit(); Application.Exit();
} }
} }
} }
}

View File

@ -21,26 +21,6 @@ namespace SonicAudioCmd
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
using (Stream source = File.OpenRead(args[0]))
{
CriTableReader reader = CriTableReader.Create(source);
reader.MoveToRow(3);
long pos = reader.GetPosition("utf");
CriTableReader soundElementReader = reader.GetTableReader("utf");
while (soundElementReader.Read())
{
CriTable table = new CriTable();
table.Read(soundElementReader.GetSubStream("data"));
using (Stream output = File.Create(Path.GetFileName(soundElementReader.GetString("name") + "_" + table.Rows[0].GetValue<byte>("lpflg") + "_" + ".dsp")))
{
DataStream.WriteBytes(output, table.Rows[0].GetValue<byte[]>("header"));
DataStream.WriteBytes(output, table.Rows[0].GetValue<byte[]>("data"));
}
}
}
} }
} }
} }

View File

@ -1,8 +1,10 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
namespace SonicAudioLib.CriMw namespace SonicAudioLib.CriMw
{ {
[StructLayout(LayoutKind.Sequential)]
struct CriTableHeader struct CriTableHeader
{ {
public static readonly byte[] SignatureBytes = { 0x40, 0x55, 0x54, 0x46 }; public static readonly byte[] SignatureBytes = { 0x40, 0x55, 0x54, 0x46 };
@ -48,13 +50,14 @@ namespace SonicAudioLib.CriMw
TypeMask = 15, TypeMask = 15,
}; };
[StructLayout(LayoutKind.Sequential)]
struct CriTableField struct CriTableField
{ {
public uint Offset;
public CriFieldFlag Flag; public CriFieldFlag Flag;
public string Name; public string Name;
public uint Position; public uint Position;
public uint Length; public uint Length;
public uint Offset;
public object Value; public object Value;
} }

View File

@ -517,15 +517,10 @@ namespace SonicAudioLib.IO
public static void Pad(Stream destination, long alignment) public static void Pad(Stream destination, long alignment)
{ {
long value = destination.Position; while (destination.Position % alignment != 0)
while ((value % alignment) != 0)
{ {
value++; WriteByte(destination, 0);
} }
byte[] buffer = new byte[value - destination.Position];
destination.Write(buffer, 0, buffer.Length);
} }
} }
} }