diff --git a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
index ce45be21..d2e8e0f4 100644
--- a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
@@ -373,7 +373,7 @@ namespace LibMSPackSharp.CHM
else
{
// PMGL chunks only, search from first_pmgl to last_pmgl
- for (n = chm.HeaderSection1.FirstPMGL; n <= chm.HeaderSection1.LastPMGL; n = BitConverter.ToUInt32(chunk, pmgl_NextChunk))
+ for (n = chm.HeaderSection1.FirstPMGL; n <= chm.HeaderSection1.LastPMGL; n = BitConverter.ToUInt32(chunk, 0x0010))
{
if ((chunk = ReadChunk(chm, fh, n)) == null)
{
@@ -386,7 +386,7 @@ namespace LibMSPackSharp.CHM
break;
// Stop simple infinite loops: can't visit the same chunk twice
- if (n == BitConverter.ToUInt32(chunk, pmgl_NextChunk))
+ if (n == BitConverter.ToUInt32(chunk, 0x0010))
break;
}
}
@@ -458,7 +458,7 @@ namespace LibMSPackSharp.CHM
///
internal Error InitDecompressor(DecompressFile file)
{
- int window_size, window_bits, reset_interval, entry;
+ int entry;
byte[] data;
MSCompressedSection sec = file.Section as MSCompressedSection;
@@ -480,7 +480,7 @@ namespace LibMSPackSharp.CHM
sec.Control = controlFile;
// Read ControlData
- if (sec.Control.Length != lzxcd_SIZEOF)
+ if (sec.Control.Length != _LZXControlData.Size)
{
Console.WriteLine("ControlData file is wrong size");
return Error = Error.MSPACK_ERR_DATAFORMAT;
@@ -492,58 +492,28 @@ namespace LibMSPackSharp.CHM
return Error;
}
- //// Create a new control data based on that
- //err = _LZXControlData.Create(data, out _LZXControlData lzxControlData);
- //if (err != Error.MSPACK_ERR_OK)
- // return err;
-
- // Check LZXC signature
- if (BitConverter.ToUInt32(data, lzxcd_Signature) != 0x43585A4C)
- return Error = Error.MSPACK_ERR_SIGNATURE;
-
- // Read reset_interval and window_size and validate version number
- switch (BitConverter.ToUInt32(data, lzxcd_Version))
- {
- case 1:
- reset_interval = (int)BitConverter.ToUInt32(data, lzxcd_ResetInterval);
- window_size = (int)BitConverter.ToUInt32(data, lzxcd_WindowSize);
- break;
- case 2:
- reset_interval = (int)BitConverter.ToUInt32(data, lzxcd_ResetInterval) * LZX.LZX_FRAME_SIZE;
- window_size = (int)BitConverter.ToUInt32(data, lzxcd_WindowSize) * LZX.LZX_FRAME_SIZE;
- break;
- default:
- Console.WriteLine("Bad controldata version");
- return Error = Error.MSPACK_ERR_DATAFORMAT;
- }
+ // Create a new control data based on that
+ err = _LZXControlData.Create(data, out _LZXControlData lzxControlData);
+ if (err != Error.MSPACK_ERR_OK)
+ return Error = err;
// Find window_bits from window_size
- switch (window_size)
- {
- case 0x008000: window_bits = 15; break;
- case 0x010000: window_bits = 16; break;
- case 0x020000: window_bits = 17; break;
- case 0x040000: window_bits = 18; break;
- case 0x080000: window_bits = 19; break;
- case 0x100000: window_bits = 20; break;
- case 0x200000: window_bits = 21; break;
- default:
- Console.WriteLine("Bad controldata window size");
- return Error = Error.MSPACK_ERR_DATAFORMAT;
- }
+ err = lzxControlData.GetWindowBits(out int windowBits);
+ if (err != Error.MSPACK_ERR_OK)
+ return Error = err;
// Validate reset_interval
- if (reset_interval == 0 || (reset_interval % LZX.LZX_FRAME_SIZE) != 0)
+ if (lzxControlData.ResetInterval == 0 || (lzxControlData.ResetInterval % LZX.LZX_FRAME_SIZE) != 0)
{
Console.WriteLine("Bad controldata reset interval");
return Error = Error.MSPACK_ERR_DATAFORMAT;
}
// Which reset table entry would we like?
- entry = (int)(file.Offset / reset_interval);
+ entry = (int)(file.Offset / lzxControlData.ResetInterval);
// Convert from reset interval multiple (usually 64k) to 32k frames
- entry *= reset_interval / LZX.LZX_FRAME_SIZE;
+ entry *= (int)lzxControlData.ResetInterval / LZX.LZX_FRAME_SIZE;
// Read the reset table entry
if (ReadResetTable(sec, (uint)entry, out long length, out long offset))
@@ -551,8 +521,8 @@ namespace LibMSPackSharp.CHM
// The uncompressed length given in the reset table is dishonest.
// The uncompressed data is always padded out from the given
// uncompressed length up to the next reset interval
- length += reset_interval - 1;
- length &= -reset_interval;
+ length += lzxControlData.ResetInterval - 1;
+ length &= -lzxControlData.ResetInterval;
}
else
{
@@ -577,7 +547,7 @@ namespace LibMSPackSharp.CHM
length -= State.Offset;
// Initialise LZX stream
- State.State = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, window_bits, reset_interval / LZX.LZX_FRAME_SIZE, 4096, length, false);
+ State.State = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, windowBits, (int)lzxControlData.ResetInterval / LZX.LZX_FRAME_SIZE, 4096, length, false);
if (State.State == null)
Error = Error.MSPACK_ERR_NOMEMORY;
@@ -818,7 +788,7 @@ namespace LibMSPackSharp.CHM
// Ensure there are chunks and that chunk size is
// large enough for signature and num_entries
- if (chm.HeaderSection1.ChunkSize < (pmgl_PMGLEntries + 2))
+ if (chm.HeaderSection1.ChunkSize < (_PMGHeader.PMGLSize + 2))
{
Console.WriteLine("Chunk size not large enough");
return Error.MSPACK_ERR_DATAFORMAT;
@@ -895,22 +865,22 @@ namespace LibMSPackSharp.CHM
if (System.Read(fh, chunk, 0, (int)chm.HeaderSection1.ChunkSize) != (int)chm.HeaderSection1.ChunkSize)
return Error.MSPACK_ERR_READ;
- //// Create a new header based on that
- //err = _PMGHeader.Create(buf, out _PMGHeader pmglHeader);
- //if (err != Error.MSPACK_ERR_OK)
- // return err;
+ // Create a new header based on that
+ err = _PMGHeader.Create(buf, out _PMGHeader pmgHeader);
+ if (err != Error.MSPACK_ERR_OK)
+ return err;
// Process only directory (PMGL) chunks
- if (BitConverter.ToUInt32(chunk, pmgl_Signature) != 0x4C474D50)
+ if (!pmgHeader.IsPMGL())
continue;
- if (BitConverter.ToUInt32(chunk, pmgl_QuickRefSize) < 2)
+ if (pmgHeader.QuickRefSize < 2)
System.Message(fh, "WARNING; PMGL quickref area is too small");
- if (BitConverter.ToUInt32(chunk, pmgl_QuickRefSize) > chm.HeaderSection1.ChunkSize - pmgl_PMGLEntries)
+ if (pmgHeader.QuickRefSize > chm.HeaderSection1.ChunkSize - pmgHeader.PMGLEntries)
System.Message(fh, "WARNING; PMGL quickref area is too large");
- p = pmgl_PMGLEntries;
+ p = (int)pmgHeader.PMGLEntries;
end = (int)(chm.HeaderSection1.ChunkSize - 2);
numEntries = BitConverter.ToUInt16(chunk, end);
@@ -1010,13 +980,14 @@ namespace LibMSPackSharp.CHM
continue;
}
- fi = new DecompressFile();
-
- fi.Next = null;
- fi.Filename = Encoding.UTF8.GetString(chunk, name, (int)nameLen) + "\0";
- fi.Section = (section == 0) ? chm.Sec0 as Section : chm.Sec1 as Section;
- fi.Offset = offset;
- fi.Length = length;
+ fi = new DecompressFile()
+ {
+ Next = null,
+ Filename = Encoding.UTF8.GetString(chunk, name, (int)nameLen) + "\0",
+ Section = (section == 0) ? chm.Sec0 as Section : chm.Sec1 as Section,
+ Offset = offset,
+ Length = length,
+ };
if (chunk[name + 0] == ':' && chunk[name + 1] == ':')
{
@@ -1054,12 +1025,12 @@ namespace LibMSPackSharp.CHM
///
/// Reads one entry out of the reset table. Also reads the uncompressed
- /// data length. Writes these to offset_ptr and length_ptr respectively.
+ /// data length. Writes these to offsetPointer and lengthPointer respectively.
/// Returns non-zero for success, zero for failure.
///
- private bool ReadResetTable(MSCompressedSection sec, uint entry, out long length_ptr, out long offset_ptr)
+ private bool ReadResetTable(MSCompressedSection sec, uint entry, out long lengthPointer, out long offsetPointer)
{
- length_ptr = 0; offset_ptr = 0;
+ lengthPointer = 0; offsetPointer = 0;
byte[] data;
// Do we have a ResetTable file?
@@ -1071,7 +1042,7 @@ namespace LibMSPackSharp.CHM
sec.ResetTable = resetTable;
// Read ResetTable file
- if (sec.ResetTable.Length < lzxrt_headerSIZEOF)
+ if (sec.ResetTable.Length < _LZXResetTable.Size)
{
Console.WriteLine("ResetTable file is too short");
return false;
@@ -1090,36 +1061,35 @@ namespace LibMSPackSharp.CHM
return false;
}
- //// Create a new reset data based on that
- //err = _LZXResetTable.Create(data, out _LZXResetTable lzxResetTable);
- //if (err != Error.MSPACK_ERR_OK)
- // return false;
+ // Create a new reset data based on that
+ err = _LZXResetTable.Create(data, out _LZXResetTable lzxResetTable);
+ if (err != Error.MSPACK_ERR_OK)
+ return false;
// Check sanity of reset table
- if (BitConverter.ToUInt32(data, lzxrt_FrameLen) != LZX.LZX_FRAME_SIZE)
+ if (lzxResetTable.FrameLength != LZX.LZX_FRAME_SIZE)
{
Console.WriteLine("Bad reset table frame length");
return false;
}
// Get the uncompressed length of the LZX stream
- if ((length_ptr = BitConverter.ToInt64(data, lzxrt_UncompLen)) == 0)
+ if ((lengthPointer = lzxResetTable.UncompressedLength) == 0)
return false;
- uint entrysize = BitConverter.ToUInt32(data, lzxrt_EntrySize);
- uint pos = BitConverter.ToUInt32(data, lzxrt_TableOffset) + (entry * entrysize);
+ uint pos = lzxResetTable.TableOffset + (entry * lzxResetTable.EntrySize);
// Ensure reset table entry for this offset exists
- if (entry < BitConverter.ToUInt32(data, lzxrt_NumEntries) && pos <= (sec.ResetTable.Length - entrysize))
+ if (entry < lzxResetTable.NumEntries && pos <= (sec.ResetTable.Length - lzxResetTable.EntrySize))
{
- switch (entrysize)
+ switch (lzxResetTable.EntrySize)
{
case 4:
- offset_ptr = BitConverter.ToUInt32(data, (int)pos);
+ offsetPointer = BitConverter.ToUInt32(data, (int)pos);
err = Error.MSPACK_ERR_OK;
break;
case 8:
- offset_ptr = BitConverter.ToInt64(data, (int)pos);
+ offsetPointer = BitConverter.ToInt64(data, (int)pos);
break;
default:
Console.WriteLine("Reset table entry size neither 4 nor 8");
@@ -1262,22 +1232,22 @@ namespace LibMSPackSharp.CHM
{
int p;
uint nameLen;
- uint left, right, midpoint, entriesOff;
- bool is_pmgl;
+ uint left, right, midpoint, entries;
int cmp;
+ // Create a new header based on the chunk
+ Error err = _PMGHeader.Create(chunk, out _PMGHeader pmgHeader);
+ if (err != Error.MSPACK_ERR_OK)
+ return -1;
+
+ // TODO: Figure out what `entriesOff` does. It feels like it's being used wrong
+
// PMGL chunk or PMGI chunk? (note: read_chunk() has already
// checked the rest of the characters in the chunk signature)
- if (chunk[3] == 0x4C)
- {
- is_pmgl = true;
- entriesOff = pmgl_PMGLEntries;
- }
+ if (pmgHeader.IsPMGL())
+ entries = pmgHeader.PMGLEntries;
else
- {
- is_pmgl = false;
- entriesOff = pmgl_PMGIEntries;
- }
+ entries = pmgHeader.PMGIEntries;
// Step 1: binary search first filename of each QR entry
// - target filename == entry
@@ -1288,7 +1258,7 @@ namespace LibMSPackSharp.CHM
// proceed to step 2 using final entry
// - target filename between two searched entries
// Proceed to step 2
- uint qrSize = BitConverter.ToUInt32(chunk, pmgl_QuickRefSize);
+ uint qrSize = pmgHeader.QuickRefSize;
int start = (int)(chm.HeaderSection1.ChunkSize - 2);
int end = (int)(chm.HeaderSection1.ChunkSize - qrSize);
ushort numEntries = BitConverter.ToUInt16(chunk, start);
@@ -1325,7 +1295,7 @@ namespace LibMSPackSharp.CHM
midpoint = (left + right) >> 1;
// Compare filename with entry QR points to
- p = (int)(entriesOff + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0));
+ p = (int)(entries + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0));
// READ_ENCINT(nameLen)
nameLen = 0;
@@ -1376,14 +1346,14 @@ namespace LibMSPackSharp.CHM
}
// Otherwise, read the group of entries for QR entry M
- p = (int)(entriesOff + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0));
+ p = (int)(entries + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0));
numEntries -= (ushort)(midpoint * qrDensity);
if (numEntries > qrDensity)
numEntries = (ushort)qrDensity;
}
else
{
- p = (int)entriesOff;
+ p = (int)entries;
}
// Step 2: linear search through the set of entries reached in step 1.
@@ -1432,7 +1402,7 @@ namespace LibMSPackSharp.CHM
}
// Read and ignore the rest of this entry
- if (is_pmgl)
+ if (pmgHeader.IsPMGL())
{
// Skip section, offset, and length
for (int i = 0; i < 3; i++)
@@ -1472,7 +1442,7 @@ namespace LibMSPackSharp.CHM
}
// PMGL? not found. PMGI? maybe found
- return (is_pmgl) ? 0 : (result != 0 ? 1 : 0);
+ return (pmgHeader.IsPMGL()) ? 0 : (result != 0 ? 1 : 0);
}
#endregion
diff --git a/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs b/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs
new file mode 100644
index 00000000..6d8e5687
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs
@@ -0,0 +1,155 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+using System;
+using LibMSPackSharp.Compression;
+
+namespace LibMSPackSharp.CHM
+{
+ internal class _LZXControlData
+ {
+ #region Fields
+
+ ///
+ /// Length of the control data
+ ///
+ /// 0x0000
+ public uint Length { get; private set; }
+
+ ///
+ /// "LZXC"
+ ///
+ /// 0x0004
+ public uint Signature { get; private set; }
+
+ ///
+ /// Control data version
+ ///
+ /// 0x0008
+ public uint Version { get; private set; }
+
+ ///
+ /// Reset interval
+ ///
+ /// 0x000C
+ public uint ResetInterval { get; private set; }
+
+ ///
+ /// Window size
+ ///
+ /// 0x0010
+ public uint WindowSize { get; private set; }
+
+ ///
+ /// Cache size
+ ///
+ /// 0x0014
+ public uint CacheSize { get; private set; }
+
+ ///
+ /// Cache size
+ ///
+ /// 0x0018
+ public uint Unknown1 { get; private set; }
+
+ ///
+ /// Total size of the LZX control data in bytes
+ ///
+ public const int Size = 0x001C;
+
+ #endregion
+
+ ///
+ /// Private constructor
+ ///
+ private _LZXControlData() { }
+
+ ///
+ /// Create a _LZXControlData from a byte array, if possible
+ ///
+ public static Error Create(byte[] buffer, out _LZXControlData controlData)
+ {
+ controlData = null;
+ if (buffer == null || buffer.Length < Size)
+ return Error.MSPACK_ERR_READ;
+
+ controlData = new _LZXControlData();
+
+ controlData.Length = BitConverter.ToUInt32(buffer, 0x0000);
+ controlData.Signature = BitConverter.ToUInt32(buffer, 0x0004);
+ if (controlData.Signature != 0x43585A4C)
+ return Error.MSPACK_ERR_SIGNATURE;
+
+ controlData.Version = BitConverter.ToUInt32(buffer, 0x0008);
+ switch (controlData.Version)
+ {
+ case 1:
+ controlData.ResetInterval = BitConverter.ToUInt32(buffer, 0x000C);
+ controlData.WindowSize = BitConverter.ToUInt32(buffer, 0x0010);
+ break;
+ case 2:
+ controlData.ResetInterval = BitConverter.ToUInt32(buffer, 0x000C) * LZX.LZX_FRAME_SIZE;
+ controlData.WindowSize = BitConverter.ToUInt32(buffer, 0x0010) * LZX.LZX_FRAME_SIZE;
+ break;
+ default:
+ return Error.MSPACK_ERR_DATAFORMAT;
+ }
+
+ controlData.CacheSize = BitConverter.ToUInt32(buffer, 0x0014);
+ controlData.Unknown1 = BitConverter.ToUInt32(buffer, 0x0018);
+
+ return Error.MSPACK_ERR_OK;
+ }
+
+ ///
+ /// Get the number of bits in the window based on the window size
+ ///
+ /// Window
+ /// An error code or MSPACK_ERR_OK if all is good
+ public Error GetWindowBits(out int windowBits)
+ {
+ switch (WindowSize)
+ {
+ case 0x008000:
+ windowBits = 15;
+ break;
+
+ case 0x010000:
+ windowBits = 16;
+ break;
+
+ case 0x020000:
+ windowBits = 17;
+ break;
+
+ case 0x040000:
+ windowBits = 18;
+ break;
+
+ case 0x080000:
+ windowBits = 19;
+ break;
+
+ case 0x100000:
+ windowBits = 20;
+ break;
+
+ case 0x200000:
+ windowBits = 21;
+ break;
+
+ default:
+ windowBits = -1;
+ return Error.MSPACK_ERR_DATAFORMAT;
+ }
+
+ return Error.MSPACK_ERR_OK;
+ }
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs b/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs
new file mode 100644
index 00000000..22495dc3
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs
@@ -0,0 +1,94 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+using System;
+
+namespace LibMSPackSharp.CHM
+{
+ internal class _LZXResetTable
+ {
+ #region Fields
+
+ ///
+ /// UNKNOWN
+ ///
+ /// 0x0000
+ public uint Unknown1 { get; private set; }
+
+ ///
+ /// Number of entries in the table
+ ///
+ /// 0x0004
+ public uint NumEntries { get; private set; }
+
+ ///
+ /// Size of each entry
+ ///
+ /// 0x0008
+ public uint EntrySize { get; private set; }
+
+ ///
+ /// Table offset
+ ///
+ /// 0x000C
+ public uint TableOffset { get; private set; }
+
+ ///
+ /// Uncompressed length
+ ///
+ /// 0x0010
+ public long UncompressedLength { get; private set; }
+
+ ///
+ /// Compressed length
+ ///
+ /// 0x0018
+ public long CompressedLength { get; private set; }
+
+ ///
+ /// Frame length
+ ///
+ /// 0x0020
+ public long FrameLength { get; private set; }
+
+ ///
+ /// Total size of the LZX reset table in bytes
+ ///
+ public const int Size = 0x0028;
+
+ #endregion
+
+ ///
+ /// Private constructor
+ ///
+ private _LZXResetTable() { }
+
+ ///
+ /// Create a _LZXControlData from a byte array, if possible
+ ///
+ public static Error Create(byte[] buffer, out _LZXResetTable resetTable)
+ {
+ resetTable = null;
+ if (buffer == null || buffer.Length < Size)
+ return Error.MSPACK_ERR_READ;
+
+ resetTable = new _LZXResetTable();
+
+ resetTable.Unknown1 = BitConverter.ToUInt32(buffer, 0x0000);
+ resetTable.NumEntries = BitConverter.ToUInt32(buffer, 0x0004);
+ resetTable.EntrySize = BitConverter.ToUInt32(buffer, 0x0008);
+ resetTable.TableOffset = BitConverter.ToUInt32(buffer, 0x000C);
+ resetTable.UncompressedLength = BitConverter.ToInt64(buffer, 0x0010);
+ resetTable.CompressedLength = BitConverter.ToInt64(buffer, 0x0018);
+ resetTable.FrameLength = BitConverter.ToInt64(buffer, 0x0020);
+
+ return Error.MSPACK_ERR_OK;
+ }
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs b/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs
new file mode 100644
index 00000000..22f4489b
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs
@@ -0,0 +1,118 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+using System;
+
+namespace LibMSPackSharp.CHM
+{
+ internal class _PMGHeader
+ {
+ #region Fields
+
+ ///
+ /// "PMGL" or "PMGI"
+ ///
+ /// 0x0000
+ public uint Signature { get; private set; }
+
+ ///
+ /// Quick reference size
+ ///
+ /// 0x0004
+ public uint QuickRefSize { get; private set; }
+
+ ///
+ /// Number of entries in a PMGI chunk
+ ///
+ ///
+ /// 0x0008
+ ///
+ /// Unused in PMGL
+ ///
+ public uint PMGIEntries { get; private set; }
+
+ ///
+ /// Previous chunk ID
+ ///
+ ///
+ /// 0x000C
+ ///
+ /// Does not exist in PMGI
+ ///
+ public uint PrevChunk { get; private set; }
+
+ ///
+ /// Next chunk ID
+ ///
+ ///
+ /// 0x0010
+ ///
+ /// Does not exist in PMGI
+ ///
+ public uint NextChunk { get; private set; }
+
+ ///
+ /// Number of entries in a PMGL chunk
+ ///
+ ///
+ /// 0x0014
+ ///
+ /// Does not exist in PMGI
+ ///
+ public uint PMGLEntries { get; private set; }
+
+ ///
+ /// Total size of the PMGI header in bytes
+ ///
+ public const int PMGISize = 0x000C;
+
+ ///
+ /// Total size of the PMGL header in bytes
+ ///
+ public const int PMGLSize = 0x0014;
+
+ #endregion
+
+ ///
+ /// Private constructor
+ ///
+ private _PMGHeader() { }
+
+ ///
+ /// Create a _PMGHeader from a byte array, if possible
+ ///
+ public static Error Create(byte[] buffer, out _PMGHeader header)
+ {
+ header = null;
+ if (buffer == null || buffer.Length < PMGISize)
+ return Error.MSPACK_ERR_READ;
+
+ header = new _PMGHeader();
+
+ header.Signature = BitConverter.ToUInt32(buffer, 0x0000);
+ header.QuickRefSize = BitConverter.ToUInt32(buffer, 0x0004);
+ header.PMGIEntries = BitConverter.ToUInt32(buffer, 0x0008);
+
+ if (buffer.Length >= PMGLSize)
+ {
+ header.PrevChunk = BitConverter.ToUInt32(buffer, 0x000C);
+ header.NextChunk = BitConverter.ToUInt32(buffer, 0x0010);
+ header.PMGLEntries = BitConverter.ToUInt32(buffer, 0x0014);
+ }
+
+ return Error.MSPACK_ERR_OK;
+ }
+
+ ///
+ /// Determines if a PMG chunk is PMGL or PMGI
+ ///
+ /// True for PMGL and false of PMGI
+ public bool IsPMGL() => Signature == 0x4C474D50;
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/Constants.cs b/BurnOutSharp/External/libmspack/Constants.cs
index eedc7346..3a83377a 100644
--- a/BurnOutSharp/External/libmspack/Constants.cs
+++ b/BurnOutSharp/External/libmspack/Constants.cs
@@ -42,37 +42,6 @@ namespace LibMSPackSharp
#region CHM
- // _PMGHeader
- public const int pmgl_Signature = 0x0000;
- public const int pmgl_QuickRefSize = 0x0004;
- public const int pmgl_PMGIEntries = 0x0008; // Unknown1 in PMGL
- public const int pmgl_PrevChunk = 0x000C; // Not in PMGI
- public const int pmgl_NextChunk = 0x0010; // Not in PMGI
- public const int pmgl_PMGLEntries = 0x0014; // Not in PMGI
- public const int pmgl_headerSIZEOF = 0x0014;
- public const int pmgi_headerSIZEOF = 0x000C;
-
- // _LZXControlData
- public const int lzxcd_Length = 0x0000;
- public const int lzxcd_Signature = 0x0004;
- public const int lzxcd_Version = 0x0008;
- public const int lzxcd_ResetInterval = 0x000C;
- public const int lzxcd_WindowSize = 0x0010;
- public const int lzxcd_CacheSize = 0x0014;
- public const int lzxcd_Unknown1 = 0x0018;
- public const int lzxcd_SIZEOF = 0x001C;
-
- // _LZXResetTable
- public const int lzxrt_Unknown1 = 0x0000;
- public const int lzxrt_NumEntries = 0x0004;
- public const int lzxrt_EntrySize = 0x0008;
- public const int lzxrt_TableOffset = 0x000C;
- public const int lzxrt_UncompLen = 0x0010;
- public const int lzxrt_CompLen = 0x0018;
- public const int lzxrt_FrameLen = 0x0020;
- public const int lzxrt_Entries = 0x0028;
- public const int lzxrt_headerSIZEOF = 0x0028;
-
// Filenames of the system files used for decompression.
// - Content and ControlData are essential.
// - ResetTable is preferred, but SpanInfo can be used if not available