mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-03-21 09:11:20 +00:00
124 lines
4.1 KiB
C#
Executable file
124 lines
4.1 KiB
C#
Executable file
using System;
|
|
using System.Collections.Generic;
|
|
using Microsoft.Xna.Framework;
|
|
using System.IO;
|
|
using FSO.Files.Utils;
|
|
|
|
namespace FSO.Files.Formats.IFF.Chunks
|
|
{
|
|
public static class SPR2FrameEncoder
|
|
{
|
|
|
|
public delegate Color[] QuantizerFunction(SPR2Frame frame, out byte[] bytes);
|
|
|
|
public static QuantizerFunction QuantizeFrame;
|
|
|
|
public static void WriteFrame(SPR2Frame frame, IoWriter output)
|
|
{
|
|
var bytes = frame.PalData;
|
|
var col = frame.PixelData;
|
|
var zs = frame.ZBufferData;
|
|
|
|
int index = 0;
|
|
int blankLines = 0;
|
|
for (int y=0; y<frame.Height; y++)
|
|
{
|
|
byte lastCmd = 0;
|
|
List<byte> dataBuf = new List<byte>();
|
|
int rlecount = 0;
|
|
bool anySolid = false;
|
|
|
|
var scanStream = new MemoryStream();
|
|
var scanOut = IoWriter.FromStream(scanStream, ByteOrder.LITTLE_ENDIAN);
|
|
|
|
for (int x=0; x<frame.Width; x++)
|
|
{
|
|
byte plt = bytes[index];
|
|
byte a = col[index].A;
|
|
byte z = zs[index];
|
|
|
|
var cmd = getCmd(plt, a, z);
|
|
|
|
if (x == 0 || cmd != lastCmd)
|
|
{
|
|
if (x != 0)
|
|
{
|
|
//write a command to write the last sequence of pixels
|
|
scanOut.WriteUInt16((ushort)(((int)lastCmd<<13)|rlecount));
|
|
if ((dataBuf.Count % 2) != 0) dataBuf.Add(0);
|
|
scanOut.WriteBytes(dataBuf.ToArray());
|
|
dataBuf.Clear();
|
|
}
|
|
|
|
lastCmd = cmd;
|
|
rlecount = 0;
|
|
}
|
|
|
|
switch (cmd)
|
|
{
|
|
case 0x1:
|
|
case 0x2:
|
|
dataBuf.Add(z);
|
|
dataBuf.Add(plt);
|
|
if (cmd == 0x2) dataBuf.Add((byte)Math.Ceiling(a/ 8.2258064516129032258064516129032));
|
|
anySolid = true;
|
|
break;
|
|
case 0x6:
|
|
dataBuf.Add(plt);
|
|
anySolid = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
rlecount++;
|
|
|
|
index++;
|
|
}
|
|
|
|
if (anySolid)
|
|
{
|
|
//write a command to write the last sequence of pixels
|
|
scanOut.WriteUInt16((ushort)(((int)lastCmd << 13) | rlecount));
|
|
if ((dataBuf.Count % 2) != 0) dataBuf.Add(0);
|
|
scanOut.WriteBytes(dataBuf.ToArray());
|
|
dataBuf.Clear();
|
|
}
|
|
|
|
var scanData = scanStream.ToArray();
|
|
|
|
if (scanData.Length == 0)
|
|
blankLines++; //line is transparent
|
|
else
|
|
{
|
|
if (blankLines > 0)
|
|
{
|
|
//add transparent lines before our new command
|
|
output.WriteUInt16((ushort)((0x4<<13) | blankLines));
|
|
blankLines = 0;
|
|
}
|
|
output.WriteUInt16((ushort)(scanData.Length+2));
|
|
output.WriteBytes(scanData);
|
|
}
|
|
|
|
}
|
|
|
|
if (blankLines > 0)
|
|
{
|
|
//add transparent lines before our new command
|
|
output.WriteUInt16((ushort)((0x4 << 13) | blankLines));
|
|
blankLines = 0;
|
|
}
|
|
output.WriteUInt16((ushort)(0x5<<13));
|
|
|
|
return;
|
|
}
|
|
|
|
private static byte getCmd(byte col, byte a, byte z)
|
|
{
|
|
if (a == 0) return 0x03; //transparent fill
|
|
else if (a < 255) return 0x02; // col,a,z
|
|
else if (z > 0) return 0x01; // col,z
|
|
else return 0x06; // col
|
|
}
|
|
}
|
|
}
|