diff --git a/RedBookPlayer.Models/Hardware/Karaoke/KaraokeDisplay.cs b/RedBookPlayer.Models/Hardware/Karaoke/KaraokeDisplay.cs
index e310a5e..2c8b545 100644
--- a/RedBookPlayer.Models/Hardware/Karaoke/KaraokeDisplay.cs
+++ b/RedBookPlayer.Models/Hardware/Karaoke/KaraokeDisplay.cs
@@ -28,15 +28,19 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
public byte[,] DisplayData { get; private set; }
///
- /// Current 8-entry color table
+ /// Current 16-entry color table
///
///
- /// In practice, this should be 8 colors, probably similar to the CGA palette,
- /// including the "bright" or "dark" variant (possibly mapping from "high" to "low").
- /// The current interpretation of this may be incorrect, as the internal color table
- /// may actually include all 16 RGB values immediately.
+ /// Each color entry has the following format:
+ ///
+ /// [---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
+ ///
+ /// Note that P and Q channel bits need to be masked off (they are marked
+ /// here with Xs.
///
- public byte[] ColorTable { get; private set; }
+ public short[] ColorTable { get; private set; }
///
/// Color currently defined as transparent
@@ -49,7 +53,7 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
public KaraokeDisplay()
{
this.DisplayData = new byte[300,216];
- this.ColorTable = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
+ this.ColorTable = new short[16];
this.TransparentColor = 0x00;
}
@@ -90,11 +94,11 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
break;
case SubchannelInstruction.LoadColorTableLower:
var loadColorTableLower = new LoadCLUT(packet.Data);
- // TODO: Load color table data
+ LoadColorTable(loadColorTableLower, false);
break;
case SubchannelInstruction.LoadColorTableUpper:
var loadColorTableUpper = new LoadCLUT(packet.Data);
- // TODO: Load color table data
+ LoadColorTable(loadColorTableUpper, true);
break;
case SubchannelInstruction.TileBlockXOR:
var tileBlockXor = new TileBlock(packet.Data);
@@ -202,12 +206,12 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
{
int adjustedX = x + tileBlock.Column;
int adjustedY = y + tileBlock.Row;
- int colorIndex = pattern[x,y] == 0 ? tileBlock.Color0 : tileBlock.Color1;
+ byte colorIndex = pattern[x,y] == 0 ? tileBlock.Color0 : tileBlock.Color1;
if(xor)
- this.DisplayData[adjustedX, adjustedY] = (byte)(this.ColorTable[colorIndex] ^ this.DisplayData[adjustedX, adjustedY]);
+ this.DisplayData[adjustedX, adjustedY] = (byte)(colorIndex ^ this.DisplayData[adjustedX, adjustedY]);
else
- this.DisplayData[adjustedX, adjustedY] = this.ColorTable[colorIndex];
+ this.DisplayData[adjustedX, adjustedY] = colorIndex;
}
}
@@ -242,12 +246,12 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
}
// Fill in the now-empty pixels
- this.DisplayData[0,y] = copy ? overflow[0] : this.ColorTable[scroll.Color];
- this.DisplayData[1,y] = copy ? overflow[1] : this.ColorTable[scroll.Color];
- this.DisplayData[2,y] = copy ? overflow[2] : this.ColorTable[scroll.Color];
- this.DisplayData[3,y] = copy ? overflow[3] : this.ColorTable[scroll.Color];
- this.DisplayData[4,y] = copy ? overflow[4] : this.ColorTable[scroll.Color];
- this.DisplayData[5,y] = copy ? overflow[5] : this.ColorTable[scroll.Color];
+ this.DisplayData[0,y] = copy ? overflow[0] : scroll.Color;
+ this.DisplayData[1,y] = copy ? overflow[1] : scroll.Color;
+ this.DisplayData[2,y] = copy ? overflow[2] : scroll.Color;
+ this.DisplayData[3,y] = copy ? overflow[3] : scroll.Color;
+ this.DisplayData[4,y] = copy ? overflow[4] : scroll.Color;
+ this.DisplayData[5,y] = copy ? overflow[5] : scroll.Color;
}
}
else if(scroll.HScrollCommand == ScrollCommand.Negative)
@@ -264,12 +268,12 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
}
// Fill in the now-empty pixels
- this.DisplayData[294,y] = copy ? overflow[0] : this.ColorTable[scroll.Color];
- this.DisplayData[295,y] = copy ? overflow[1] : this.ColorTable[scroll.Color];
- this.DisplayData[296,y] = copy ? overflow[2] : this.ColorTable[scroll.Color];
- this.DisplayData[297,y] = copy ? overflow[3] : this.ColorTable[scroll.Color];
- this.DisplayData[298,y] = copy ? overflow[4] : this.ColorTable[scroll.Color];
- this.DisplayData[299,y] = copy ? overflow[5] : this.ColorTable[scroll.Color];
+ this.DisplayData[294,y] = copy ? overflow[0] : scroll.Color;
+ this.DisplayData[295,y] = copy ? overflow[1] : scroll.Color;
+ this.DisplayData[296,y] = copy ? overflow[2] : scroll.Color;
+ this.DisplayData[297,y] = copy ? overflow[3] : scroll.Color;
+ this.DisplayData[298,y] = copy ? overflow[4] : scroll.Color;
+ this.DisplayData[299,y] = copy ? overflow[5] : scroll.Color;
}
}
@@ -288,18 +292,18 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
}
// Fill in the now-empty pixels
- this.DisplayData[x,0] = copy ? overflow[0] : this.ColorTable[scroll.Color];
- this.DisplayData[x,1] = copy ? overflow[1] : this.ColorTable[scroll.Color];
- this.DisplayData[x,2] = copy ? overflow[2] : this.ColorTable[scroll.Color];
- this.DisplayData[x,3] = copy ? overflow[3] : this.ColorTable[scroll.Color];
- this.DisplayData[x,4] = copy ? overflow[4] : this.ColorTable[scroll.Color];
- this.DisplayData[x,5] = copy ? overflow[5] : this.ColorTable[scroll.Color];
- this.DisplayData[x,6] = copy ? overflow[6] : this.ColorTable[scroll.Color];
- this.DisplayData[x,7] = copy ? overflow[7] : this.ColorTable[scroll.Color];
- this.DisplayData[x,8] = copy ? overflow[8] : this.ColorTable[scroll.Color];
- this.DisplayData[x,9] = copy ? overflow[9] : this.ColorTable[scroll.Color];
- this.DisplayData[x,10] = copy ? overflow[10] : this.ColorTable[scroll.Color];
- this.DisplayData[x,11] = copy ? overflow[11] : this.ColorTable[scroll.Color];
+ this.DisplayData[x,0] = copy ? overflow[0] : scroll.Color;
+ this.DisplayData[x,1] = copy ? overflow[1] : scroll.Color;
+ this.DisplayData[x,2] = copy ? overflow[2] : scroll.Color;
+ this.DisplayData[x,3] = copy ? overflow[3] : scroll.Color;
+ this.DisplayData[x,4] = copy ? overflow[4] : scroll.Color;
+ this.DisplayData[x,5] = copy ? overflow[5] : scroll.Color;
+ this.DisplayData[x,6] = copy ? overflow[6] : scroll.Color;
+ this.DisplayData[x,7] = copy ? overflow[7] : scroll.Color;
+ this.DisplayData[x,8] = copy ? overflow[8] : scroll.Color;
+ this.DisplayData[x,9] = copy ? overflow[9] : scroll.Color;
+ this.DisplayData[x,10] = copy ? overflow[10] : scroll.Color;
+ this.DisplayData[x,11] = copy ? overflow[11] : scroll.Color;
}
}
else if(scroll.VScrollCommand == ScrollCommand.Negative)
@@ -316,20 +320,42 @@ namespace RedBookPlayer.Models.Hardware.Karaoke
}
// Fill in the now-empty pixels
- this.DisplayData[x,204] = copy ? overflow[0] : this.ColorTable[scroll.Color];
- this.DisplayData[x,205] = copy ? overflow[1] : this.ColorTable[scroll.Color];
- this.DisplayData[x,206] = copy ? overflow[2] : this.ColorTable[scroll.Color];
- this.DisplayData[x,207] = copy ? overflow[3] : this.ColorTable[scroll.Color];
- this.DisplayData[x,208] = copy ? overflow[4] : this.ColorTable[scroll.Color];
- this.DisplayData[x,209] = copy ? overflow[5] : this.ColorTable[scroll.Color];
- this.DisplayData[x,210] = copy ? overflow[6] : this.ColorTable[scroll.Color];
- this.DisplayData[x,211] = copy ? overflow[7] : this.ColorTable[scroll.Color];
- this.DisplayData[x,212] = copy ? overflow[8] : this.ColorTable[scroll.Color];
- this.DisplayData[x,213] = copy ? overflow[9] : this.ColorTable[scroll.Color];
- this.DisplayData[x,214] = copy ? overflow[10] : this.ColorTable[scroll.Color];
- this.DisplayData[x,215] = copy ? overflow[11] : this.ColorTable[scroll.Color];
+ this.DisplayData[x,204] = copy ? overflow[0] : scroll.Color;
+ this.DisplayData[x,205] = copy ? overflow[1] : scroll.Color;
+ this.DisplayData[x,206] = copy ? overflow[2] : scroll.Color;
+ this.DisplayData[x,207] = copy ? overflow[3] : scroll.Color;
+ this.DisplayData[x,208] = copy ? overflow[4] : scroll.Color;
+ this.DisplayData[x,209] = copy ? overflow[5] : scroll.Color;
+ this.DisplayData[x,210] = copy ? overflow[6] : scroll.Color;
+ this.DisplayData[x,211] = copy ? overflow[7] : scroll.Color;
+ this.DisplayData[x,212] = copy ? overflow[8] : scroll.Color;
+ this.DisplayData[x,213] = copy ? overflow[9] : scroll.Color;
+ this.DisplayData[x,214] = copy ? overflow[10] : scroll.Color;
+ this.DisplayData[x,215] = copy ? overflow[11] : scroll.Color;
}
}
}
+
+ ///
+ /// Load either the upper or lower half of the color table
+ ///
+ /// Color table data to load
+ /// True for colors 8-15, false for colors 0-7
+ private void LoadColorTable(LoadCLUT tableData, bool upper)
+ {
+ if(tableData == null)
+ return;
+
+ // Load the color table data directly
+ int start = upper ? 8 : 0;
+ this.ColorTable[start] = tableData.ColorSpec[0];
+ this.ColorTable[start + 1] = tableData.ColorSpec[1];
+ this.ColorTable[start + 2] = tableData.ColorSpec[2];
+ this.ColorTable[start + 3] = tableData.ColorSpec[3];
+ this.ColorTable[start + 4] = tableData.ColorSpec[4];
+ this.ColorTable[start + 5] = tableData.ColorSpec[5];
+ this.ColorTable[start + 6] = tableData.ColorSpec[6];
+ this.ColorTable[start + 7] = tableData.ColorSpec[7];
+ }
}
}
\ No newline at end of file