diff --git a/Tools/lib-novalogic/PFF/PffArchive.cs b/Tools/lib-novalogic/PFF/PffArchive.cs index 49604ba..d6f9f3e 100644 --- a/Tools/lib-novalogic/PFF/PffArchive.cs +++ b/Tools/lib-novalogic/PFF/PffArchive.cs @@ -11,7 +11,7 @@ namespace Novalogic.PFF public class PffArchive : IDisposable { private readonly BinaryReader _bReader; - private readonly Header_Pff3_20 _header; + private readonly IPffHeaderAbstract _header; private List _cachedEntries; private PffArchive(FileInfo fileInfo) @@ -29,7 +29,8 @@ private PffArchive(FileInfo fileInfo) else if (version == PffVersion.PFF2 && headerSize == 20) _header = reader.ReadBytes(20).ToStruct(); - + else if (version == PffVersion.PFF4 && headerSize == 20) + _header = reader.ReadBytes(20).ToStruct(); else throw new NotImplementedException(); } @@ -105,6 +106,16 @@ private IEnumerable EnumerateDirectory() else throw new NotImplementedException(); } + else if (_header.Signature == PffVersion.PFF4) + { + if (_header.RecordSize == 36) + { + var entry = _bReader.ReadBytes(36).ToStruct(); + pffEntry = new PffEntry(_bReader, entry, _header.Signature); + } + else + throw new NotImplementedException(); + } else throw new NotImplementedException(); @@ -127,10 +138,19 @@ internal interface IPffEntryAbstract Byte[] FileName { get; } } + internal interface IPffHeaderAbstract + { + UInt32 HeaderSize { get; } + PffVersion Signature { get; } + UInt32 RecordCount { get; } + UInt32 RecordSize { get; } + UInt32 RecordOffset { get; } + } + // ReSharper disable UnassignedGetOnlyAutoProperty [StructLayout(LayoutKind.Sequential, Size = 20, Pack = 1)] - private struct Header_Pff3_20 + private struct Header_Pff3_20 : IPffHeaderAbstract { public UInt32 HeaderSize { get; } public PffVersion Signature { get; } @@ -151,10 +171,33 @@ private struct Entry_Pff3_32 : IPffEntryAbstract public Byte Null { get; } } + [StructLayout(LayoutKind.Sequential, Size = 20, Pack = 1)] + private struct Header_Pff4_20 : IPffHeaderAbstract + { + public UInt32 HeaderSize { get; } + public PffVersion Signature { get; } + public UInt32 RecordCount { get; } + public UInt32 RecordSize { get; } + public UInt32 RecordOffset { get; } + } + + [StructLayout(LayoutKind.Sequential, Size = 32, Pack = 1)] + private struct Entry_Pff4_36 : IPffEntryAbstract + { + public UInt32 Deleted { get; } + public UInt32 FileOffset { get; } + public UInt32 FileSize { get; } + public UInt32 FileModified { get; } + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] private readonly Byte[] fileName; + public Byte[] FileName => fileName; + public Byte Null { get; } + } + internal enum PffVersion : uint { PFF2 = 0x32464650, //{'P','F','F','2'} PFF3 = 0x33464650, //{'P','F','F','3'} + PFF4 = 0x34464650, //{'P','F','F','4'} } // ReSharper restore UnassignedGetOnlyAutoProperty diff --git a/Tools/lib-novalogic/PFF/PffEntry.cs b/Tools/lib-novalogic/PFF/PffEntry.cs index 03161d6..1898961 100644 --- a/Tools/lib-novalogic/PFF/PffEntry.cs +++ b/Tools/lib-novalogic/PFF/PffEntry.cs @@ -37,7 +37,7 @@ internal PffEntry(BinaryReader reader, PffArchive.IPffEntryAbstract entry, PffAr public byte[] GetContents() { if ((_version == PffArchive.PffVersion.PFF3 && _entry.Deleted == 0 && _entry.FileOffset != uint.MaxValue) || - _version == PffArchive.PffVersion.PFF2) + _version == PffArchive.PffVersion.PFF2 || _version == PffArchive.PffVersion.PFF4) { var stream = _reader.BaseStream; diff --git a/Tools/vsk/FormPreview.cs b/Tools/vsk/FormPreview.cs index 6f3d515..bce9d46 100644 --- a/Tools/vsk/FormPreview.cs +++ b/Tools/vsk/FormPreview.cs @@ -59,38 +59,41 @@ private void LoadFile(PffEntry entry) Bitmap img; var ext = Path.GetExtension(entry.FilePath)?.Substring(1); - switch (ext) + switch (ext.ToLower()) { - case "PCX": + case "pcx": img = PcxConvert.LoadPcx(fileContents); ClientSize = img.Size; pictureBox.Image = img; pictureBox.Visible = true; break; - case "TGA": + case "tga": img = TgaConvert.LoadTga(fileContents); ClientSize = img.Size; pictureBox.Image = img; pictureBox.Visible = true; break; - case "JPG": + case "jpg": img = LoadBitmap(fileContents); ClientSize = img.Size; pictureBox.Image = img; pictureBox.Visible = true; break; - case "WAV": + case "wav": using (var stream = new MemoryStream(fileContents)) { var simpleSound = new SoundPlayer(stream); simpleSound.Play(); } break; - case "3DI": + case "3di": var file = File3di.Open(fileContents); _renderer = new ModelRenderer(renderControl, file); renderControl.Visible = true; break; + default: + MessageBox.Show("Can't preview this file"); + break; } }