snes: unify color generation for debugger and core. include 3 alternate implications: r3809, r3808, and hypothetical snes9x. nothing ui hooked up yet

This commit is contained in:
goyuken 2012-11-16 21:29:23 +00:00
parent b51cfbaa45
commit 276b00fb35
7 changed files with 135 additions and 58 deletions
BizHawk.Emulation
BizHawk.MultiClient/output/dll
libsnes/bsnes/target-libsnes

View File

@ -382,6 +382,7 @@
<Compile Include="Consoles\Nintendo\NES\PPU.run.cs" />
<Compile Include="Consoles\Nintendo\NES\Unif.cs" />
<Compile Include="Consoles\Nintendo\SNES\LibsnesCore.cs" />
<Compile Include="Consoles\Nintendo\SNES\SnesColors.cs" />
<Compile Include="Consoles\Nintendo\SNES\SNESGraphicsDecoder.cs" />
<Compile Include="Consoles\PC Engine\ADPCM.cs" />
<Compile Include="Consoles\PC Engine\ArcadeCard.cs" />

View File

@ -132,6 +132,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void snes_dequeue_message(IntPtr strBuffer);
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void snes_set_color_lut(IntPtr colors);
public static bool HasMessage { get { return snes_poll_message() != -1; } }
public static string DequeueMessage()
@ -404,6 +407,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
scanlineStart_cb = new LibsnesDll.snes_scanlineStart_t(snes_scanlineStart);
// set palette
int[] tmp = SnesColors.GetLUT(SnesColors.ColorType.Bizhawk);
fixed (int* p = &tmp[0])
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_color_lut((IntPtr)p);
// start up audio resampler
InitAudio();

View File

@ -299,7 +299,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
//the same basic color table that libsnes uses to convert from snes 555 to rgba32
public static int[] colortable = new int[16 * 32768];
public static int[] colortable;
static int[] directColorTable = new int[256]; //8bpp gfx -> rgb555
static SNESGraphicsDecoder()
{
@ -315,35 +315,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
int color = (b << 10) | (g << 5) | r;
directColorTable[i] = color;
}
//make colortable
//this is unlikely to change, so maybe we could precompute it to save bootup time.. benchmark it.
//alternatively, we could drag it out of libsneshawk dll
for (int l = 0; l < 16; l++)
{
for (int r = 0; r < 32; r++)
{
for (int g = 0; g < 32; g++)
{
for (int b = 0; b < 32; b++)
{
//zero 04-sep-2012 - go ahead and turn this into a pixel format we'll want
//double luma = (double)l / 15.0;
//int ar = (int)(luma * r + 0.5);
//int ag = (int)(luma * g + 0.5);
//int ab = (int)(luma * b + 0.5);
//ar = ar * 255 / 31;
//ag = ag * 255 / 31;
//ab = ab * 255 / 31;
int ar = (r * l * 17 + 15) / 31;
int ag = (g * l * 17 + 15) / 31;
int ab = (b * l * 17 + 15) / 31;
int color = (ab << 16) + (ag << 8) + (ar << 0) | unchecked((int)0xFF000000);
colortable[(l << 15) + (r << 10) + (g << 5) + (b << 0)] = color;
}
}
}
}
colortable = SnesColors.GetLUT(SnesColors.ColorType.Bizhawk);
}
byte* vram;

View File

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
{
public static class SnesColors
{
// the SNES renders colors in a 15 bit RGB space. in addition, there is a 4 bit "luma" or "brightness" register
// we want to map this to a 24 bit RGB space; the exactly authentic way to do this is not known
// none of this is optimized for speed because we make a LUT at load time
public static void BizColor(out int or, out int og, out int ob, int l, int r, int g, int b)
{
// bizhawk through r3808, from bsnes
double luma = (double)l / 15.0;
int ar = (int)(luma * r + 0.5);
int ag = (int)(luma * g + 0.5);
int ab = (int)(luma * b + 0.5);
or = ar * 255 / 31;
og = ag * 255 / 31;
ob = ab * 255 / 31;
}
public static void NattColor(out int or, out int og, out int ob, int l, int r, int g, int b)
{
// bizhawk r3809. assumes that luma mixing is done in analog
or = (r * l * 17 + 15) / 31;
og = (g * l * 17 + 15) / 31;
ob = (b * l * 17 + 15) / 31;
}
// LUT from snes9x
static byte[,] mul_brightness =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04 },
{ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06 },
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08 },
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05,
0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a },
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06,
0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c },
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07,
0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e },
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08,
0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x11 },
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09,
0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x13 },
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x09, 0x0a,
0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15 },
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b,
0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17 },
{ 0x00, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19 },
{ 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1b },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }
};
public static void Snes9xColor(out int or, out int og, out int ob, int l, int r, int g, int b)
{
int ar = mul_brightness[l, r];
int ag = mul_brightness[l, r];
int ab = mul_brightness[l, r];
or = ar * 8;
og = ag * 8;
ob = ab * 8;
}
public enum ColorType
{
Bizhawk,
Natt,
Snes9x
};
public static int[] GetLUT(ColorType t)
{
int[] ret = new int[16 * 32768];
for (int l = 0; l < 16; l++)
{
for (int r = 0; r < 32; r++)
{
for (int g = 0; g < 32; g++)
{
for (int b = 0; b < 32; b++)
{
int ar, ag, ab;
if (t == ColorType.Snes9x)
Snes9xColor(out ar, out ag, out ab, l, r, g, b);
else if (t == ColorType.Natt)
NattColor(out ar, out ag, out ab, l, r, g, b);
else
BizColor(out ar, out ag, out ab, l, r, g, b);
int color = (ar << 16) + (ag << 8) + (ab << 0) | unchecked((int)0xFF000000);
ret[(l << 15) + (b << 10) + (g << 5) + (r << 0)] = color;
}
}
}
}
return ret;
}
}
}

View File

@ -98,34 +98,6 @@ struct Interface : public SNES::Interface {
buffer = new uint32_t[512 * 480];
palette = new uint32_t[16 * 32768];
//{llll bbbbb ggggg rrrrr} -> { rrrrr ggggg bbbbb }
for(unsigned l = 0; l < 16; l++) {
for(unsigned r = 0; r < 32; r++) {
for(unsigned g = 0; g < 32; g++) {
for(unsigned b = 0; b < 32; b++) {
//double luma = (double)l / 15.0;
//unsigned ar = (luma * r + 0.5);
//unsigned ag = (luma * g + 0.5);
//unsigned ab = (luma * b + 0.5);
//palette[(l << 15) + (r << 10) + (g << 5) + (b << 0)] = (ab << 10) + (ag << 5) + (ar << 0);
//zero 04-sep-2012 - go ahead and turn this into a pixel format we'll want
//double luma = (double)l / 15.0;
//unsigned ar = (luma * r + 0.5);
//unsigned ag = (luma * g + 0.5);
//unsigned ab = (luma * b + 0.5);
//ar = ar * 255 / 31;
//ag = ag * 255 / 31;
//ab = ab * 255 / 31;
int ar = (r * l * 17 + 15) / 31;
int ag = (g * l * 17 + 15) / 31;
int ab = (b * l * 17 + 15) / 31;
unsigned color = (ab << 16) + (ag << 8) + (ar << 0) | 0xFF000000;
palette[(l << 15) + (r << 10) + (g << 5) + (b << 0)] = color;
}
}
}
}
}
~Interface() {
@ -153,6 +125,11 @@ void snes_set_video_refresh(snes_video_refresh_t video_refresh) {
interface.pvideo_refresh = video_refresh;
}
void snes_set_color_lut(uint32_t * colors) {
for (int i = 0; i < 16 * 32768; i++)
interface.palette[i] = colors[i];
}
void snes_set_audio_sample(snes_audio_sample_t audio_sample) {
interface.paudio_sample = audio_sample;
}

View File

@ -143,6 +143,8 @@ void snes_dequeue_message(char* buffer);
typedef const char* (*snes_path_request_t)(int slot, const char* hint);
void snes_set_path_request(snes_path_request_t path_request);
void snes_set_color_lut(uint32_t * colors);
// system bus implementation
uint8_t bus_read(unsigned addr);
void bus_write(unsigned addr, uint8_t val);