quicknes: fix colors in custom palette use

This commit is contained in:
goyuken 2014-01-10 01:31:24 +00:00
parent 128f81bbb0
commit db386e4dee
3 changed files with 108 additions and 14 deletions

View File

@ -393,6 +393,7 @@
<Compile Include="Consoles\Nintendo\NES\PPU.run.cs" />
<Compile Include="Consoles\Nintendo\NES\Unif.cs" />
<Compile Include="Consoles\Nintendo\QuickNES\LibQuickNES.cs" />
<Compile Include="Consoles\Nintendo\QuickNES\Nes_NTSC_Colors.cs" />
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.cs" />
<Compile Include="Consoles\Nintendo\SNES\LibsnesApi.cs" />
<Compile Include="Consoles\Nintendo\SNES\LibsnesApi_BRK.cs" />

View File

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
{
public class Nes_NTSC_Colors
{
// just the color deemphasis routines from nes_ntsc
static void RGB_TO_YIQ(float r, float g, float b, out float y, out float i, out float q)
{
y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f;
i = (r) * 0.596f - (g) * 0.275f - (b) * 0.321f;
q = (r) * 0.212f - (g) * 0.523f + (b) * 0.311f;
}
static readonly float[] to_rgb = { 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
static void YIQ_TO_RGB(float y, float i, float q, out float r, out float g, out float b)
{
r = (float)(y + to_rgb[0] * i + to_rgb[1] * q);
g = (float)(y + to_rgb[2] * i + to_rgb[3] * q);
b = (float)(y + to_rgb[4] * i + to_rgb[5] * q);
}
static readonly float[] lo_levels = { -0.12f, 0.00f, 0.31f, 0.72f };
static readonly float[] hi_levels = { 0.40f, 0.68f, 1.00f, 1.00f };
static readonly byte[] tints = { 0, 6, 10, 8, 2, 4, 0, 0 };
static readonly float[] phases =
{
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
1.0f, 0.866025f, 0.5f, 0.0f, -0.5f, -0.866025f,
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
1.0f
};
public static void Emphasis(byte[] inp, byte[] outp, int entrynum)
{
int level = entrynum >> 4 & 0x03;
float lo = lo_levels[level];
float hi = hi_levels[level];
int color = entrynum & 0x0f;
int tint = entrynum >> 6;
if (color == 0)
lo = hi;
if (color == 0x0D)
hi = lo;
if (color > 0x0D)
hi = lo = 0.0f;
const float to_float = 1.0f / 0xff;
float r = to_float * inp[0];
float g = to_float * inp[1];
float b = to_float * inp[2];
float y, i, q;
RGB_TO_YIQ(r, g, b, out y, out i, out q);
if (tint > 0 && color < 0x0d)
{
const float atten_mul = 0.79399f;
const float atten_sub = 0.0782838f;
if (tint == 7)
{
y = y * (atten_mul * 1.13f) - (atten_sub * 1.13f);
}
else
{
int tint_color = tints[tint];
float sat = hi * (0.5f - atten_mul * 0.5f) + atten_sub * 0.5f;
y -= sat * 0.5f;
if (tint >= 3 && tint != 4)
{
/* combined tint bits */
sat *= 0.6f;
y -= sat;
}
i += phases[tint_color] * sat;
q += phases[tint_color + 3] * sat;
}
}
YIQ_TO_RGB(y, i, q, out r, out g, out b);
r = Math.Min(1.0f, Math.Max(0.0f, r));
g = Math.Min(1.0f, Math.Max(0.0f, g));
b = Math.Min(1.0f, Math.Max(0.0f, b));
outp[0] = (byte)(r * 255);
outp[1] = (byte)(g * 255);
outp[2] = (byte)(b * 255);
}
}
}

View File

@ -428,22 +428,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
{
if (pal.GetLength(0) != 64 || pal.GetLength(1) != 3)
throw new ArgumentOutOfRangeException();
for (int c = 0; c < 64; c++)
{
_Palette[c * 3] = (byte)pal[c, 0];
_Palette[c * 3 + 1] = (byte)pal[c, 1];
_Palette[c * 3 + 2] = (byte)pal[c, 2];
}
for (int c = 64; c < 512; c++)
for (int c = 0; c < 512; c++)
{
int a = c & 63;
int r = _Palette[a * 3];
int g = _Palette[a * 3 + 1];
int b = _Palette[a * 3 + 2];
BizHawk.Emulation.Cores.Nintendo.NES.NES.Palettes.ApplyDeemphasis(ref r, ref g, ref b, c >> 6);
_Palette[c * 3] = (byte)r;
_Palette[c * 3 + 1] = (byte)g;
_Palette[c * 3 + 2] = (byte)b;
byte[] inp = { (byte)pal[a, 0], (byte)pal[a, 1], (byte)pal[a, 2] };
byte[] outp = new byte[3];
Nes_NTSC_Colors.Emphasis(inp, outp, c);
_Palette[c * 3] = outp[0];
_Palette[c * 3 + 1] = outp[1];
_Palette[c * 3 + 2] = outp[2];
}
}