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:
parent
b51cfbaa45
commit
276b00fb35
BizHawk.Emulation
BizHawk.MultiClient/output/dll
libsnes/bsnes/target-libsnes
|
@ -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" />
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue