diff --git a/CdgLib/CdgLib.csproj b/CdgLib/CdgLib.csproj
index 56f3a50..402b69e 100644
--- a/CdgLib/CdgLib.csproj
+++ b/CdgLib/CdgLib.csproj
@@ -42,9 +42,12 @@
-
+
+
+
-
+
+
diff --git a/CdgLib/CDGFile.cs b/CdgLib/Graphic.cs
similarity index 62%
rename from CdgLib/CDGFile.cs
rename to CdgLib/Graphic.cs
index 20bd18e..587111d 100644
--- a/CdgLib/CDGFile.cs
+++ b/CdgLib/Graphic.cs
@@ -1,80 +1,40 @@
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 CdgLib.SubCode;
namespace CdgLib
{
- public class CdgFile : FileStream
+ public class Graphic
{
- private const int ColourTableSize = 16;
- private const byte CdgCommand = 0x9;
- private const int CdgInstMemoryPreset = 1;
- private const int CdgInstBorderPreset = 2;
- private const int CdgInstTileBlock = 6;
- private const int CdgInstScrollPreset = 20;
- private const int CdgInstScrollCopy = 24;
- private const int CdgInstDefTranspCol = 28;
- private const int CdgInstLoadColTblLo = 30;
- private const int CdgInstLoadColTblHigh = 31;
- private const int CdgInstTileBlockXor = 38;
- private const byte CdgMask = 0x3f;
- private const int CdgPacketSize = 24;
- private const int TileHeight = 12;
- private const int TileWidth = 6;
- public const int FullWidth = 300;
- public const int FullHeight = 216;
- private const int CdgDisplayWidth = 294;
- private const int CdgDisplayHeight = 204;
- private readonly int[] _mColourTable = new int[ColourTableSize];
- private readonly byte[,] _mPixelColours = new byte[FullHeight, FullWidth];
+ private int _mPresetColourIndex;
private int _mBorderColourIndex;
+
private long _mDuration;
private int _mHOffset;
private Bitmap _mImage;
- private int _mPresetColourIndex;
+
private CdgFileIoStream _mPStream;
private readonly Surface _mPSurface;
private int _mTransparentColour;
private int _mVOffset;
- private long _previousPosition;
- public CdgFile(string path, FileMode mode, FileAccess fileAccess) : base(path, mode, fileAccess, FileShare.Read)
+ private const byte Command = 0x9;
+ private const byte CdgMask = 0x3f;
+ private const int CdgDisplayWidth = 294;
+ private const int CdgDisplayHeight = 204;
+ private int[,] _graphicData;
+ public Graphic(IEnumerable packets)
{
- _mPSurface = new Surface();
+
}
- public bool Transparent => true;
-
- public long Duration => Length/CdgPacketSize*1000/300;
-
- public async Task Render(long position = -1)
+ public Bitmap ToBitmap()
{
- if (position < 0)
- {
- position = _previousPosition + CdgPacketSize;
- }
-
- if (position < _previousPosition)
- {
- Reset();
- }
-
- //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();
Bitmap myBitmap;
using (var bitmapStream = new MemoryStream())
{
@@ -85,95 +45,50 @@ namespace CdgLib
}
myBitmap = GraphicUtil.StreamToBitmap(bitmapStream, FullWidth, FullHeight);
}
-
- if (Transparent)
- {
- myBitmap.MakeTransparent(myBitmap.GetPixel(1, 1));
- }
+ myBitmap.MakeTransparent(myBitmap.GetPixel(1, 1));
+
return myBitmap;
-
- }
-
- private void Reset()
- {
- Position = 0;
- Array.Clear(_mPixelColours, 0, _mPixelColours.Length);
- Array.Clear(_mColourTable, 0, _mColourTable.Length);
-
- _mPresetColourIndex = 0;
- _mBorderColourIndex = 0;
- _mTransparentColour = 0;
- _mHOffset = 0;
- _mVOffset = 0;
-
- _mDuration = 0;
- _previousPosition = 0;
-
- //clear surface
- if (_mPSurface.RgbData != null)
- {
- Array.Clear(_mPSurface.RgbData, 0, _mPSurface.RgbData.Length);
- }
- }
-
- private async Task> ReadSubCodeAsync(long numberOfPackets)
- {
- var subCodePackets = new List();
- var buffer = new byte[CdgPacketSize*numberOfPackets];
- var bytesRead = await ReadAsync(buffer, 0, buffer.Length);
-
- for (var i = 0; i < bytesRead/CdgPacketSize; i++)
- {
- var subCodePacket = new SubCodePacket();
- Array.Copy(buffer, i*CdgPacketSize + 0, subCodePacket.Command, 0, 1);
- Array.Copy(buffer, i*CdgPacketSize + 1, subCodePacket.Instruction, 0, 1);
- Array.Copy(buffer, i*CdgPacketSize + 2, subCodePacket.ParityQ, 0, 2);
- Array.Copy(buffer, i*CdgPacketSize + 4, subCodePacket.Data, 0, 16);
- Array.Copy(buffer, i*CdgPacketSize + 20, subCodePacket.ParityP, 0, 4);
- subCodePackets.Add(subCodePacket);
- }
- return subCodePackets;
}
- private void ProcessPacket(SubCodePacket subCodePacketPacket)
+ private void ProcessPacket(Packet packetPacket)
{
- if ((subCodePacketPacket.Command[0] & CdgMask) != CdgCommand) return;
- var instructionCode = subCodePacketPacket.Instruction[0] & CdgMask;
+ if ((packetPacket.Command[0] & CdgMask) != Command) return;
+ var instructionCode = (Instruction)(packetPacket.Instruction[0] & CdgMask);
switch (instructionCode)
{
- case CdgInstMemoryPreset:
- MemoryPreset(subCodePacketPacket);
+ case Instruction.MemoryPreset:
+ MemoryPreset(packetPacket);
break;
- case CdgInstBorderPreset:
- BorderPreset(subCodePacketPacket);
+ case Instruction.BorderPreset:
+ BorderPreset(packetPacket);
break;
- case CdgInstTileBlock:
- TileBlock(subCodePacketPacket, false);
+ case Instruction.TileBlockNormal:
+ TileBlock(packetPacket, false);
break;
- case CdgInstScrollPreset:
- Scroll(subCodePacketPacket, false);
+ case Instruction.ScrollPreset:
+ Scroll(packetPacket, false);
break;
- case CdgInstScrollCopy:
- Scroll(subCodePacketPacket, true);
+ case Instruction.ScrollCopy:
+ Scroll(packetPacket, true);
break;
- case CdgInstDefTranspCol:
- DefineTransparentColour(subCodePacketPacket);
+ case Instruction.DefineTransparentColor:
+ DefineTransparentColour(packetPacket);
break;
- case CdgInstLoadColTblLo:
- LoadColorTable(subCodePacketPacket, 0);
+ case Instruction.LoadColorTableLower:
+ LoadColorTable(packetPacket, 0);
break;
- case CdgInstLoadColTblHigh:
- LoadColorTable(subCodePacketPacket, 1);
+ case Instruction.LoadColorTableUpper:
+ LoadColorTable(packetPacket, 1);
break;
- case CdgInstTileBlockXor:
- TileBlock(subCodePacketPacket, true);
+ case Instruction.TileBlockXor:
+ TileBlock(packetPacket, true);
break;
}
}
- private void MemoryPreset(SubCodePacket pack)
+ private void MemoryPreset(Packet pack)
{
var colour = 0;
var ri = 0;
@@ -206,14 +121,34 @@ namespace CdgLib
{
for (ci = 0; ci <= FullWidth - 1; ci++)
{
- _mPixelColours[ri, ci] = (byte) colour;
+ _mPixelColours[ri, ci] = (byte)colour;
}
}
}
}
+ private void Reset()
+ {
+ Position = 0;
+ Array.Clear(_mPixelColours, 0, _mPixelColours.Length);
+ Array.Clear(_mColourTable, 0, _mColourTable.Length);
- private void BorderPreset(SubCodePacket pack)
+ _mBorderColourIndex = 0;
+ _mTransparentColour = 0;
+ _mHOffset = 0;
+ _mVOffset = 0;
+
+ _mDuration = 0;
+ _previousPosition = 0;
+
+ //clear surface
+ if (_mPSurface.RgbData != null)
+ {
+ Array.Clear(_mPSurface.RgbData, 0, _mPSurface.RgbData.Length);
+ }
+ }
+
+ private void BorderPreset(Packet pack)
{
var colour = 0;
var ri = 0;
@@ -230,12 +165,12 @@ namespace CdgLib
{
for (ci = 0; ci <= 5; ci++)
{
- _mPixelColours[ri, ci] = (byte) colour;
+ _mPixelColours[ri, ci] = (byte)colour;
}
for (ci = FullWidth - 6; ci <= FullWidth - 1; ci++)
{
- _mPixelColours[ri, ci] = (byte) colour;
+ _mPixelColours[ri, ci] = (byte)colour;
}
}
@@ -243,18 +178,18 @@ namespace CdgLib
{
for (ri = 0; ri <= 11; ri++)
{
- _mPixelColours[ri, ci] = (byte) colour;
+ _mPixelColours[ri, ci] = (byte)colour;
}
for (ri = FullHeight - 12; ri <= FullHeight - 1; ri++)
{
- _mPixelColours[ri, ci] = (byte) colour;
+ _mPixelColours[ri, ci] = (byte)colour;
}
}
}
- private void LoadColorTable(SubCodePacket pack, int table)
+ private void LoadColorTable(Packet pack, int table)
{
for (var i = 0; i <= 7; i++)
{
@@ -262,8 +197,8 @@ namespace CdgLib
//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 = pack.Data[2*i];
- var byte1 = pack.Data[2*i + 1];
+ var byte0 = pack.Data[2 * i];
+ var byte1 = pack.Data[2 * i + 1];
var red = (byte0 & 0x3f) >> 2;
var green = ((byte0 & 0x3) << 2) | ((byte1 & 0x3f) >> 4);
var blue = byte1 & 0xf;
@@ -274,13 +209,13 @@ namespace CdgLib
if (_mPSurface != null)
{
- _mColourTable[i + table*8] = _mPSurface.MapRgbColour(red, green, blue);
+ _mColourTable[i + table * 8] = _mPSurface.MapRgbColour(red, green, blue);
}
}
}
- private void TileBlock(SubCodePacket pack, bool bXor)
+ private void TileBlock(Packet pack, bool bXor)
{
var colour0 = 0;
var colour1 = 0;
@@ -294,8 +229,8 @@ namespace CdgLib
colour0 = pack.Data[0] & 0xf;
colour1 = pack.Data[1] & 0xf;
- rowIndex = (pack.Data[2] & 0x1f)*12;
- columnIndex = (pack.Data[3] & 0x3f)*6;
+ rowIndex = (pack.Data[2] & 0x1f) * 12;
+ columnIndex = (pack.Data[3] & 0x3f) * 6;
if (rowIndex > FullHeight - TileHeight)
return;
@@ -345,18 +280,18 @@ namespace CdgLib
//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;
+ _mPixelColours[rowIndex + i, columnIndex + j] = (byte)newCol;
}
}
}
- private void DefineTransparentColour(SubCodePacket pack)
+ private void DefineTransparentColour(Packet pack)
{
_mTransparentColour = pack.Data[0] & 0xf;
}
- private void Scroll(SubCodePacket pack, bool copy)
+ private void Scroll(Packet pack, bool copy)
{
var colour = 0;
var hScroll = 0;
@@ -425,7 +360,7 @@ namespace CdgLib
{
for (ci = 0; ci <= FullWidth - 1; ci++)
{
- temp[(ri + vInc)%FullHeight, (ci + hInc)%FullWidth] = _mPixelColours[ri, ci];
+ temp[(ri + vInc) % FullHeight, (ci + hInc) % FullWidth] = _mPixelColours[ri, ci];
}
}
@@ -442,7 +377,7 @@ namespace CdgLib
{
for (ri = 0; ri <= vScrollPixels - 1; ri++)
{
- temp[ri, ci] = (byte) colour;
+ temp[ri, ci] = (byte)colour;
}
}
}
@@ -452,7 +387,7 @@ namespace CdgLib
{
for (ri = FullHeight + vScrollPixels; ri <= FullHeight - 1; ri++)
{
- temp[ri, ci] = (byte) colour;
+ temp[ri, ci] = (byte)colour;
}
}
}
@@ -464,7 +399,7 @@ namespace CdgLib
{
for (ri = 0; ri <= FullHeight - 1; ri++)
{
- temp[ri, ci] = (byte) colour;
+ temp[ri, ci] = (byte)colour;
}
}
}
@@ -474,7 +409,7 @@ namespace CdgLib
{
for (ri = 0; ri <= FullHeight - 1; ri++)
{
- temp[ri, ci] = (byte) colour;
+ temp[ri, ci] = (byte)colour;
}
}
}
@@ -490,26 +425,5 @@ namespace CdgLib
}
}
}
-
- 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] = _mColourTable[_mBorderColourIndex];
- }
- else
- {
- _mPSurface.RgbData[ri, ci] = _mColourTable[_mPixelColours[ri + _mVOffset, ci + _mHOffset]];
- }
- }
- }
- }
}
-}
\ No newline at end of file
+}
diff --git a/CdgLib/GraphicUtil.cs b/CdgLib/GraphicUtil.cs
index e40ff02..a1ba19b 100644
--- a/CdgLib/GraphicUtil.cs
+++ b/CdgLib/GraphicUtil.cs
@@ -61,7 +61,7 @@ namespace CdgLib
public static Bitmap GetCdgSizeBitmap(string filename)
{
var bm = new Bitmap(filename);
- return ResizeBitmap(ref bm, CdgFile.FullWidth, CdgFile.FullHeight);
+ return ResizeBitmap(ref bm, GraphicsFile.FullWidth, GraphicsFile.FullHeight);
}
///
diff --git a/CdgLib/SubCode/Command.cs b/CdgLib/SubCode/Command.cs
new file mode 100644
index 0000000..1e9568e
--- /dev/null
+++ b/CdgLib/SubCode/Command.cs
@@ -0,0 +1,7 @@
+namespace CdgLib.SubCode
+{
+ internal enum Command : byte
+ {
+ Graphic = 0x9
+ }
+}
diff --git a/CdgLib/SubCode/Instruction.cs b/CdgLib/SubCode/Instruction.cs
new file mode 100644
index 0000000..ed0e1b6
--- /dev/null
+++ b/CdgLib/SubCode/Instruction.cs
@@ -0,0 +1,45 @@
+namespace CdgLib.SubCode
+{
+ ///
+ ///
+ ///
+ internal enum Instruction
+ {
+ ///
+ /// Set the screen to a particular color.
+ ///
+ MemoryPreset = 1,
+ ///
+ /// Set the border of the screen to a particular color.
+ ///
+ BorderPreset = 2,
+ ///
+ /// Load a 12 x 6, 2 color tile and display it normally.
+ ///
+ TileBlockNormal = 6,
+ ///
+ /// Scroll the image, filling in the new area with a color.
+ ///
+ ScrollPreset = 20,
+ ///
+ /// Scroll the image, rotating the bits back around.
+ ///
+ ScrollCopy = 24,
+ ///
+ /// Define a specific color as being transparent.
+ ///
+ DefineTransparentColor = 28,
+ ///
+ /// (entries 0-7) Load in the lower 8 entries of the color table.
+ ///
+ LoadColorTableLower = 30,
+ ///
+ /// (entries 8-15) Load in the upper 8 entries of the color table.
+ ///
+ LoadColorTableUpper = 31,
+ ///
+ /// Load a 12 x 6, 2 color tile and display it using the XOR method.
+ ///
+ TileBlockXor = 38
+ }
+}
\ No newline at end of file
diff --git a/CdgLib/SubCodePacket.cs b/CdgLib/SubCode/Packet.cs
similarity index 82%
rename from CdgLib/SubCodePacket.cs
rename to CdgLib/SubCode/Packet.cs
index 9bf23bf..c0df716 100644
--- a/CdgLib/SubCodePacket.cs
+++ b/CdgLib/SubCode/Packet.cs
@@ -1,6 +1,6 @@
-namespace CdgLib
+namespace CdgLib.SubCode
{
- public class SubCodePacket
+ public class Packet
{
public byte[] Command = new byte[1];
public byte[] Data = new byte[16];
diff --git a/CdgLib/Surface.cs b/CdgLib/Surface.cs
index 6c3467a..dfad705 100644
--- a/CdgLib/Surface.cs
+++ b/CdgLib/Surface.cs
@@ -4,7 +4,7 @@ namespace CdgLib
{
public class Surface
{
- public int[,] RgbData = new int[CdgFile.FullHeight, CdgFile.FullWidth];
+ public int[,] RgbData = new int[GraphicsFile.FullHeight, GraphicsFile.FullWidth];
public int MapRgbColour(int red, int green, int blue)
{
diff --git a/KaraokeConverter/ExportAVI.cs b/KaraokeConverter/ExportAVI.cs
index 35ead69..445645e 100644
--- a/KaraokeConverter/ExportAVI.cs
+++ b/KaraokeConverter/ExportAVI.cs
@@ -19,7 +19,7 @@ namespace KaraokeConverter
Bitmap backgroundBmp = null;
Bitmap mergedBMP = null;
VideoStream aviStream = null;
- var myCDGFile = new CdgFile(cdgFileName, FileMode.Open, FileAccess.Read);
+ var myCDGFile = new GraphicsFile(cdgFileName, FileMode.Open, FileAccess.Read);
myCDGFile.RenderAtPosition(0);
var bitmap__1 = (Bitmap) myCDGFile.RgbImage;
if (!string.IsNullOrEmpty(backgroundFileName))
@@ -27,8 +27,8 @@ namespace KaraokeConverter
try
{
if (IsMovie(backgroundFileName))
- backgroundBmp = MovieFrameExtractor.GetBitmap(0, backgroundFileName, CdgFile.FullWidth,
- CdgFile.FullHeight);
+ backgroundBmp = MovieFrameExtractor.GetBitmap(0, backgroundFileName, GraphicsFile.FullWidth,
+ GraphicsFile.FullHeight);
if (IsGraphic(backgroundFileName))
backgroundBmp = GraphicUtil.GetCdgSizeBitmap(backgroundFileName);
}
@@ -64,7 +64,7 @@ namespace KaraokeConverter
{
if (IsMovie(backgroundFileName))
backgroundBmp = MovieFrameExtractor.GetBitmap(position/1000, backgroundFileName,
- CdgFile.FullWidth, CdgFile.FullHeight);
+ GraphicsFile.FullWidth, GraphicsFile.FullHeight);
}
if (backgroundBmp != null)
{
diff --git a/KaraokeConverter/Form1.cs b/KaraokeConverter/Form1.cs
index ee52b1f..a5dc3c4 100644
--- a/KaraokeConverter/Form1.cs
+++ b/KaraokeConverter/Form1.cs
@@ -25,7 +25,7 @@ namespace KaraokeConverter
#region "Private Declarations"
- private CdgFile mCDGFile;
+ private GraphicsFile mCDGFile;
private CdgFileIoStream mCDGStream;
private string mCDGFileName;
private string mMP3FileName;
diff --git a/KaraokePlayer/KaraokeVideoPlayer.cs b/KaraokePlayer/KaraokeVideoPlayer.cs
index 7c8af80..03acc8c 100644
--- a/KaraokePlayer/KaraokeVideoPlayer.cs
+++ b/KaraokePlayer/KaraokeVideoPlayer.cs
@@ -16,7 +16,7 @@ namespace KaraokePlayer
public partial class KaraokeVideoPlayer : UserControl
{
private readonly PictureBox _lyrics = new PictureBox {Dock = DockStyle.Fill};
- private CdgFile _cdgFile;
+ private GraphicsFile _cdgFile;
private Image _lyricImage;
private OverlayForm _overlayForm;
private DateTime _startTime;
@@ -39,7 +39,7 @@ namespace KaraokePlayer
public void Play(Uri file)
{
vlcPlayer.SetMedia(file);
- _cdgFile = new CdgFile(Path.ChangeExtension(file.LocalPath, "cdg"), FileMode.Open, FileAccess.Read);
+ _cdgFile = new GraphicsFile(Path.ChangeExtension(file.LocalPath, "cdg"), FileMode.Open, FileAccess.Read);
vlcPlayer.Play();
}
@@ -52,7 +52,7 @@ namespace KaraokePlayer
{
var stopwatch = new Stopwatch();
stopwatch.Start();
- var picture = await _cdgFile.Render((long) (DateTime.Now - _startTime).TotalMilliseconds);
+ var picture = await _cdgFile.RenderAtTime((long) (DateTime.Now - _startTime).TotalMilliseconds);
stopwatch.Reset();
Debug.Print(stopwatch.ElapsedMilliseconds.ToString());