implemented ScrPlayer 'pack' archives and IMG2 images.

This commit is contained in:
morkt
2016-09-12 01:27:29 +04:00
parent 72f6d329f1
commit 3eea7bb5df
8 changed files with 481 additions and 0 deletions

View File

@@ -195,6 +195,8 @@
<Compile Include="RealLive\AudioOWP.cs" />
<Compile Include="RealLive\ImageG00.cs" />
<Compile Include="RealLive\ImagePDT.cs" />
<Compile Include="ScrPlayer\ArcPAK.cs" />
<Compile Include="ScrPlayer\ImageI.cs" />
<Compile Include="ShiinaRio\WarcEncryption.cs" />
<Compile Include="Silky\ImageZIT.cs" />
<Compile Include="SimpleEncryption.cs" />
@@ -594,6 +596,11 @@
</Compile>
<EmbeddedResource Include="Softpal\WaveTable1" />
<EmbeddedResource Include="Softpal\WaveTable2" />
<EmbeddedResource Include="ScrPlayer\ColorBitsTable1" />
<EmbeddedResource Include="ScrPlayer\ColorBitsTable2" />
<EmbeddedResource Include="ScrPlayer\ControlTable1" />
<EmbeddedResource Include="ScrPlayer\ControlTable2" />
<EmbeddedResource Include="ScrPlayer\ControlTable32" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GameRes\GameRes.csproj">

View File

@@ -0,0 +1,70 @@
//! \file ArcPAK.cs
//! \date Sat Sep 10 16:00:06 2016
//! \brief ScrPlayer resource archive.
//
// Copyright (C) 2016 by morkt
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System.Collections.Generic;
using System.ComponentModel.Composition;
namespace GameRes.Formats.ScrPlayer
{
[Export(typeof(ArchiveFormat))]
public class PakOpener : ArchiveFormat
{
public override string Tag { get { return "PAK/ScrPlayer"; } }
public override string Description { get { return "ScrPlayer engine resource archive"; } }
public override uint Signature { get { return 0x6B636170; } } // 'pack'
public override bool IsHierarchic { get { return false; } }
public override bool CanCreate { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
uint index_size = file.View.ReadUInt32 (4);
if (index_size < 0x10 || index_size >= file.MaxOffset)
return null;
uint index_offset = 8;
uint index_end = index_offset + index_size;
var dir = new List<Entry>();
while (index_offset < index_end)
{
uint offset = file.View.ReadUInt32 (index_offset);
if (0 == offset)
break;
uint size = file.View.ReadUInt32 (index_offset+4);
byte name_length = file.View.ReadByte (index_offset+8);
var name = file.View.ReadString (index_offset+9, name_length);
index_offset += ((9u + name_length) & ~7u) + 8u;
if (index_offset > index_end)
return null;
var entry = FormatCatalog.Instance.Create<Entry> (name);
entry.Offset = offset;
entry.Size = size;
dir.Add (entry);
}
if (0 == dir.Count)
return null;
return new ArcFile (file, this, dir);
}
}
}

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,404 @@
//! \file ImageI.cs
//! \date Sat Sep 10 17:06:39 2016
//! \brief ScrPlayer image format.
//
// Copyright (C) 2016 by morkt
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System;
using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Media;
using GameRes.Utility;
namespace GameRes.Formats.ScrPlayer
{
[Export(typeof(ImageFormat))]
public class Img2Format : ImageFormat
{
public override string Tag { get { return "IMG2"; } }
public override string Description { get { return "ScrPlayer image format"; } }
public override uint Signature { get { return 0x32474D49; } } // 'IMG2'
public Img2Format ()
{
Extensions = new string[] { "i" };
}
public override ImageMetaData ReadMetaData (Stream stream)
{
var header = new byte[0x20];
if (header.Length != stream.Read (header, 0, header.Length))
return null;
return new ImageMetaData
{
Width = LittleEndian.ToUInt16 (header, 0xC),
Height = LittleEndian.ToUInt16 (header, 0xE),
BPP = LittleEndian.ToUInt16 (header, 0x10),
};
}
public override ImageData Read (Stream stream, ImageMetaData info)
{
using (var reader = new Img2Reader (stream, info))
{
reader.Unpack();
return ImageData.Create (info, reader.Format, null, reader.Data);
}
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("Img2Format.Write not implemented");
}
}
internal class Img2BitStream : BitStream
{
public Img2BitStream (Stream file, bool leave_open = false) : base (file, leave_open)
{
}
public int GetBits (byte[] table, int count)
{
int n = PeekBits (count);
if (-1 == n)
throw new EndOfStreamException();
n *= 2;
count = table[n];
m_bits >>= count;
m_cached_bits -= count;
return table[n + 1];
}
public int PeekBits (int count)
{
while (m_cached_bits < count)
{
int b = m_input.ReadByte();
if (-1 == b)
return -1;
m_bits |= b << m_cached_bits;
m_cached_bits += 8;
}
return m_bits & ((1 << count) - 1);
}
}
internal sealed class Img2Reader : IDisposable
{
Img2BitStream m_input;
byte[] m_output;
int m_width;
int m_height;
int m_stride;
bool m_has_alpha;
public byte[] Data { get { return m_output; } }
public PixelFormat Format { get; private set; }
public Img2Reader (Stream input, ImageMetaData info)
{
m_input = new Img2BitStream (input, true);
m_width = (int)info.Width;
m_height = (int)info.Height;
m_stride = m_width * 4;
m_output = new byte[m_stride * m_height];
m_has_alpha = 32 == info.BPP;
Format = m_has_alpha ? PixelFormats.Bgra32 : PixelFormats.Bgr32;
}
public void Unpack ()
{
m_input.Input.Position = 0x20;
if (m_has_alpha)
Unpack32bpp();
else
Unpack24bpp();
}
void Unpack24bpp ()
{
var rows = new int[3];
var offset_table = OffsetTable.Clone() as int[];
for (int y = 0; y < m_height; ++y)
{
int dst = rows[0];
for (int x = 0; x < m_width; )
{
int ctl = m_input.GetBits (ControlTable1, 13);
if (0xB8 == ctl)
ctl += m_input.GetBits (ControlTable2, 13);
int pos = m_input.GetBits (PosTable24, 6) * 2;
int x_offset = offset_table[pos];
int y_offset = offset_table[pos + 1];
if (pos > 0)
{
offset_table[pos] = offset_table[pos-2];
offset_table[pos+1] = offset_table[pos-1];
offset_table[pos-2] = x_offset;
offset_table[pos-1] = y_offset;
}
int src = rows[y_offset] + (x + x_offset) * 4;
if (ctl >= 0xD8)
{
int count = ctl - 0xD6;
Binary.CopyOverlapped (m_output, src, dst, count * 4);
dst += count * 4;
x += count;
}
else
{
for (int j = 2; j >= 0; --j)
{
byte r = RgbBits[j,ctl];
if (0xFD == r)
r = GetDelta (DeltaTable);
m_output[dst+j] = (byte)(m_output[src+j] - r);
}
dst += 4;
++x;
}
}
rows[2] = rows[1];
rows[1] = rows[0];
rows[0] += m_stride;
}
}
void Unpack32bpp ()
{
for (int i = 3; i < m_stride; i += 4)
m_output[i] = 0xFF;
var rows = new int[3];
var offset_table = OffsetTable.Clone() as int[];
for (int y = 0; y < m_height; ++y)
{
int dst = rows[0];
for (int x = 0; x < m_width; )
{
int ctl = m_input.GetBits (ControlTable1, 13);
if (0xB8 == ctl)
ctl += m_input.GetBits (ControlTable2, 13);
int t = m_input.GetBits (ControlTable32, 9) * 2;
int pos = PosTable32[t] * 2;
bool diff_alpha = PosTable32[t + 1] != 0;
int x_offset = offset_table[pos];
int y_offset = offset_table[pos + 1];
if (pos > 0)
{
offset_table[pos] = offset_table[pos-2];
offset_table[pos+1] = offset_table[pos-1];
offset_table[pos-2] = x_offset;
offset_table[pos-1] = y_offset;
}
int src = rows[y_offset] + (x + x_offset) * 4;
if (ctl >= 0xD8)
{
int count = ctl - 0xD6;
Binary.CopyOverlapped (m_output, src, dst, count * 4);
dst += count * 4;
x += count;
}
else
{
for (int j = 2; j >= 0; --j)
{
byte r = RgbBits[j,ctl];
if (0xFD == r)
r = GetDelta (DeltaTable);
m_output[dst+j] = (byte)(m_output[src+j] - r);
}
byte alpha = 0;
if (diff_alpha)
alpha = GetDelta (AlphaTable);
m_output[dst+3] = (byte)(m_output[src+3] - alpha);
dst += 4;
++x;
}
}
rows[2] = rows[1];
rows[1] = rows[0];
rows[0] += m_stride;
}
}
byte GetDelta (byte[] table)
{
int delta = m_input.GetBits (ColorBitsTable1, 10);
if (0x41 == delta)
delta += m_input.GetBits (ColorBitsTable2, 10);
return table[delta];
}
static byte[] LoadResource (string name)
{
var type = typeof(Img2Reader);
var assembly = type.Assembly;
using (var stream = assembly.GetManifestResourceStream (type.Namespace+'.'+name))
{
if (null == stream)
return null;
var data = new byte[stream.Length];
stream.Read (data, 0, data.Length);
return data;
}
}
#region IDisposable Members
bool _disposed = false;
public void Dispose ()
{
if (!_disposed)
{
m_input.Dispose();
_disposed = true;
}
}
#endregion
#region Bitmap tables
static readonly Lazy<byte[]> s_control_table1 = new Lazy<byte[]> (() => LoadResource ("ControlTable1"));
static readonly Lazy<byte[]> s_control_table2 = new Lazy<byte[]> (() => LoadResource ("ControlTable2"));
static readonly Lazy<byte[]> s_control_table32 = new Lazy<byte[]> (() => LoadResource ("ControlTable32"));
static readonly Lazy<byte[]> s_color_bits1 = new Lazy<byte[]> (() => LoadResource ("ColorBitsTable1"));
static readonly Lazy<byte[]> s_color_bits2 = new Lazy<byte[]> (() => LoadResource ("ColorBitsTable2"));
static byte[] ControlTable1 { get { return s_control_table1.Value; } }
static byte[] ControlTable2 { get { return s_control_table2.Value; } }
static byte[] ControlTable32 { get { return s_control_table32.Value; } }
static byte[] ColorBitsTable1 { get { return s_color_bits1.Value; } }
static byte[] ColorBitsTable2 { get { return s_color_bits2.Value; } }
static readonly byte[] PosTable24 = {
0x01, 0x00, 0x06, 0x07, 0x01, 0x00, 0x06, 0x09, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x04, 0x03, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x05, 0x05, 0x01, 0x00, 0x05, 0x06, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x04, 0x03, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x06, 0x08, 0x01, 0x00, 0x06, 0x0A, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x04, 0x03, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x05, 0x05, 0x01, 0x00, 0x05, 0x06, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
0x01, 0x00, 0x04, 0x03, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x02,
};
static readonly int[] PosTable32 = {
0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0,
0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1
};
static readonly byte[] DeltaTable = {
0x03, 0xFD, 0x04, 0xFC, 0x05, 0xFB, 0x06, 0xFA, 0x07, 0xF9, 0x08, 0xF8, 0x09, 0xF7, 0x0A, 0xF6,
0x0B, 0xF5, 0x0C, 0xF4, 0x0D, 0xF3, 0x0E, 0xF2, 0x0F, 0xF1, 0x10, 0xF0, 0x11, 0xEF, 0x12, 0xEE,
0x13, 0xED, 0x14, 0xEC, 0x15, 0xEB, 0x16, 0xEA, 0x17, 0xE9, 0x18, 0xE8, 0x19, 0xE7, 0x1A, 0xE6,
0x1B, 0xE5, 0x1C, 0xE4, 0x1D, 0xE3, 0x1E, 0xE2, 0x1F, 0xE1, 0x20, 0xE0, 0x21, 0xDF, 0x22, 0xDE,
0x23, 0xDD, 0x24, 0xDC, 0x25, 0xDB, 0x26, 0xDA, 0x27, 0xD9, 0x28, 0xD8, 0x29, 0xD7, 0x2A, 0xD6,
0x2B, 0xD5, 0x2C, 0xD4, 0x2D, 0xD3, 0x2E, 0xD2, 0x2F, 0xD1, 0x30, 0xD0, 0x31, 0xCF, 0x32, 0xCE,
0x33, 0xCD, 0x34, 0xCC, 0x35, 0xCB, 0x36, 0xCA, 0x37, 0xC9, 0x38, 0xC8, 0x39, 0xC7, 0x3A, 0xC6,
0x3B, 0xC5, 0x3C, 0xC4, 0x3D, 0xC3, 0x3E, 0xC2, 0x3F, 0xC1, 0x40, 0xC0, 0x41, 0xBF, 0x42, 0xBE,
0x43, 0xBD, 0x44, 0xBC, 0x45, 0xBB, 0x46, 0xBA, 0x47, 0xB9, 0x48, 0xB8, 0x49, 0xB7, 0x4A, 0xB6,
0x4B, 0xB5, 0x4C, 0xB4, 0x4D, 0xB3, 0x4E, 0xB2, 0x4F, 0xB1, 0x50, 0xB0, 0x51, 0xAF, 0x52, 0xAE,
0x53, 0xAD, 0x54, 0xAC, 0x55, 0xAB, 0x56, 0xAA, 0x57, 0xA9, 0x58, 0xA8, 0x59, 0xA7, 0x5A, 0xA6,
0x5B, 0xA5, 0x5C, 0xA4, 0x5D, 0xA3, 0x5E, 0xA2, 0x5F, 0xA1, 0x60, 0xA0, 0x61, 0x9F, 0x62, 0x9E,
0x63, 0x9D, 0x64, 0x9C, 0x65, 0x9B, 0x66, 0x9A, 0x67, 0x99, 0x68, 0x98, 0x69, 0x97, 0x6A, 0x96,
0x6B, 0x95, 0x6C, 0x94, 0x6D, 0x93, 0x6E, 0x92, 0x6F, 0x91, 0x70, 0x90, 0x71, 0x8F, 0x72, 0x8E,
0x73, 0x8D, 0x74, 0x8C, 0x75, 0x8B, 0x76, 0x8A, 0x77, 0x89, 0x78, 0x88, 0x79, 0x87, 0x7A, 0x86,
0x7B, 0x85, 0x7C, 0x84, 0x7D, 0x83, 0x7E, 0x82, 0x7F, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static readonly byte[] AlphaTable = {
0x01, 0xFF, 0x02, 0xFE, 0x03, 0xFD, 0x04, 0xFC, 0x05, 0xFB, 0x06, 0xFA, 0x07, 0xF9, 0x08, 0xF8,
0x09, 0xF7, 0x0A, 0xF6, 0x0B, 0xF5, 0x0C, 0xF4, 0x0D, 0xF3, 0x0E, 0xF2, 0x0F, 0xF1, 0x10, 0xF0,
0x11, 0xEF, 0x12, 0xEE, 0x13, 0xED, 0x14, 0xEC, 0x15, 0xEB, 0x16, 0xEA, 0x17, 0xE9, 0x18, 0xE8,
0x19, 0xE7, 0x1A, 0xE6, 0x1B, 0xE5, 0x1C, 0xE4, 0x1D, 0xE3, 0x1E, 0xE2, 0x1F, 0xE1, 0x20, 0xE0,
0x21, 0xDF, 0x22, 0xDE, 0x23, 0xDD, 0x24, 0xDC, 0x25, 0xDB, 0x26, 0xDA, 0x27, 0xD9, 0x28, 0xD8,
0x29, 0xD7, 0x2A, 0xD6, 0x2B, 0xD5, 0x2C, 0xD4, 0x2D, 0xD3, 0x2E, 0xD2, 0x2F, 0xD1, 0x30, 0xD0,
0x31, 0xCF, 0x32, 0xCE, 0x33, 0xCD, 0x34, 0xCC, 0x35, 0xCB, 0x36, 0xCA, 0x37, 0xC9, 0x38, 0xC8,
0x39, 0xC7, 0x3A, 0xC6, 0x3B, 0xC5, 0x3C, 0xC4, 0x3D, 0xC3, 0x3E, 0xC2, 0x3F, 0xC1, 0x40, 0xC0,
0x41, 0xBF, 0x42, 0xBE, 0x43, 0xBD, 0x44, 0xBC, 0x45, 0xBB, 0x46, 0xBA, 0x47, 0xB9, 0x48, 0xB8,
0x49, 0xB7, 0x4A, 0xB6, 0x4B, 0xB5, 0x4C, 0xB4, 0x4D, 0xB3, 0x4E, 0xB2, 0x4F, 0xB1, 0x50, 0xB0,
0x51, 0xAF, 0x52, 0xAE, 0x53, 0xAD, 0x54, 0xAC, 0x55, 0xAB, 0x56, 0xAA, 0x57, 0xA9, 0x58, 0xA8,
0x59, 0xA7, 0x5A, 0xA6, 0x5B, 0xA5, 0x5C, 0xA4, 0x5D, 0xA3, 0x5E, 0xA2, 0x5F, 0xA1, 0x60, 0xA0,
0x61, 0x9F, 0x62, 0x9E, 0x63, 0x9D, 0x64, 0x9C, 0x65, 0x9B, 0x66, 0x9A, 0x67, 0x99, 0x68, 0x98,
0x69, 0x97, 0x6A, 0x96, 0x6B, 0x95, 0x6C, 0x94, 0x6D, 0x93, 0x6E, 0x92, 0x6F, 0x91, 0x70, 0x90,
0x71, 0x8F, 0x72, 0x8E, 0x73, 0x8D, 0x74, 0x8C, 0x75, 0x8B, 0x76, 0x8A, 0x77, 0x89, 0x78, 0x88,
0x79, 0x87, 0x7A, 0x86, 0x7B, 0x85, 0x7C, 0x84, 0x7D, 0x83, 0x7E, 0x82, 0x7F, 0x81, 0x80, 0x00,
};
static readonly byte[,] RgbBits = {
{
0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00,
0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE,
0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02,
0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00,
0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE,
0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02,
0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00,
0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE,
0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02,
0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00,
0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE,
0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02,
0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00,
0x01, 0x02, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02,
},
{
0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xFD, 0xFD, 0xFD, 0xFD,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
},
{
0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
}
};
static readonly int[] OffsetTable = {
-1, 0, 0, 1, 1, 1, -1, 1, 2, 1, -2, 1, -2, 0, 0, 2, 1, 2, -1, 2, -3, 0,
};
#endregion
}
}