diff --git a/CdgLib/CdgFileIoStream.cs b/CdgLib/CdgFileIoStream.cs
deleted file mode 100644
index 624a033..0000000
--- a/CdgLib/CdgFileIoStream.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using System.IO;
-
-namespace CdgLib
-{
- ///
- ///
- public class CdgFileIoStream
- {
- private Stream _cdgFile;
-
- ///
- ///
- public CdgFileIoStream()
- {
- _cdgFile = null;
- }
-
- ///
- /// Reads the specified buf.
- ///
- /// The buf.
- /// The buf_size.
- ///
- public int Read(ref byte[] buf, int bufSize)
- {
- return _cdgFile.Read(buf, 0, bufSize);
- }
-
- ///
- /// Writes the specified buf.
- ///
- /// The buf.
- /// The buf_size.
- ///
- public int Write(ref byte[] buf, int bufSize)
- {
- _cdgFile.Write(buf, 0, bufSize);
- return 1;
- }
-
- ///
- /// Seeks the specified offset.
- ///
- /// The offset.
- /// The whence.
- ///
- public int Seek(int offset, SeekOrigin whence)
- {
- return (int) _cdgFile.Seek(offset, whence);
- }
-
- ///
- /// EOFs this instance.
- ///
- ///
- public bool Eof()
- {
- return _cdgFile.Position >= _cdgFile.Length;
- }
-
- ///
- /// Getsizes this instance.
- ///
- ///
- public int Getsize()
- {
- return (int) _cdgFile.Length;
- }
-
- ///
- /// Opens the specified filename.
- ///
- /// The filename.
- ///
- public bool Open(string filename)
- {
- Close();
- _cdgFile = new FileStream(filename, FileMode.Open, FileAccess.Read);
- return _cdgFile != null;
- }
-
- ///
- /// Closes this instance.
- ///
- public void Close()
- {
- if (_cdgFile != null)
- {
- _cdgFile.Close();
- _cdgFile = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/CdgLib/CdgLib.csproj b/CdgLib/CdgLib.csproj
index b2b5136..82e7198 100644
--- a/CdgLib/CdgLib.csproj
+++ b/CdgLib/CdgLib.csproj
@@ -42,15 +42,12 @@
-
+
-
-
-
diff --git a/CdgLib/Extension/Extensions.cs b/CdgLib/Extension/Extensions.cs
deleted file mode 100644
index c1ea5f7..0000000
--- a/CdgLib/Extension/Extensions.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CdgLib.Extension
-{
- internal class Extensions
- {
- void tr
- }
-}
diff --git a/CdgLib/Graphic.cs b/CdgLib/Graphic.cs
index 484fca4..c057ea8 100644
--- a/CdgLib/Graphic.cs
+++ b/CdgLib/Graphic.cs
@@ -1,24 +1,30 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.Drawing.Imaging;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Runtime.InteropServices;
using CdgLib.SubCode;
namespace CdgLib
{
public class Graphic
{
+ private const int ColourTableSize = 16;
+ private const int TileHeight = 12;
+ private const int TileWidth = 6;
+ public const int FullWidth = 300;
+ public const int FullHeight = 216;
+ private readonly int[] _colourTable = new int[ColourTableSize];
+ private readonly byte[,] _pixelColours = new byte[FullHeight, FullWidth];
private int[,] _graphicData;
public Graphic(IEnumerable packets)
{
foreach (var packet in packets)
{
- packet.ApplyTransform(ref _graphicData);
+ Process(packet);
}
}
@@ -27,21 +33,339 @@ namespace CdgLib
Bitmap myBitmap;
using (var bitmapStream = new MemoryStream())
{
- foreach (var colourValue in _mPSurface.RgbData)
+ foreach (var colourValue in _graphicData)
{
var colour = BitConverter.GetBytes(colourValue);
bitmapStream.Write(colour, 0, 4);
}
- myBitmap = GraphicUtil.StreamToBitmap(bitmapStream, FullWidth, FullHeight);
+ myBitmap = StreamToBitmap(bitmapStream, FullWidth, FullHeight);
}
myBitmap.MakeTransparent(myBitmap.GetPixel(1, 1));
return myBitmap;
}
+ private Bitmap StreamToBitmap(Stream stream, int width, int height)
+ {
+ //create a new bitmap
+ var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
+ var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat);
+ stream.Seek(0, SeekOrigin.Begin);
+ //copy the stream of pixel
+ for (var n = 0; n <= stream.Length - 1; n++)
+ {
+ var myByte = new byte[1];
+ stream.Read(myByte, 0, 1);
+ Marshal.WriteByte(bmpData.Scan0, n, myByte[0]);
+ }
+ bmp.UnlockBits(bmpData);
+ return bmp;
+ }
-
+ private void Process(Packet packet)
+ {
+ if (packet.Command != Command.Graphic) return;
+ switch (packet.Instruction)
+ {
+ case Instruction.MemoryPreset:
+ MemoryPreset(packet);
+ break;
+ case Instruction.BorderPreset:
+ BorderPreset(packet);
+ break;
+ case Instruction.TileBlockNormal:
+ TileBlock(packet, false);
+ break;
+ case Instruction.ScrollPreset:
+ Scroll(packet, false);
+ break;
+ case Instruction.ScrollCopy:
+ Scroll(packet, true);
+ break;
+ case Instruction.DefineTransparentColor:
+ DefineTransparentColour(packet);
+ break;
+ case Instruction.LoadColorTableLower:
+ LoadColorTable(packet, 0);
+ break;
+ case Instruction.LoadColorTableUpper:
+ LoadColorTable(packet, 1);
+ break;
+ case Instruction.TileBlockXor:
+ TileBlock(packet, true);
+ break;
+ }
+ }
+ private void MemoryPreset(Packet packet)
+ {
+ var colour = packet.Data[0] & 0xf;
+ var repeat = packet.Data[1] & 0xf;
+
+ //we have a reliable packet stream, so the repeat command
+ //is executed only the first time
+ if (repeat == 0)
+ {
+ //Note that this may be done before any load colour table
+ //commands by some CDGs. So the load colour table itself
+ //actual recalculates the RGB values for all pixels when
+ //the colour table changes.
+
+ //Set the preset colour for every pixel. Must be stored in
+ //the pixel colour table indeces array
+ for (int rowIndex = 0; rowIndex < _pixelColours.GetLength(0); rowIndex++)
+ {
+ for (int columnIndex = 0; columnIndex < _pixelColours.GetLength(1); columnIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+ }
+
+ private void BorderPreset(Packet packet)
+ {
+ int rowIndex;
+ int columnIndex;
+
+ var colour = packet.Data[0] & 0xf;
+
+ //The border area is the area contained with a rectangle
+ //defined by (0,0,300,216) minus the interior pixels which are contained
+ //within a rectangle defined by (6,12,294,204).
+
+ for (rowIndex = 0; rowIndex < _pixelColours.GetLength(0); rowIndex++)
+ {
+ for (columnIndex = 0; columnIndex < 6; columnIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = (byte)colour;
+ }
+
+ for (columnIndex = _pixelColours.GetLength(1) - 6; columnIndex < _pixelColours.GetLength(1); columnIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+
+ for (columnIndex = 6; columnIndex < _pixelColours.GetLength(1) - 6; columnIndex++)
+ {
+ for (rowIndex = 0; rowIndex < 12; rowIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = (byte)colour;
+ }
+
+ for (rowIndex = _pixelColours.GetLength(1) - 12; rowIndex < _pixelColours.GetLength(1); rowIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+
+
+ private void LoadColorTable(Packet packet, int table)
+ {
+ for (var i = 0; i < 8; i++)
+ {
+ //[---high byte---] [---low byte----]
+ //7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+ //X X r r r r g g X X g g b b b b
+ var highByte = packet.Data[2 * i];
+ var lowByte = packet.Data[2 * i + 1];
+
+ var red = (highByte & 0x3f) >> 2;
+ var green = ((highByte & 0x3) << 2) | ((lowByte & 0x3f) >> 4);
+ var blue = lowByte & 0xf;
+
+ //4 bit colour to 8 bit colour
+ red *= 17;
+ green *= 17;
+ blue *= 17;
+
+ _colourTable[i + table*8] = Color.FromArgb(red, green, blue).ToArgb();
+ }
+ }
+
+
+ private void TileBlock(Packet packet, bool bXor)
+ {
+ var colour0 = packet.Data[0] & 0xf;
+ var colour1 = packet.Data[1] & 0xf;
+ var rowIndex = (packet.Data[2] & 0x1f) * 12;
+ var columnIndex = (packet.Data[3] & 0x3f) * 6;
+
+ if (rowIndex > FullHeight - TileHeight)
+ return;
+ if (columnIndex > FullWidth - TileWidth)
+ return;
+
+ //Set the pixel array for each of the pixels in the 12x6 tile.
+ //Normal = Set the colour to either colour0 or colour1 depending
+ //on whether the pixel value is 0 or 1.
+ //XOR = XOR the colour with the colour index currently there.
+
+
+ for (var i = 0; i <= 11; i++)
+ {
+ var myByte = packet.Data[4 + i] & 0x3f;
+ for (var j = 0; j <= 5; j++)
+ {
+ var pixel = (myByte >> (5 - j)) & 0x1;
+ var newCol = 0;
+ if (bXor)
+ {
+ //Tile Block XOR
+ var xorCol = pixel == 0 ? colour0 : colour1;
+
+ //Get the colour index currently at this location, and xor with it
+ int currentColourIndex = _pixelColours[rowIndex + i, columnIndex + j];
+ newCol = currentColourIndex ^ xorCol;
+ }
+ else
+ {
+ newCol = pixel == 0 ? colour0 : colour1;
+ }
+
+ //Set the pixel with the new colour. We set both the surfarray
+ //containing actual RGB values, as well as our array containing
+ //the colour indexes into our colour table.
+ _pixelColours[rowIndex + i, columnIndex + j] = (byte)newCol;
+ }
+ }
+ }
+
+ private void DefineTransparentColour(Packet packet)
+ {
+ //_mTransparentColour = packet.Data[0] & 0xf;
+ }
+
+
+ private void Scroll(Packet packet, bool copy)
+ {
+ //Decode the scroll command parameters
+ var colour = packet.Data[0] & 0xf;
+ var horizontalScroll = packet.Data[1] & 0x3f;
+ var verticalScroll = packet.Data[2] & 0x3f;
+
+ var horizontalScrollCommand = (horizontalScroll & 0x30) >> 4;
+ var horizontalOffset = horizontalScroll & 0x7;
+ var verticalScrollCommand = (verticalScroll & 0x30) >> 4;
+ var verticalOffset = verticalScroll & 0xf;
+
+
+ _mHOffset = horizontalOffset < 5 ? horizontalOffset : 5;
+ _mVOffset = verticalOffset < 11 ? verticalOffset : 11;
+
+ //Scroll Vertical - Calculate number of pixels
+
+ var verticalScrollPixels = 0;
+ switch (verticalScrollCommand)
+ {
+ case 2:
+ verticalScrollPixels = -12;
+ break;
+ case 1:
+ verticalScrollPixels = 12;
+ break;
+ }
+
+ //Scroll Horizontal- Calculate number of pixels
+
+ var horizontalScrollPixels = 0;
+ switch (horizontalScrollCommand)
+ {
+ case 2:
+ horizontalScrollPixels = -6;
+ break;
+ case 1:
+ horizontalScrollPixels = 6;
+ break;
+ }
+
+ if (horizontalScrollPixels == 0 && verticalScrollPixels == 0)
+ {
+ return;
+ }
+
+ //Perform the actual scroll.
+
+ var temp = new byte[FullHeight + 1, FullWidth + 1];
+ var vInc = verticalScrollPixels + FullHeight;
+ var hInc = horizontalScrollPixels + FullWidth;
+ var rowIndex = 0;
+ //row index
+ var columnIndex = 0;
+ //column index
+
+ for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
+ {
+ for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
+ {
+ temp[(rowIndex + vInc) % FullHeight, (columnIndex + hInc) % FullWidth] = _pixelColours[rowIndex, columnIndex];
+ }
+ }
+
+
+ //if copy is false, we were supposed to fill in the new pixels
+ //with a new colour. Go back and do that now.
+
+
+ if (copy == false)
+ {
+ if (verticalScrollPixels > 0)
+ {
+ for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
+ {
+ for (rowIndex = 0; rowIndex <= verticalScrollPixels - 1; rowIndex++)
+ {
+ temp[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+ else if (verticalScrollPixels < 0)
+ {
+ for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
+ {
+ for (rowIndex = FullHeight + verticalScrollPixels; rowIndex <= FullHeight - 1; rowIndex++)
+ {
+ temp[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+
+
+ if (horizontalScrollPixels > 0)
+ {
+ for (columnIndex = 0; columnIndex <= horizontalScrollPixels - 1; columnIndex++)
+ {
+ for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
+ {
+ temp[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+ else if (horizontalScrollPixels < 0)
+ {
+ for (columnIndex = FullWidth + horizontalScrollPixels; columnIndex <= FullWidth - 1; columnIndex++)
+ {
+ for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
+ {
+ temp[rowIndex, columnIndex] = (byte)colour;
+ }
+ }
+ }
+ }
+
+ //Now copy the temporary buffer back to our array
+
+ for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
+ {
+ for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
+ {
+ _pixelColours[rowIndex, columnIndex] = temp[rowIndex, columnIndex];
+ }
+ }
+ }
+
}
}
diff --git a/CdgLib/GraphicFileStream.cs b/CdgLib/GraphicFileStream.cs
new file mode 100644
index 0000000..c7e3e6d
--- /dev/null
+++ b/CdgLib/GraphicFileStream.cs
@@ -0,0 +1,46 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using CdgLib.SubCode;
+
+namespace CdgLib
+{
+ public class GraphicFileStream : FileStream
+ {
+ private const int PacketSize = 24;
+
+ public GraphicFileStream(string path) : base(path, FileMode.Open, FileAccess.Read, FileShare.Read)
+ {
+ }
+
+ public async Task> ReadFile()
+ {
+ Position = 0;
+ var subCodePackets = new List();
+ var buffer = new byte[Length];
+ var bytesRead = await ReadAsync(buffer, 0, buffer.Length);
+
+ for (var i = 0; i < bytesRead/PacketSize; i++)
+ {
+ var subCodePacket = new Packet(buffer.Skip(i*PacketSize).Take(PacketSize).ToArray());
+ subCodePackets.Add(subCodePacket);
+ }
+ return subCodePackets;
+ }
+
+ private async Task> ReadSubCodeAsync(long numberOfPackets)
+ {
+ var subCodePackets = new List();
+ var buffer = new byte[PacketSize*numberOfPackets];
+ var bytesRead = await ReadAsync(buffer, 0, buffer.Length);
+
+ for (var i = 0; i < bytesRead/PacketSize; i++)
+ {
+ var subCodePacket = new Packet(buffer.Skip(i*PacketSize).Take(PacketSize).ToArray());
+ subCodePackets.Add(subCodePacket);
+ }
+ return subCodePackets;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CdgLib/GraphicUtil.cs b/CdgLib/GraphicUtil.cs
deleted file mode 100644
index a1ba19b..0000000
--- a/CdgLib/GraphicUtil.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Runtime.InteropServices;
-
-namespace CdgLib
-{
- ///
- ///
- public class GraphicUtil
- {
- ///
- /// Bitmaps to stream.
- ///
- /// The filename.
- ///
- public static Stream BitmapToStream(string filename)
- {
- var oldBmp = (Bitmap) Image.FromFile(filename);
- var oldData = oldBmp.LockBits(new Rectangle(0, 0, oldBmp.Width, oldBmp.Height), ImageLockMode.WriteOnly,
- PixelFormat.Format24bppRgb);
- var length = oldData.Stride*oldBmp.Height;
- var stream = new byte[length];
- Marshal.Copy(oldData.Scan0, stream, 0, length);
- oldBmp.UnlockBits(oldData);
- oldBmp.Dispose();
- return new MemoryStream(stream);
- }
-
-
- ///
- /// Streams to bitmap.
- ///
- /// The stream.
- /// The width.
- /// The height.
- ///
- public static Bitmap StreamToBitmap(Stream stream, int width, int height)
- {
- //create a new bitmap
- var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
- var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat);
- stream.Seek(0, SeekOrigin.Begin);
- //copy the stream of pixel
- for (var n = 0; n <= stream.Length - 1; n++)
- {
- var myByte = new byte[1];
- stream.Read(myByte, 0, 1);
- Marshal.WriteByte(bmpData.Scan0, n, myByte[0]);
- }
- bmp.UnlockBits(bmpData);
- return bmp;
- }
-
- ///
- /// Gets the CDG size bitmap.
- ///
- /// The filename.
- ///
- public static Bitmap GetCdgSizeBitmap(string filename)
- {
- var bm = new Bitmap(filename);
- return ResizeBitmap(ref bm, GraphicsFile.FullWidth, GraphicsFile.FullHeight);
- }
-
- ///
- /// Resizes the bitmap.
- ///
- /// The bm.
- /// The width.
- /// The height.
- ///
- public static Bitmap ResizeBitmap(ref Bitmap bm, int width, int height)
- {
- var thumb = new Bitmap(width, height);
- using (bm)
- {
- using (var g = Graphics.FromImage(thumb))
- {
- g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.DrawImage(bm, new Rectangle(0, 0, width, height), new Rectangle(0, 0, bm.Width, bm.Height),
- GraphicsUnit.Pixel);
- }
- }
- return thumb;
- }
-
- ///
- /// Merges the images with transparency.
- ///
- /// The pic1.
- /// The pic2.
- ///
- public static Bitmap MergeImagesWithTransparency(Bitmap picture1, Bitmap picture2)
- {
- Bitmap mergedImage;
- var bm = new Bitmap(picture1.Width, picture1.Height);
- using (var gr = Graphics.FromImage(bm))
- {
- gr.DrawImage(picture1, 0, 0);
- picture2.MakeTransparent(picture2.GetPixel(1, 1));
- gr.DrawImage(picture2, 0, 0);
- mergedImage = bm;
- }
- return mergedImage;
- }
- }
-}
\ No newline at end of file
diff --git a/CdgLib/GraphicsFile.cs b/CdgLib/GraphicsFile.cs
index d019a2d..d38e7a5 100644
--- a/CdgLib/GraphicsFile.cs
+++ b/CdgLib/GraphicsFile.cs
@@ -1,105 +1,46 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CdgLib.SubCode;
namespace CdgLib
{
- public class GraphicsFile : FileStream
+ public class GraphicsFile
{
- private const int ColourTableSize = 16;
-
private const int PacketSize = 24;
- private const int TileHeight = 12;
- private const int TileWidth = 6;
- public const int FullWidth = 300;
- public const int FullHeight = 216;
+ private IEnumerable _packets;
- private readonly int[] _colourTable = new int[ColourTableSize];
- private readonly byte[,] _pixelColours = new byte[FullHeight, FullWidth];
-
-
- private long _previousPosition;
-
- public GraphicsFile(string path) : base(path, FileMode.Open, FileAccess.Read, FileShare.Read)
+ private GraphicsFile()
{
}
public bool Transparent => true;
- public long Duration => Length/PacketSize*1000/300;
+ public long Duration => _packets.Count()/PacketSize*1000/300;
- public async Task RenderAtTime(long position = -1)
+ public static async Task LoadAsync(string fileName)
{
- if (position < 0)
- {
- position = _previousPosition + PacketSize;
- }
+ var graphicsFile = new GraphicsFile {_packets = await LoadFileAsync(fileName)};
+ return graphicsFile;
+ }
- if (position < _previousPosition)
+ private static async Task> LoadFileAsync(string fileName)
+ {
+ using (var fileStream = new GraphicFileStream(fileName))
{
- // Reset();
+ return await fileStream.ReadFile();
}
+ }
+ public Bitmap RenderAtTime(long time)
+ {
//duration of one packet is 1/300 seconds (4 packets per sector, 75 sectors per second)
//p=t*3/10 t=p*10/3 t=milliseconds, p=packets
- var timeToRender = position - _previousPosition;
- _previousPosition += timeToRender;
- var numberOfSubCodePackets = timeToRender*3/10;
-
- var subCodePackets = await ReadSubCodeAsync(numberOfSubCodePackets);
- foreach (var subCodePacket in subCodePackets)
- {
- // ProcessPacket(subCodePacket);
- }
-
- RenderSurface();
-
-
-
- }
-
-
-
- private async Task> ReadSubCodeAsync(long numberOfPackets)
- {
- var subCodePackets = new List();
- var buffer = new byte[PacketSize*numberOfPackets];
- var bytesRead = await ReadAsync(buffer, 0, buffer.Length);
-
- for (var i = 0; i < bytesRead/PacketSize; i++)
- {
- var subCodePacket = new Packet(buffer.Skip(i* PacketSize).Take(PacketSize).ToArray());
- subCodePackets.Add(subCodePacket);
- }
- return subCodePackets;
- }
-
-
-
- private void RenderSurface()
- {
- if (_mPSurface == null)
- return;
- for (var ri = 0; ri <= FullHeight - 1; ri++)
- {
- for (var ci = 0; ci <= FullWidth - 1; ci++)
- {
- if (ri < TileHeight || ri >= FullHeight - TileHeight || ci < TileWidth ||
- ci >= FullWidth - TileWidth)
- {
- // _mPSurface.RgbData[ri, ci] = _colourTable[_mBorderColourIndex];
- }
- else
- {
- _mPSurface.RgbData[ri, ci] = _colourTable[_pixelColours[ri + _mVOffset, ci + _mHOffset]];
- }
- }
- }
+ var numberOfSubCodePackets = (int) (time*3/10);
+ var graphic = new Graphic(_packets.Take(numberOfSubCodePackets));
+ var image = graphic.ToBitmap();
+ return image;
}
}
}
\ No newline at end of file
diff --git a/CdgLib/SubCode/Packet.cs b/CdgLib/SubCode/Packet.cs
index 4c89639..2b2bb09 100644
--- a/CdgLib/SubCode/Packet.cs
+++ b/CdgLib/SubCode/Packet.cs
@@ -4,340 +4,19 @@ namespace CdgLib.SubCode
{
public class Packet
{
- public Command Command { get; }
-
- public Instruction Instruction { get; }
-
- public byte[] ParityQ { get; } = new byte[2];
-
- public byte[] Data { get; } = new byte[16];
-
- public byte[] ParityP { get; } = new byte[4];
-
-
public Packet(byte[] data)
{
- Command = (Command)(data[0] & 0x3F);
- Instruction = (Instruction)(data[1] & 0x3F);
+ Command = (Command) (data[0] & 0x3F);
+ Instruction = (Instruction) (data[1] & 0x3F);
Array.Copy(data, 2, ParityQ, 0, 2);
Array.Copy(data, 4, Data, 0, 16);
Array.Copy(data, 20, ParityP, 0, 4);
}
- public void ApplyTransform(int[,] data)
- {
- if (Command != Command.Graphic) return;
- switch (Instruction)
- {
- case Instruction.MemoryPreset:
- MemoryPreset(data);
- break;
- case Instruction.BorderPreset:
- BorderPreset(data);
- break;
- case Instruction.TileBlockNormal:
- TileBlock(data,false);
- break;
- case Instruction.ScrollPreset:
- Scroll(data,false);
- break;
- case Instruction.ScrollCopy:
- Scroll(data,true);
- break;
- case Instruction.DefineTransparentColor:
- DefineTransparentColour(data);
- break;
- case Instruction.LoadColorTableLower:
- LoadColorTable(data,0);
- break;
- case Instruction.LoadColorTableUpper:
- LoadColorTable(data,1);
- break;
- case Instruction.TileBlockXor:
- TileBlock(data,true);
- break;
- }
- }
-
-
- private void MemoryPreset(int[,] data)
- {
- var colour = Data[0] & 0xf;
- var repeat = Data[1] & 0xf;
-
- //we have a reliable data stream, so the repeat command
- //is executed only the first time
- if (repeat == 0)
- {
- //Note that this may be done before any load colour table
- //commands by some CDGs. So the load colour table itself
- //actual recalculates the RGB values for all pixels when
- //the colour table changes.
-
- //Set the preset colour for every pixel. Must be stored in
- //the pixel colour table indeces array
- for (int rowIndex = 0; rowIndex < data.GetLength(0); rowIndex++)
- {
- for (int columnIndex = 0; columnIndex < data.GetLength(1); columnIndex++)
- {
- data[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
- }
-
- private void BorderPreset(int[,] data)
- {
- int rowIndex;
- int columnIndex;
-
- var colour = Data[0] & 0xf;
-
- //The border area is the area contained with a rectangle
- //defined by (0,0,300,216) minus the interior pixels which are contained
- //within a rectangle defined by (6,12,294,204).
-
- for (rowIndex = 0; rowIndex < data.GetLength(0); rowIndex++)
- {
- for (columnIndex = 0; columnIndex < 6; columnIndex++)
- {
- data[rowIndex, columnIndex] = (byte) colour;
- }
-
- for (columnIndex = data.GetLength(1) - 6; columnIndex < data.GetLength(1); columnIndex++)
- {
- data[rowIndex, columnIndex] = (byte) colour;
- }
- }
-
- for (columnIndex = 6; columnIndex < data.GetLength(1) - 6; columnIndex++)
- {
- for (rowIndex = 0; rowIndex < 12; rowIndex++)
- {
- data[rowIndex, columnIndex] = (byte) colour;
- }
-
- for (rowIndex = data.GetLength(1) - 12; rowIndex < data.GetLength(1); rowIndex++)
- {
- data[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
-
-
- private void LoadColorTable(int[,] data,int table)
- {
- for (var i = 0; i < 8; i++)
- {
- //[---high byte---] [---low byte----]
- //7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
- //X X r r r r g g X X g g b b b b
-
- var byte0 = Data[2*i];
- var byte1 = Data[2*i + 1];
- var red = (byte0 & 0x3f) >> 2;
- var green = ((byte0 & 0x3) << 2) | ((byte1 & 0x3f) >> 4);
- var blue = byte1 & 0xf;
-
- red *= 17;
- green *= 17;
- blue *= 17;
-
- if (_mPSurface != null)
- {
- _mColourTable[i + table*8] = _mPSurface.MapRgbColour(red, green, blue);
- }
- }
- }
-
-
- private void TileBlock(int[,] data,bool bXor)
- {
- var colour0 = 0;
- var colour1 = 0;
- var columnIndex = 0;
- var rowIndex = 0;
- var myByte = 0;
- var pixel = 0;
- var xorCol = 0;
- var currentColourIndex = 0;
- var newCol = 0;
-
- colour0 = pack.Data[0] & 0xf;
- colour1 = pack.Data[1] & 0xf;
- rowIndex = (pack.Data[2] & 0x1f)*12;
- columnIndex = (pack.Data[3] & 0x3f)*6;
-
- if (rowIndex > FullHeight - TileHeight)
- return;
- if (columnIndex > FullWidth - TileWidth)
- return;
-
- //Set the pixel array for each of the pixels in the 12x6 tile.
- //Normal = Set the colour to either colour0 or colour1 depending
- //on whether the pixel value is 0 or 1.
- //XOR = XOR the colour with the colour index currently there.
-
-
- for (var i = 0; i <= 11; i++)
- {
- myByte = pack.Data[4 + i] & 0x3f;
- for (var j = 0; j <= 5; j++)
- {
- pixel = (myByte >> (5 - j)) & 0x1;
- if (bXor)
- {
- //Tile Block XOR
- xorCol = pixel == 0 ? colour0 : colour1;
-
- //Get the colour index currently at this location, and xor with it
- currentColourIndex = _mPixelColours[rowIndex + i, columnIndex + j];
- newCol = currentColourIndex ^ xorCol;
- }
- else
- {
- newCol = pixel == 0 ? colour0 : colour1;
- }
-
- //Set the pixel with the new colour. We set both the surfarray
- //containing actual RGB values, as well as our array containing
- //the colour indexes into our colour table.
- _mPixelColours[rowIndex + i, columnIndex + j] = (byte) newCol;
- }
- }
- }
-
- private void DefineTransparentColour(int[,] data)
- {
- _mTransparentColour = Data[0] & 0xf;
- }
-
-
- private void Scroll(int[,] data,bool copy)
- {
- //Decode the scroll command parameters
- var colour = Data[0] & 0xf;
- var horizontalScroll = Data[1] & 0x3f;
- var verticalScroll = Data[2] & 0x3f;
-
- var horizontalScrollCommand = (horizontalScroll & 0x30) >> 4;
- var horizontalOffset = horizontalScroll & 0x7;
- var verticalScrollCommand = (verticalScroll & 0x30) >> 4;
- var verticalOffset = verticalScroll & 0xf;
-
-
- _mHOffset = horizontalOffset < 5 ? horizontalOffset : 5;
- _mVOffset = verticalOffset < 11 ? verticalOffset : 11;
-
- //Scroll Vertical - Calculate number of pixels
-
- var verticalScrollPixels = 0;
- switch (verticalScrollCommand)
- {
- case 2:
- verticalScrollPixels = -12;
- break;
- case 1:
- verticalScrollPixels = 12;
- break;
- }
-
- //Scroll Horizontal- Calculate number of pixels
-
- var horizontalScrollPixels = 0;
- switch (horizontalScrollCommand)
- {
- case 2:
- horizontalScrollPixels = -6;
- break;
- case 1:
- horizontalScrollPixels = 6;
- break;
- }
-
- if (horizontalScrollPixels == 0 && verticalScrollPixels == 0)
- {
- return;
- }
-
- //Perform the actual scroll.
-
- var temp = new byte[FullHeight + 1, FullWidth + 1];
- var vInc = verticalScrollPixels + FullHeight;
- var hInc = horizontalScrollPixels + FullWidth;
- var rowIndex = 0;
- //row index
- var columnIndex = 0;
- //column index
-
- for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
- {
- for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
- {
- temp[(rowIndex + vInc)%FullHeight, (columnIndex + hInc)%FullWidth] = _mPixelColours[rowIndex, columnIndex];
- }
- }
-
-
- //if copy is false, we were supposed to fill in the new pixels
- //with a new colour. Go back and do that now.
-
-
- if (copy == false)
- {
- if (verticalScrollPixels > 0)
- {
- for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
- {
- for (rowIndex = 0; rowIndex <= verticalScrollPixels - 1; rowIndex++)
- {
- temp[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
- else if (verticalScrollPixels < 0)
- {
- for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
- {
- for (rowIndex = FullHeight + verticalScrollPixels; rowIndex <= FullHeight - 1; rowIndex++)
- {
- temp[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
-
-
- if (horizontalScrollPixels > 0)
- {
- for (columnIndex = 0; columnIndex <= horizontalScrollPixels - 1; columnIndex++)
- {
- for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
- {
- temp[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
- else if (horizontalScrollPixels < 0)
- {
- for (columnIndex = FullWidth + horizontalScrollPixels; columnIndex <= FullWidth - 1; columnIndex++)
- {
- for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
- {
- temp[rowIndex, columnIndex] = (byte) colour;
- }
- }
- }
- }
-
- //Now copy the temporary buffer back to our array
-
- for (rowIndex = 0; rowIndex <= FullHeight - 1; rowIndex++)
- {
- for (columnIndex = 0; columnIndex <= FullWidth - 1; columnIndex++)
- {
- _mPixelColours[rowIndex, columnIndex] = temp[rowIndex, columnIndex];
- }
- }
- }
+ public Command Command { get; }
+ public Instruction Instruction { get; }
+ public byte[] ParityQ { get; } = new byte[2];
+ public byte[] Data { get; } = new byte[16];
+ public byte[] ParityP { get; } = new byte[4];
}
}
\ No newline at end of file
diff --git a/CdgLib/Surface.cs b/CdgLib/Surface.cs
deleted file mode 100644
index dfad705..0000000
--- a/CdgLib/Surface.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Drawing;
-
-namespace CdgLib
-{
- public class Surface
- {
- public int[,] RgbData = new int[GraphicsFile.FullHeight, GraphicsFile.FullWidth];
-
- public int MapRgbColour(int red, int green, int blue)
- {
- return Color.FromArgb(red, green, blue).ToArgb();
- }
- }
-}
\ No newline at end of file