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\STIC.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\NES\APU.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)
|
||||
ChangeDMGColors(new int[] { 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157, 10798341, 8956165, 1922333, 337157 });
|
||||
|
||||
SetCGBColors();
|
||||
|
||||
InitSound();
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#region ISoundProvider
|
||||
|
|
|
@ -98,6 +98,14 @@ namespace BizHawk.Emulation.Consoles.GB
|
|||
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
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>
|
||||
/// combination of button flags used by the input callback
|
||||
/// </summary>
|
||||
|
|
Binary file not shown.
|
@ -80,6 +80,8 @@ public:
|
|||
*/
|
||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32);
|
||||
|
||||
void setCgbPalette(unsigned *lut);
|
||||
|
||||
/** Sets the callback used for getting input state. */
|
||||
void setInputGetter(InputGetter *getInput);
|
||||
|
||||
|
|
|
@ -45,6 +45,12 @@ __declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned paln
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -16,6 +16,8 @@ extern "C"
|
|||
|
||||
__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_setreadcallback(void *core, void (*callback)(unsigned));
|
||||
|
|
|
@ -110,6 +110,10 @@ public:
|
|||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) {
|
||||
memory.setDmgPaletteColor(palNum, colorNum, rgb32);
|
||||
}
|
||||
|
||||
void setCgbPalette(unsigned *lut) {
|
||||
memory.setCgbPalette(lut);
|
||||
}
|
||||
|
||||
void setGameGenie(const std::string &codes) { memory.setGameGenie(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);
|
||||
}
|
||||
|
||||
void GB::setCgbPalette(unsigned *lut) {
|
||||
p_->cpu.setCgbPalette(lut);
|
||||
}
|
||||
|
||||
bool GB::loadState(std::istream &file) {
|
||||
if (p_->cpu.loaded()) {
|
||||
// p_->cpu.saveSavedata();
|
||||
|
|
|
@ -1031,6 +1031,10 @@ void Memory::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned lon
|
|||
display.setDmgPaletteColor(palNum, colorNum, rgb32);
|
||||
}
|
||||
|
||||
void Memory::setCgbPalette(unsigned *lut) {
|
||||
display.setCgbPalette(lut);
|
||||
}
|
||||
|
||||
bool Memory::getMemoryArea(int which, unsigned char **data, int *length) {
|
||||
if (!data || !length)
|
||||
return false;
|
||||
|
|
|
@ -173,6 +173,7 @@ public:
|
|||
}
|
||||
|
||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||
void setCgbPalette(unsigned *lut);
|
||||
void setGameGenie(const std::string &codes) { cart.setGameGenie(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];
|
||||
}
|
||||
|
||||
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 g = bgr15 >> 5 & 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 cgbColorsRgb32[bgr15 & 0x7FFF];
|
||||
}
|
||||
|
||||
/*static unsigned long gbcToRgb16(const unsigned bgr15) {
|
||||
|
@ -357,7 +365,7 @@ bool LCD::cgbpAccessible(const unsigned long cycleCounter) {
|
|||
|| 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) {
|
||||
pdata[index] = data;
|
||||
index >>= 1;
|
||||
|
|
|
@ -120,6 +120,7 @@ class LCD {
|
|||
|
||||
PPU ppu;
|
||||
unsigned long dmgColorsRgb32[3 * 4];
|
||||
unsigned long cgbColorsRgb32[32768];
|
||||
unsigned char bgpData[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);
|
||||
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 setDBuffer();
|
||||
|
||||
|
@ -160,6 +164,7 @@ public:
|
|||
void saveState(SaveState &state) const;
|
||||
void loadState(const SaveState &state, const unsigned char *oamram);
|
||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||
void setCgbPalette(unsigned *lut);
|
||||
void setVideoBuffer(uint_least32_t *videoBuf, int pitch);
|
||||
|
||||
void setOsdElement(std::auto_ptr<OsdElement> osdElement) { this->osdElement = osdElement; }
|
||||
|
|
Loading…
Reference in New Issue