Added Eighting FPK archive format (without compression)

This commit is contained in:
Michael Becker 2014-10-07 23:24:51 -04:00
parent 0ccba48bb7
commit 459468ff68
2 changed files with 143 additions and 0 deletions

View File

@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.FileSystem;
namespace UniversalEditor.DataFormats.FileSystem.Eighting.FPK
{
public class FPKDataFormat : DataFormat
{
private static DataFormatReference _dfr = null;
public override DataFormatReference MakeReference()
{
if (_dfr == null)
{
_dfr = base.MakeReference();
_dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
_dfr.ExportOptions.Add(new CustomOptionNumber("DataAlignment", "Data &alignment (in bytes): ", 16, 0, UInt32.MaxValue));
_dfr.Filters.Add("Eighting (Bleach PSP) FPK archive", new byte?[][] { new byte?[] { (byte)'x', (byte)'J', (byte)0, (byte)0 } }, new string[] { "*.fpk" });
_dfr.Sources.Add("http://wiki.xentax.com/index.php?title=Bleach_%28PSP%29");
}
return _dfr;
}
private uint mvarDataAlignment = 16;
public uint DataAlignment { get { return mvarDataAlignment; } set { mvarDataAlignment = value; } }
protected override void LoadInternal(ref ObjectModel objectModel)
{
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
if (fsom == null) throw new ObjectModelNotSupportedException();
Reader reader = base.Accessor.Reader;
string header1 = reader.ReadFixedLengthString(2);
ushort header2 = reader.ReadUInt16();
if (!(header1 == "xJ" && header2 == 0)) throw new InvalidDataFormatException("File does not begin with 'xJ', 0x00, 0x00");
uint fileCount = reader.ReadUInt32();
mvarDataAlignment = reader.ReadUInt32();
uint archiveSize = reader.ReadUInt32();
for (uint i = 0; i < fileCount; i++)
{
string fileName = reader.ReadFixedLengthString(36).TrimNull();
uint offset = reader.ReadUInt32();
uint compressedLength = reader.ReadUInt32();
uint decompressedLength = reader.ReadUInt32();
File file = fsom.AddFile(fileName);
file.Size = decompressedLength;
file.Properties.Add("reader", reader);
file.Properties.Add("offset", offset);
file.Properties.Add("CompressedLength", compressedLength);
file.Properties.Add("DecompressedLength", decompressedLength);
file.DataRequest += file_DataRequest;
}
}
private void file_DataRequest(object sender, DataRequestEventArgs e)
{
File file = (sender as File);
Reader reader = (Reader)file.Properties["reader"];
uint offset = (uint)file.Properties["offset"];
uint CompressedLength = (uint)file.Properties["CompressedLength"];
uint DecompressedLength = (uint)file.Properties["DecompressedLength"];
reader.Seek(offset, SeekOrigin.Begin);
byte flag = reader.ReadByte();
bool compressed = (flag == 255);
byte[] compressedData = reader.ReadBytes(CompressedLength);
byte[] decompressedData = compressedData;
if (compressed)
{
}
e.Data = decompressedData;
}
protected override void SaveInternal(ObjectModel objectModel)
{
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
if (fsom == null) throw new ObjectModelNotSupportedException();
Writer writer = base.Accessor.Writer;
writer.WriteFixedLengthString("xJ");
writer.WriteUInt16(0);
File[] files = fsom.GetAllFiles();
writer.WriteUInt32((uint)files.Length);
writer.WriteUInt32(mvarDataAlignment);
uint archiveSize = 16;
long archiveSizePosition = base.Accessor.Position;
writer.WriteUInt32(archiveSize);
uint offset = (uint)(base.Accessor.Position + (48 * files.Length));
byte[][] compressedDatas = new byte[files.Length][];
bool[] compressed = new bool[files.Length];
for (int i = 0; i < files.Length; i++)
{
File file = files[i];
writer.WriteFixedLengthString(file.Name, 36);
writer.WriteUInt32(offset);
byte[] decompressedData = file.GetDataAsByteArray();
byte[] compressedData = decompressedData;
compressedDatas[i] = compressedData;
compressed[i] = false;
writer.WriteUInt32((uint)compressedData.Length);
writer.WriteUInt32((uint)decompressedData.Length);
offset += (uint)(compressedData.Length + 1);
long count = (offset % mvarDataAlignment);
offset += (uint)count;
}
for (int i = 0; i < files.Length; i++)
{
if (compressed[i])
{
writer.WriteByte(255);
}
else
{
writer.WriteByte(0);
}
writer.WriteBytes(compressedDatas[i]);
writer.Align((int)mvarDataAlignment);
}
base.Accessor.Seek(archiveSizePosition, SeekOrigin.Begin);
writer.WriteUInt32((uint)base.Accessor.Length);
writer.Flush();
}
}
}

View File

@ -78,6 +78,7 @@
<Compile Include="DataFormats\FileSystem\CPIO\CPIOEncoding.cs" />
<Compile Include="DataFormats\FileSystem\DeepSilver\SecretFiles\SPRDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\Dreamfall\PAKDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\Eighting\FPK\FPKDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\ElectronicArts\BIGFDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\FARC\FARCDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\FAT\FATBiosParameterBlock.cs" />