mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2024-11-24 07:00:11 +01:00
Add UTF-8 support for UTF tables
This commit is contained in:
parent
b4598ad8f6
commit
8b2333eecf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -75,18 +75,21 @@ namespace CsbEditor
|
|||||||
{
|
{
|
||||||
CriCpkEntry cpkEntry = cpkArchive.GetByPath(sdlName);
|
CriCpkEntry cpkEntry = cpkArchive.GetByPath(sdlName);
|
||||||
|
|
||||||
using (Stream cpkSource = File.OpenRead(cpkPath))
|
if (cpkEntry != null)
|
||||||
using (Stream aaxSource = cpkEntry.Open(cpkSource))
|
|
||||||
{
|
{
|
||||||
aaxArchive.Read(aaxSource);
|
using (Stream cpkSource = File.OpenRead(cpkPath))
|
||||||
|
using (Stream aaxSource = cpkEntry.Open(cpkSource))
|
||||||
foreach (CriAaxEntry entry in aaxArchive)
|
|
||||||
{
|
{
|
||||||
using (Stream destination = File.Create(Path.Combine(destinationPath.FullName,
|
aaxArchive.Read(aaxSource);
|
||||||
entry.Flag == CriAaxEntryFlag.Intro ? "Intro.adx" : "Loop.adx")))
|
|
||||||
using (Stream entrySource = entry.Open(aaxSource))
|
foreach (CriAaxEntry entry in aaxArchive)
|
||||||
{
|
{
|
||||||
entrySource.CopyTo(destination);
|
using (Stream destination = File.Create(Path.Combine(destinationPath.FullName,
|
||||||
|
entry.Flag == CriAaxEntryFlag.Intro ? "Intro.adx" : "Loop.adx")))
|
||||||
|
using (Stream entrySource = entry.Open(aaxSource))
|
||||||
|
{
|
||||||
|
entrySource.CopyTo(destination);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,20 @@ namespace SonicAudioLib.Archive
|
|||||||
|
|
||||||
public CriCpkEntry GetByPath(string path)
|
public CriCpkEntry GetByPath(string path)
|
||||||
{
|
{
|
||||||
return entries.FirstOrDefault(entry => ((entry.DirectoryName + "/" + entry.Name) == path));
|
string correctedPath = path.Replace('\\', '/');
|
||||||
|
|
||||||
|
return entries.FirstOrDefault(entry =>
|
||||||
|
{
|
||||||
|
string search = string.Empty;
|
||||||
|
if (!string.IsNullOrEmpty(entry.DirectoryName))
|
||||||
|
{
|
||||||
|
search += $"{entry.DirectoryName.Replace('\\', '/')}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
search += entry.Name;
|
||||||
|
|
||||||
|
return search == correctedPath;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime DateTimeFromCpkDateTime(ulong dateTime)
|
private DateTime DateTimeFromCpkDateTime(ulong dateTime)
|
||||||
|
@ -4,10 +4,13 @@ namespace SonicAudioLib.CriMw
|
|||||||
{
|
{
|
||||||
struct CriTableHeader
|
struct CriTableHeader
|
||||||
{
|
{
|
||||||
public static readonly string Signature = "@UTF";
|
public const string Signature = "@UTF";
|
||||||
|
public const byte EncodingTypeShiftJis = 0;
|
||||||
|
public const byte EncodingTypeUtf8 = 1;
|
||||||
|
|
||||||
public uint Length { get; set; }
|
public uint Length { get; set; }
|
||||||
public bool FirstBoolean { get; set; }
|
public byte UnknownByte { get; set; }
|
||||||
public bool SecondBoolean { get; set; }
|
public byte EncodingType { get; set; }
|
||||||
public ushort RowsPosition { get; set; }
|
public ushort RowsPosition { get; set; }
|
||||||
public uint StringPoolPosition { get; set; }
|
public uint StringPoolPosition { get; set; }
|
||||||
public uint DataPoolPosition { get; set; }
|
public uint DataPoolPosition { get; set; }
|
||||||
@ -18,7 +21,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
enum CriFieldFlag
|
enum CriFieldFlag : byte
|
||||||
{
|
{
|
||||||
Name = 16,
|
Name = 16,
|
||||||
DefaultValue = 32,
|
DefaultValue = 32,
|
||||||
|
@ -12,7 +12,8 @@ namespace SonicAudioLib.CriMw
|
|||||||
private List<CriTableField> fields;
|
private List<CriTableField> fields;
|
||||||
private Stream source;
|
private Stream source;
|
||||||
private CriTableHeader header;
|
private CriTableHeader header;
|
||||||
private int rowIndex = -1;
|
private Encoding encoding;
|
||||||
|
private long rowIndex = -1;
|
||||||
private uint headerPosition;
|
private uint headerPosition;
|
||||||
private bool leaveOpen;
|
private bool leaveOpen;
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CurrentRow
|
public long CurrentRow
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -72,6 +73,14 @@ namespace SonicAudioLib.CriMw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Encoding EncodingType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadTable()
|
private void ReadTable()
|
||||||
{
|
{
|
||||||
headerPosition = (uint)source.Position;
|
headerPosition = (uint)source.Position;
|
||||||
@ -102,8 +111,29 @@ namespace SonicAudioLib.CriMw
|
|||||||
}
|
}
|
||||||
|
|
||||||
header.Length = ReadUInt32() + 0x8;
|
header.Length = ReadUInt32() + 0x8;
|
||||||
header.FirstBoolean = ReadBoolean();
|
header.UnknownByte = ReadByte();
|
||||||
header.SecondBoolean = ReadBoolean();
|
header.EncodingType = ReadByte();
|
||||||
|
|
||||||
|
if (header.UnknownByte != 0)
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid byte ({header.UnknownByte}. Please report the error with the file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This actually might be a boolean telling the reader that it's using UTF-8 encoding, but idk
|
||||||
|
switch (header.EncodingType)
|
||||||
|
{
|
||||||
|
case CriTableHeader.EncodingTypeShiftJis:
|
||||||
|
encoding = Encoding.GetEncoding("shift-jis");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CriTableHeader.EncodingTypeUtf8:
|
||||||
|
encoding = Encoding.UTF8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Exception($"Unknown encoding type ({header.EncodingType}). Please report the error with the file.");
|
||||||
|
}
|
||||||
|
|
||||||
header.RowsPosition = (ushort)(ReadUInt16() + 0x8);
|
header.RowsPosition = (ushort)(ReadUInt16() + 0x8);
|
||||||
header.StringPoolPosition = ReadUInt32() + 0x8;
|
header.StringPoolPosition = ReadUInt32() + 0x8;
|
||||||
header.DataPoolPosition = ReadUInt32() + 0x8;
|
header.DataPoolPosition = ReadUInt32() + 0x8;
|
||||||
@ -112,11 +142,6 @@ namespace SonicAudioLib.CriMw
|
|||||||
header.RowLength = ReadUInt16();
|
header.RowLength = ReadUInt16();
|
||||||
header.NumberOfRows = ReadUInt32();
|
header.NumberOfRows = ReadUInt32();
|
||||||
|
|
||||||
if (header.FirstBoolean)
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid boolean ({header.FirstBoolean}. Please report the error with the file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ushort i = 0; i < header.NumberOfFields; i++)
|
for (ushort i = 0; i < header.NumberOfFields; i++)
|
||||||
{
|
{
|
||||||
CriTableField field = new CriTableField();
|
CriTableField field = new CriTableField();
|
||||||
@ -271,7 +296,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveToRow(int rowIndex)
|
public bool MoveToRow(long rowIndex)
|
||||||
{
|
{
|
||||||
if (rowIndex >= header.NumberOfRows)
|
if (rowIndex >= header.NumberOfRows)
|
||||||
{
|
{
|
||||||
@ -617,7 +642,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
long previousPosition = source.Position;
|
long previousPosition = source.Position;
|
||||||
|
|
||||||
source.Position = headerPosition + header.StringPoolPosition + stringPosition;
|
source.Position = headerPosition + header.StringPoolPosition + stringPosition;
|
||||||
string strResult = EndianStream.ReadCString(source, Encoding.GetEncoding("shift-jis"));
|
string strResult = EndianStream.ReadCString(source, encoding);
|
||||||
source.Position = previousPosition;
|
source.Position = previousPosition;
|
||||||
|
|
||||||
if (strResult == "<NULL>" ||
|
if (strResult == "<NULL>" ||
|
||||||
@ -675,12 +700,12 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
ReadData(out vldPosition, out vldLength);
|
ReadData(out vldPosition, out vldLength);
|
||||||
|
|
||||||
// SecondBoolean being true, check if utf table
|
// Some ACB files have the length info set to zero for UTF table fields, so find the correct length
|
||||||
if (vldPosition > 0 && vldLength == 0)
|
if (vldPosition > 0 && vldLength == 0)
|
||||||
{
|
{
|
||||||
source.Position = headerPosition + header.DataPoolPosition + vldPosition;
|
source.Position = headerPosition + header.DataPoolPosition + vldPosition;
|
||||||
|
|
||||||
if (Encoding.ASCII.GetString(ReadBytes(4)) == "@UTF")
|
if (EndianStream.ReadCString(source, 4) == "@UTF")
|
||||||
{
|
{
|
||||||
vldLength = ReadUInt32() + 8;
|
vldLength = ReadUInt32() + 8;
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,8 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
EndianStream.WriteCString(destination, CriTableHeader.Signature, 4);
|
EndianStream.WriteCString(destination, CriTableHeader.Signature, 4);
|
||||||
WriteUInt32(uint.MinValue);
|
WriteUInt32(uint.MinValue);
|
||||||
WriteBoolean(false);
|
WriteByte(byte.MinValue);
|
||||||
WriteBoolean(false);
|
WriteByte(byte.MinValue);
|
||||||
WriteUInt16(ushort.MinValue);
|
WriteUInt16(ushort.MinValue);
|
||||||
WriteUInt32(uint.MinValue);
|
WriteUInt32(uint.MinValue);
|
||||||
WriteUInt32(uint.MinValue);
|
WriteUInt32(uint.MinValue);
|
||||||
@ -112,13 +112,20 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
header.Length = (uint)destination.Position - headerPosition;
|
header.Length = (uint)destination.Position - headerPosition;
|
||||||
|
|
||||||
header.FirstBoolean = false;
|
if (settings.EncodingType == Encoding.GetEncoding("shift-jis"))
|
||||||
header.SecondBoolean = false;
|
{
|
||||||
|
header.EncodingType = CriTableHeader.EncodingTypeShiftJis;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (settings.EncodingType == Encoding.UTF8)
|
||||||
|
{
|
||||||
|
header.EncodingType = CriTableHeader.EncodingTypeUtf8;
|
||||||
|
}
|
||||||
|
|
||||||
destination.Position = headerPosition + 4;
|
destination.Position = headerPosition + 4;
|
||||||
WriteUInt32(header.Length - 8);
|
WriteUInt32(header.Length - 8);
|
||||||
WriteBoolean(header.FirstBoolean);
|
WriteByte(header.UnknownByte);
|
||||||
WriteBoolean(header.SecondBoolean);
|
WriteByte(header.EncodingType);
|
||||||
WriteUInt16((ushort)(header.RowsPosition - 8));
|
WriteUInt16((ushort)(header.RowsPosition - 8));
|
||||||
WriteUInt32(header.StringPoolPosition - 8);
|
WriteUInt32(header.StringPoolPosition - 8);
|
||||||
WriteUInt32(header.DataPoolPosition - 8);
|
WriteUInt32(header.DataPoolPosition - 8);
|
||||||
@ -670,6 +677,11 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (value != Encoding.UTF8 || value != Encoding.GetEncoding("shift-jis"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
encodingType = value;
|
encodingType = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,16 @@ namespace SonicAudioLib.IO
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] ReadBytesAt(Stream source, int length, long position)
|
||||||
|
{
|
||||||
|
long oldPosition = source.Position;
|
||||||
|
source.Position = position;
|
||||||
|
FillBuffer(source, length);
|
||||||
|
source.Position = oldPosition;
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
public static void WriteBytes(Stream destination, byte[] value)
|
public static void WriteBytes(Stream destination, byte[] value)
|
||||||
{
|
{
|
||||||
destination.Write(value, 0, value.Length);
|
destination.Write(value, 0, value.Length);
|
||||||
|
Loading…
Reference in New Issue
Block a user