Skip to content

Commit

Permalink
Add basic PFF4 support
Browse files Browse the repository at this point in the history
Other changes:
 - Make the previewer case insensitive for the file extension
  • Loading branch information
[email protected] committed Jul 11, 2024
1 parent 70e3e6f commit 43ea63a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
49 changes: 46 additions & 3 deletions Tools/lib-novalogic/PFF/PffArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PffEntry> _cachedEntries;

private PffArchive(FileInfo fileInfo)
Expand All @@ -29,7 +29,8 @@ private PffArchive(FileInfo fileInfo)

else if (version == PffVersion.PFF2 && headerSize == 20)
_header = reader.ReadBytes(20).ToStruct<Header_Pff3_20>();

else if (version == PffVersion.PFF4 && headerSize == 20)
_header = reader.ReadBytes(20).ToStruct<Header_Pff4_20>();
else
throw new NotImplementedException();
}
Expand Down Expand Up @@ -105,6 +106,16 @@ private IEnumerable<PffEntry> EnumerateDirectory()
else
throw new NotImplementedException();
}
else if (_header.Signature == PffVersion.PFF4)
{
if (_header.RecordSize == 36)
{
var entry = _bReader.ReadBytes(36).ToStruct<Entry_Pff4_36>();
pffEntry = new PffEntry(_bReader, entry, _header.Signature);
}
else
throw new NotImplementedException();
}
else
throw new NotImplementedException();

Expand All @@ -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; }
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Tools/lib-novalogic/PFF/PffEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 9 additions & 6 deletions Tools/vsk/FormPreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down

0 comments on commit 43ea63a

Please sign in to comment.