GB: gbc color change infrastructure. not hooked up to UI yet
This commit is contained in:
parent
40d4253f7a
commit
12844bbd7f
|
@ -212,6 +212,7 @@
|
||||||
<Compile Include="Consoles\Intellivision\PSG.cs" />
|
<Compile Include="Consoles\Intellivision\PSG.cs" />
|
||||||
<Compile Include="Consoles\Intellivision\STIC.cs" />
|
<Compile Include="Consoles\Intellivision\STIC.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
|
||||||
|
<Compile Include="Consoles\Nintendo\Gameboy\GBColors.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\LibGambatte.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\LibGambatte.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\NES\APU.cs" />
|
<Compile Include="Consoles\Nintendo\NES\APU.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\NES\BoardSystem.cs" />
|
<Compile Include="Consoles\Nintendo\NES\BoardSystem.cs" />
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Consoles.GB
|
||||||
|
{
|
||||||
|
public class GBColors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The GBC uses a RGB555 color space, but it most definately does not resemble sRGB at all.
|
||||||
|
* To make matters worse, because of the reflective screen, the visible colors depend greatly
|
||||||
|
* on the viewing environment.
|
||||||
|
*
|
||||||
|
* All of these algorithms convert from GBC RGB555 to sRGB RGB888
|
||||||
|
*/
|
||||||
|
public struct Triple
|
||||||
|
{
|
||||||
|
public int r;
|
||||||
|
public int g;
|
||||||
|
public int b;
|
||||||
|
public Triple(int r, int g, int b)
|
||||||
|
{
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Triple Bit5to8Bad()
|
||||||
|
{
|
||||||
|
Triple ret;
|
||||||
|
ret.r = r * 8;
|
||||||
|
ret.g = g * 8;
|
||||||
|
ret.b = b * 8;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Triple Bit5to8Good()
|
||||||
|
{
|
||||||
|
Triple ret;
|
||||||
|
ret.r = (r * 255 + 15) / 31;
|
||||||
|
ret.g = (g * 255 + 15) / 31;
|
||||||
|
ret.b = (b * 255 + 15) / 31;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ToARGB32()
|
||||||
|
{
|
||||||
|
return b | g << 8 | r << 16 | 255 << 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the version of gambatte in bizhawk
|
||||||
|
public static Triple GambatteColor(Triple c)
|
||||||
|
{
|
||||||
|
Triple ret;
|
||||||
|
ret.r = (c.r * 13 + c.g * 2 + c.b) >> 1;
|
||||||
|
ret.g = (c.g * 3 + c.b) << 1;
|
||||||
|
ret.b = (c.r * 3 + c.g * 2 + c.b * 11) >> 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vba's default mode
|
||||||
|
public static Triple VividColor(Triple c)
|
||||||
|
{
|
||||||
|
return c.Bit5to8Bad();
|
||||||
|
}
|
||||||
|
|
||||||
|
// "gameboy colors" mode on older versions of VBA
|
||||||
|
static int gbGetValue(int min, int max, int v)
|
||||||
|
{
|
||||||
|
return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
|
||||||
|
}
|
||||||
|
public static Triple OldVBAColor(Triple c)
|
||||||
|
{
|
||||||
|
Triple ret;
|
||||||
|
ret.r = gbGetValue(gbGetValue(4, 14, c.g),
|
||||||
|
gbGetValue(24, 29, c.g), c.r) - 4;
|
||||||
|
ret.g = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, c.r),
|
||||||
|
14 + gbGetValue(0, 3, c.r), c.b),
|
||||||
|
gbGetValue(24 + gbGetValue(0, 3, c.r),
|
||||||
|
29 + gbGetValue(0, 1, c.r), c.b), c.g) - 4;
|
||||||
|
ret.b = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, c.r),
|
||||||
|
14 + gbGetValue(0, 3, c.r), c.g),
|
||||||
|
gbGetValue(24 + gbGetValue(0, 3, c.r),
|
||||||
|
29 + gbGetValue(0, 1, c.r), c.g), c.b) - 4;
|
||||||
|
return ret.Bit5to8Bad();
|
||||||
|
}
|
||||||
|
|
||||||
|
// "gameboy colors" mode on newer versions of VBA
|
||||||
|
public static Triple NewVBAColor(Triple c)
|
||||||
|
{
|
||||||
|
Triple ret;
|
||||||
|
ret.r = (c.r * 13 + c.g * 2 + c.b * 1 + 8) >> 4;
|
||||||
|
ret.g = (c.r * 1 + c.g * 12 + c.b * 3 + 8) >> 4;
|
||||||
|
ret.b = (c.r * 2 + c.g * 2 + c.b * 12 + 8) >> 4;
|
||||||
|
return ret.Bit5to8Bad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,8 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
|
|
||||||
// set real default colors (before anyone mucks with them at all)
|
// set real default colors (before anyone mucks with them at all)
|
||||||
ChangeDMGColors(new int[] { 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157 });
|
ChangeDMGColors(new int[] { 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157 });
|
||||||
|
SetCGBColors();
|
||||||
|
|
||||||
InitSound();
|
InitSound();
|
||||||
|
|
||||||
Frame = 0;
|
Frame = 0;
|
||||||
|
@ -706,6 +707,21 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
LibGambatte.gambatte_setdmgpalettecolor(GambatteState, (LibGambatte.PalType)(i / 4), (uint)i % 4, (uint)colors[i]);
|
LibGambatte.gambatte_setdmgpalettecolor(GambatteState, (LibGambatte.PalType)(i / 4), (uint)i % 4, (uint)colors[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetCGBColors()
|
||||||
|
{
|
||||||
|
int[] lut = new int[32768];
|
||||||
|
int i = 0;
|
||||||
|
for (int b = 0; b < 32; b++)
|
||||||
|
for (int g = 0; g < 32; g++)
|
||||||
|
for (int r = 0; r < 32; r++)
|
||||||
|
lut[i++] = GBColors.GambatteColor(new GBColors.Triple(r, g, b)).ToARGB32();
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (int* p = &lut[0])
|
||||||
|
LibGambatte.gambatte_setcgbpalette(GambatteState, (IntPtr)p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ISoundProvider
|
#region ISoundProvider
|
||||||
|
|
|
@ -98,6 +98,14 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void gambatte_setdmgpalettecolor(IntPtr core, PalType palnum, uint colornum, uint rgb32);
|
public static extern void gambatte_setdmgpalettecolor(IntPtr core, PalType palnum, uint colornum, uint rgb32);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// set cgb palette lookup
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="core">opaque state pointer</param>
|
||||||
|
/// <param name="lut">uint32[32768], input color (r,g,b) is at lut[r | g << 5 | b << 10]</param>
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setcgbpalette(IntPtr core, IntPtr lut);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// combination of button flags used by the input callback
|
/// combination of button flags used by the input callback
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Binary file not shown.
|
@ -80,6 +80,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32);
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32);
|
||||||
|
|
||||||
|
void setCgbPalette(unsigned *lut);
|
||||||
|
|
||||||
/** Sets the callback used for getting input state. */
|
/** Sets the callback used for getting input state. */
|
||||||
void setInputGetter(InputGetter *getInput);
|
void setInputGetter(InputGetter *getInput);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ __declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned paln
|
||||||
g->setDmgPaletteColor(palnum, colornum, rgb32);
|
g->setDmgPaletteColor(palnum, colornum, rgb32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setcgbpalette(void *core, unsigned *lut)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->setCgbPalette(lut);
|
||||||
|
}
|
||||||
|
|
||||||
class CInputGetter: public InputGetter
|
class CInputGetter: public InputGetter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -16,6 +16,8 @@ extern "C"
|
||||||
|
|
||||||
__declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned palnum, unsigned colornum, unsigned rgb32);
|
__declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned palnum, unsigned colornum, unsigned rgb32);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setcgbpalette(void *core, unsigned *lut);
|
||||||
|
|
||||||
__declspec(dllexport) void gambatte_setinputgetter(void *core, unsigned (*getinput)(void));
|
__declspec(dllexport) void gambatte_setinputgetter(void *core, unsigned (*getinput)(void));
|
||||||
|
|
||||||
__declspec(dllexport) void gambatte_setreadcallback(void *core, void (*callback)(unsigned));
|
__declspec(dllexport) void gambatte_setreadcallback(void *core, void (*callback)(unsigned));
|
||||||
|
|
|
@ -110,6 +110,10 @@ public:
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) {
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) {
|
||||||
memory.setDmgPaletteColor(palNum, colorNum, rgb32);
|
memory.setDmgPaletteColor(palNum, colorNum, rgb32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setCgbPalette(unsigned *lut) {
|
||||||
|
memory.setCgbPalette(lut);
|
||||||
|
}
|
||||||
|
|
||||||
void setGameGenie(const std::string &codes) { memory.setGameGenie(codes); }
|
void setGameGenie(const std::string &codes) { memory.setGameGenie(codes); }
|
||||||
void setGameShark(const std::string &codes) { memory.setGameShark(codes); }
|
void setGameShark(const std::string &codes) { memory.setGameShark(codes); }
|
||||||
|
|
|
@ -182,6 +182,10 @@ void GB::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32)
|
||||||
p_->cpu.setDmgPaletteColor(palNum, colorNum, rgb32);
|
p_->cpu.setDmgPaletteColor(palNum, colorNum, rgb32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB::setCgbPalette(unsigned *lut) {
|
||||||
|
p_->cpu.setCgbPalette(lut);
|
||||||
|
}
|
||||||
|
|
||||||
bool GB::loadState(std::istream &file) {
|
bool GB::loadState(std::istream &file) {
|
||||||
if (p_->cpu.loaded()) {
|
if (p_->cpu.loaded()) {
|
||||||
// p_->cpu.saveSavedata();
|
// p_->cpu.saveSavedata();
|
||||||
|
|
|
@ -1031,6 +1031,10 @@ void Memory::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned lon
|
||||||
display.setDmgPaletteColor(palNum, colorNum, rgb32);
|
display.setDmgPaletteColor(palNum, colorNum, rgb32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memory::setCgbPalette(unsigned *lut) {
|
||||||
|
display.setCgbPalette(lut);
|
||||||
|
}
|
||||||
|
|
||||||
bool Memory::getMemoryArea(int which, unsigned char **data, int *length) {
|
bool Memory::getMemoryArea(int which, unsigned char **data, int *length) {
|
||||||
if (!data || !length)
|
if (!data || !length)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -173,6 +173,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||||
|
void setCgbPalette(unsigned *lut);
|
||||||
void setGameGenie(const std::string &codes) { cart.setGameGenie(codes); }
|
void setGameGenie(const std::string &codes) { cart.setGameGenie(codes); }
|
||||||
void setGameShark(const std::string &codes) { interrupter.setGameShark(codes); }
|
void setGameShark(const std::string &codes) { interrupter.setGameShark(codes); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,12 +30,20 @@ void LCD::setDmgPalette(unsigned long *const palette, const unsigned long *const
|
||||||
palette[3] = dmgColors[data >> 6 & 3];
|
palette[3] = dmgColors[data >> 6 & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long gbcToRgb32(const unsigned bgr15) {
|
void LCD::setCgbPalette(unsigned *lut) {
|
||||||
|
for (int i = 0; i < 32768; i++)
|
||||||
|
cgbColorsRgb32[i] = lut[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long LCD::gbcToRgb32(const unsigned bgr15) {
|
||||||
|
/*
|
||||||
const unsigned long r = bgr15 & 0x1F;
|
const unsigned long r = bgr15 & 0x1F;
|
||||||
const unsigned long g = bgr15 >> 5 & 0x1F;
|
const unsigned long g = bgr15 >> 5 & 0x1F;
|
||||||
const unsigned long b = bgr15 >> 10 & 0x1F;
|
const unsigned long b = bgr15 >> 10 & 0x1F;
|
||||||
|
|
||||||
return ((r * 13 + g * 2 + b) >> 1) << 16 | (g * 3 + b) << 9 | (r * 3 + g * 2 + b * 11) >> 1;
|
return ((r * 13 + g * 2 + b) >> 1) << 16 | (g * 3 + b) << 9 | (r * 3 + g * 2 + b * 11) >> 1;
|
||||||
|
*/
|
||||||
|
return cgbColorsRgb32[bgr15 & 0x7FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static unsigned long gbcToRgb16(const unsigned bgr15) {
|
/*static unsigned long gbcToRgb16(const unsigned bgr15) {
|
||||||
|
@ -357,7 +365,7 @@ bool LCD::cgbpAccessible(const unsigned long cycleCounter) {
|
||||||
|| cycleCounter >= m0TimeOfCurrentLine(cycleCounter) + 3 - isDoubleSpeed();
|
|| cycleCounter >= m0TimeOfCurrentLine(cycleCounter) + 3 - isDoubleSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doCgbColorChange(unsigned char *const pdata,
|
void LCD::doCgbColorChange(unsigned char *const pdata,
|
||||||
unsigned long *const palette, unsigned index, const unsigned data) {
|
unsigned long *const palette, unsigned index, const unsigned data) {
|
||||||
pdata[index] = data;
|
pdata[index] = data;
|
||||||
index >>= 1;
|
index >>= 1;
|
||||||
|
|
|
@ -120,6 +120,7 @@ class LCD {
|
||||||
|
|
||||||
PPU ppu;
|
PPU ppu;
|
||||||
unsigned long dmgColorsRgb32[3 * 4];
|
unsigned long dmgColorsRgb32[3 * 4];
|
||||||
|
unsigned long cgbColorsRgb32[32768];
|
||||||
unsigned char bgpData[8 * 8];
|
unsigned char bgpData[8 * 8];
|
||||||
unsigned char objpData[8 * 8];
|
unsigned char objpData[8 * 8];
|
||||||
|
|
||||||
|
@ -137,6 +138,9 @@ class LCD {
|
||||||
static void setDmgPalette(unsigned long *palette, const unsigned long *dmgColors, unsigned data);
|
static void setDmgPalette(unsigned long *palette, const unsigned long *dmgColors, unsigned data);
|
||||||
void setDmgPaletteColor(unsigned index, unsigned long rgb32);
|
void setDmgPaletteColor(unsigned index, unsigned long rgb32);
|
||||||
|
|
||||||
|
unsigned long gbcToRgb32(const unsigned bgr15);
|
||||||
|
void doCgbColorChange(unsigned char *const pdata, unsigned long *const palette, unsigned index, const unsigned data);
|
||||||
|
|
||||||
void refreshPalettes();
|
void refreshPalettes();
|
||||||
void setDBuffer();
|
void setDBuffer();
|
||||||
|
|
||||||
|
@ -160,6 +164,7 @@ public:
|
||||||
void saveState(SaveState &state) const;
|
void saveState(SaveState &state) const;
|
||||||
void loadState(const SaveState &state, const unsigned char *oamram);
|
void loadState(const SaveState &state, const unsigned char *oamram);
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||||
|
void setCgbPalette(unsigned *lut);
|
||||||
void setVideoBuffer(uint_least32_t *videoBuf, int pitch);
|
void setVideoBuffer(uint_least32_t *videoBuf, int pitch);
|
||||||
|
|
||||||
void setOsdElement(std::auto_ptr<OsdElement> osdElement) { this->osdElement = osdElement; }
|
void setOsdElement(std::auto_ptr<OsdElement> osdElement) { this->osdElement = osdElement; }
|
||||||
|
|
Loading…
Reference in New Issue