mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-03-27 04:29:01 +03:00
80 lines
2.9 KiB
C#
80 lines
2.9 KiB
C#
using System.IO;
|
|
|
|
namespace Syroot.Worms.Core
|
|
{
|
|
/// <summary>
|
|
/// Represents methods to decompress data which is compressed using Team17's internal compression algorithm for
|
|
/// graphic file formats.
|
|
/// S. http://worms2d.info/Team17_compression.
|
|
/// </summary>
|
|
internal static class Team17Compression
|
|
{
|
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Decompresses the data available in the given <paramref name="stream"/> into the provided
|
|
/// <paramref name="buffer"/>.
|
|
/// </summary>
|
|
/// <param name="stream">The <see cref="Stream"/> to read the data from.</param>
|
|
/// <param name="buffer">The byte array buffer to write the decompressed data to.</param>
|
|
internal static void Decompress(Stream stream, ref byte[] buffer)
|
|
{
|
|
// TODO: This fails for compressed data in CD:\\Data\Mission\Training0-9.img.
|
|
int output = 0; // Offset of next write.
|
|
int cmd;
|
|
while ((cmd = stream.ReadByte()) != -1)
|
|
{
|
|
// Read a byte.
|
|
if ((cmd & 0x80) == 0)
|
|
{
|
|
// Command: 1 byte (color)
|
|
buffer[output++] = (byte)cmd;
|
|
}
|
|
else
|
|
{
|
|
// Arg1 = bits 2-5
|
|
int arg1 = (cmd >> 3) & 0xF;
|
|
int arg2 = stream.ReadByte();
|
|
if (arg2 == -1)
|
|
{
|
|
return;
|
|
}
|
|
// Arg2 = bits 6-16
|
|
arg2 = ((cmd << 8) | arg2) & 0x7FF;
|
|
if (arg1 == 0)
|
|
{
|
|
// Command: 0x80 0x00
|
|
if (arg2 == 0)
|
|
{
|
|
return;
|
|
}
|
|
int arg3 = stream.ReadByte();
|
|
if (arg3 == -1)
|
|
{
|
|
return;
|
|
}
|
|
// Command: 3 bytes
|
|
output = CopyData(output, arg2, arg3 + 18, ref buffer);
|
|
}
|
|
else
|
|
{
|
|
// Command: 2 bytes
|
|
output = CopyData(output, arg2 + 1, arg1 + 2, ref buffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
|
|
|
private static int CopyData(int offset, int compressedOffset, int count, ref byte[] buffer)
|
|
{
|
|
for (; count > 0; count--)
|
|
{
|
|
buffer[offset] = buffer[offset++ - compressedOffset];
|
|
}
|
|
return offset;
|
|
}
|
|
}
|
|
}
|