private void Decode(IoBuffer io)
{
var y = 0;
var endmarker = false;
var hasPixels = (this.Flags & 0x01) == 0x01;
var hasZBuffer = (this.Flags & 0x02) == 0x02;
var hasAlpha = (this.Flags & 0x04) == 0x04;
var numPixels = this.Width * this.Height;
if (hasPixels){
this.PixelData = new Color[numPixels];
this.PalData = new byte[numPixels];
}
if (hasZBuffer){
this.ZBufferData = new byte[numPixels];
}
if (hasAlpha){
this.AlphaData = new byte[numPixels];
}
var palette = Parent.ChunkParent.Get<PALT>(this.PaletteID);
if (palette == null) palette = new PALT() { Colors = new Color[256] };
palette.References++;
var transparentPixel = palette.Colors[TransparentColorIndex];
transparentPixel.A = 0;
while (!endmarker)
{
var marker = io.ReadUInt16();
var command = marker >> 13;
var count = marker & 0x1FFF;
switch (command)
{
/** Fill with pixel data **/
case 0x00:
var bytes = count;
bytes -= 2;
var x = 0;
while (bytes > 0)
{
var pxMarker = io.ReadUInt16();
var pxCommand = pxMarker >> 13;
var pxCount = pxMarker & 0x1FFF;
bytes -= 2;
switch (pxCommand)
{
case 0x01:
case 0x02:
var pxWithAlpha = pxCommand == 0x02;
for (var col = 0; col < pxCount; col++)
{
var zValue = io.ReadByte();
var pxValue = io.ReadByte();
bytes -= 2;
var pxColor = palette.Colors[pxValue];
if (pxWithAlpha)
{
var alpha = io.ReadByte();
pxColor.A = (byte)(alpha * 8.2258064516129032258064516129032);
bytes--;
}
//this mode draws the transparent colour as solid for some reason.
//fixes backdrop theater
var offset = (y * Width) + x;
this.PixelData[offset] = pxColor;
this.PalData[offset] = pxValue;
this.ZBufferData[offset] = zValue;
x++;
}
if (pxWithAlpha)
{
/** Padding? **/
if ((pxCount * 3) % 2 != 0){
bytes--;
io.ReadByte();
}
}
break;
case 0x03:
for (var col = 0; col < pxCount; col++)
{
var offset = (y * Width) + x;
this.PixelData[offset] = transparentPixel;
this.PalData[offset] = (byte)TransparentColorIndex;
this.PixelData[offset].A = 0;
if (hasZBuffer){
this.ZBufferData[offset] = 255;
}
x++;
}
break;
case 0x06:
for (var col = 0; col < pxCount; col++)
{
var pxIndex = io.ReadByte();
bytes--;
var offset = (y * Width) + x;
var pxColor = palette.Colors[pxIndex];
byte z = 0;
//not sure if this should happen
/*if (pxIndex == TransparentColorIndex)
{
pxColor.A = 0;
z = 255;
}*/
this.PixelData[offset] = pxColor;
this.PalData[offset] = pxIndex;
if (hasZBuffer)
{
this.ZBufferData[offset] = z;
}
x++;
}
if (pxCount % 2 != 0)
{
bytes--;
io.ReadByte();
}
break;
}
}
/** If row isnt filled in, the rest is transparent **/
while (x < Width)
{
var offset = (y * Width) + x;
if (hasZBuffer)
{
this.ZBufferData[offset] = 255;
}
x++;
}
break;
/** Leave the next count rows in the color channel filled with the transparent color,
* in the z-buffer channel filled with 255, and in the alpha channel filled with 0. **/
case 0x04:
for (var row = 0; row < count; row++)
{
for (var col = 0; col < Width; col++)
{
var offset = ((y+row) * Width) + col;
if (hasPixels)
{
this.PixelData[offset] = transparentPixel;
this.PalData[offset] = (byte)TransparentColorIndex;
}
if (hasAlpha)
{
this.PixelData[offset].A = 0;
}
if (hasZBuffer)
{
ZBufferData[offset] = 255;
}
}
}
y += count - 1;
break;
case 0x05:
endmarker = true;
break;
}
y++;
}
}