forked from sin365/AxibugEmuOnline
[Essgee] 干掉访问器 | 色彩表预先计算
This commit is contained in:
parent
bb2129f49a
commit
8ce51896dc
@ -170,6 +170,7 @@ namespace Essgee.Emulation.CPU
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* 全都不要了吧 log
|
||||||
if (AppEnvironment.EnableSuperSlowCPULogger && logEntries != null)
|
if (AppEnvironment.EnableSuperSlowCPULogger && logEntries != null)
|
||||||
{
|
{
|
||||||
string disasm = string.Format("{0} | {1} | {2} | {3}\n", DisassembleOpcode(this, pc).PadRight(48), PrintRegisters(this), PrintFlags(this), PrintInterrupt(this));
|
string disasm = string.Format("{0} | {1} | {2} | {3}\n", DisassembleOpcode(this, pc).PadRight(48), PrintRegisters(this), PrintFlags(this), PrintInterrupt(this));
|
||||||
@ -181,6 +182,7 @@ namespace Essgee.Emulation.CPU
|
|||||||
numLogEntries = 0;
|
numLogEntries = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* Do HALT bug */
|
/* Do HALT bug */
|
||||||
if (doHaltBug)
|
if (doHaltBug)
|
||||||
|
|||||||
@ -8,7 +8,8 @@ namespace Essgee.Emulation.CPU
|
|||||||
public class SM83CGB : SM83
|
public class SM83CGB : SM83
|
||||||
{
|
{
|
||||||
// TODO: better way of implementing this?
|
// TODO: better way of implementing this?
|
||||||
public bool IsDoubleSpeed { get; private set; }
|
//public bool IsDoubleSpeed { get; private set; }
|
||||||
|
public bool IsDoubleSpeed;
|
||||||
|
|
||||||
public SM83CGB(MemoryReadDelegate memoryRead, MemoryWriteDelegate memoryWrite) : base(memoryRead, memoryWrite) { }
|
public SM83CGB(MemoryReadDelegate memoryRead, MemoryWriteDelegate memoryWrite) : base(memoryRead, memoryWrite) { }
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,8 @@ namespace Essgee.Emulation.Configuration
|
|||||||
public class GameBoyColor : IConfiguration
|
public class GameBoyColor : IConfiguration
|
||||||
{
|
{
|
||||||
//todo Unity [CheckBoxControl("General", "Use Bootstrap ROM")]
|
//todo Unity [CheckBoxControl("General", "Use Bootstrap ROM")]
|
||||||
public bool UseBootstrap { get; set; }
|
//public bool UseBootstrap { get; set; }
|
||||||
|
public bool UseBootstrap;
|
||||||
[IsBootstrapRomPath]
|
[IsBootstrapRomPath]
|
||||||
//todo Unity [FileBrowserControl("General", "Bootstrap Path", "Game Boy Color Bootstrap ROM (*.gbc;*.bin;*.zip)|*.gbc;*.bin;*.zip")]
|
//todo Unity [FileBrowserControl("General", "Bootstrap Path", "Game Boy Color Bootstrap ROM (*.gbc;*.bin;*.zip)|*.gbc;*.bin;*.zip")]
|
||||||
public string BootstrapRom { get; set; }
|
public string BootstrapRom { get; set; }
|
||||||
@ -25,37 +26,47 @@ namespace Essgee.Emulation.Configuration
|
|||||||
|
|
||||||
//todo Unity [DropDownControl("Infrared", "Infrared Source", typeof(Machines.GameBoyColor.InfraredSources))]
|
//todo Unity [DropDownControl("Infrared", "Infrared Source", typeof(Machines.GameBoyColor.InfraredSources))]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public Machines.GameBoyColor.InfraredSources InfraredSource { get; set; }
|
//public Machines.GameBoyColor.InfraredSources InfraredSource { get; set; }
|
||||||
|
public Machines.GameBoyColor.InfraredSources InfraredSource;
|
||||||
//todo Unity [FileBrowserControl("Infrared", "Pokemon Pikachu DB", "Database Binary (*.bin)|*.bin")]
|
//todo Unity [FileBrowserControl("Infrared", "Pokemon Pikachu DB", "Database Binary (*.bin)|*.bin")]
|
||||||
public string InfraredDatabasePikachu { get; set; }
|
public string InfraredDatabasePikachu { get; set; }
|
||||||
|
|
||||||
//todo Unity [DropDownControl("Controls", "Up", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Up", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsUp { get; set; }
|
//public EssgeeMotionKey ControlsUp { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsUp;
|
||||||
//todo Unity [DropDownControl("Controls", "Down", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Down", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsDown { get; set; }
|
//public EssgeeMotionKey ControlsDown { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsDown;
|
||||||
//todo Unity [DropDownControl("Controls", "Left", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Left", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsLeft { get; set; }
|
//public EssgeeMotionKey ControlsLeft { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsLeft;
|
||||||
//todo Unity [DropDownControl("Controls", "Right", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Right", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsRight { get; set; }
|
//public EssgeeMotionKey ControlsRight { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsRight;
|
||||||
//todo Unity [DropDownControl("Controls", "A", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "A", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsA { get; set; }
|
//public EssgeeMotionKey ControlsA { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsA;
|
||||||
//todo Unity [DropDownControl("Controls", "B", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "B", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsB { get; set; }
|
//public EssgeeMotionKey ControlsB { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsB;
|
||||||
//todo Unity [DropDownControl("Controls", "Select", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Select", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsSelect { get; set; }
|
//public EssgeeMotionKey ControlsSelect { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsSelect;
|
||||||
//todo Unity [DropDownControl("Controls", "Start", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Start", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsStart { get; set; }
|
//public EssgeeMotionKey ControlsStart { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsStart;
|
||||||
//todo Unity [DropDownControl("Controls", "Send IR Signal", typeof(Keys), Keys.F11)]
|
//todo Unity [DropDownControl("Controls", "Send IR Signal", typeof(Keys), Keys.F11)]
|
||||||
//[JsonConverter(typeof(StringEnumConverter))]
|
//[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public EssgeeMotionKey ControlsSendIR { get; set; }
|
//public EssgeeMotionKey ControlsSendIR { get; set; }
|
||||||
|
public EssgeeMotionKey ControlsSendIR;
|
||||||
|
|
||||||
public GameBoyColor()
|
public GameBoyColor()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,6 +4,12 @@ namespace Essgee.Emulation
|
|||||||
{
|
{
|
||||||
public unsafe static class Utilities
|
public unsafe static class Utilities
|
||||||
{
|
{
|
||||||
|
static Utilities()
|
||||||
|
{
|
||||||
|
InitRGB222toBGRA8888Cache();
|
||||||
|
InitRGB444toBGRA8888Cache();
|
||||||
|
InitRGBCGBtoBGRA8888Cache();
|
||||||
|
}
|
||||||
public static bool IsBitSet(byte value, int bit)
|
public static bool IsBitSet(byte value, int bit)
|
||||||
{
|
{
|
||||||
return ((value & (1 << bit)) != 0);
|
return ((value & (1 << bit)) != 0);
|
||||||
@ -17,13 +23,34 @@ namespace Essgee.Emulation
|
|||||||
// buffer[address + 2] = (byte)((r << 6) | (r << 4) | (r << 2) | r);
|
// buffer[address + 2] = (byte)((r << 6) | (r << 4) | (r << 2) | r);
|
||||||
// buffer[address + 3] = 0xFF;
|
// buffer[address + 3] = 0xFF;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly byte[] RGB222toBGRA8888Cache_LutR = new byte[32768];
|
||||||
|
private static readonly byte[] RGB222toBGRA8888Cache_LutG = new byte[32768];
|
||||||
|
private static readonly byte[] RGB222toBGRA8888Cache_LutB = new byte[32768];
|
||||||
|
|
||||||
|
static void InitRGB222toBGRA8888Cache() // 静态构造函数初始化LUT
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32768; i++)
|
||||||
|
{
|
||||||
|
byte r = (byte)((i >> 0) & 0x3), g = (byte)((i >> 2) & 0x3), b = (byte)((i >> 4) & 0x3);
|
||||||
|
RGB222toBGRA8888Cache_LutR[i] = (byte)((b << 6) | (b << 4) | (b << 2) | b);
|
||||||
|
RGB222toBGRA8888Cache_LutG[i] = (byte)((g << 6) | (g << 4) | (g << 2) | g);
|
||||||
|
RGB222toBGRA8888Cache_LutB[i] = (byte)((r << 6) | (r << 4) | (r << 2) | r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void RGB222toBGRA8888(int color, ref byte* buffer, int address)
|
public static void RGB222toBGRA8888(int color, ref byte* buffer, int address)
|
||||||
{
|
{
|
||||||
byte r = (byte)((color >> 0) & 0x3), g = (byte)((color >> 2) & 0x3), b = (byte)((color >> 4) & 0x3);
|
//byte r = (byte)((color >> 0) & 0x3), g = (byte)((color >> 2) & 0x3), b = (byte)((color >> 4) & 0x3);
|
||||||
buffer[address + 0] = (byte)((b << 6) | (b << 4) | (b << 2) | b);
|
//buffer[address + 0] = (byte)((b << 6) | (b << 4) | (b << 2) | b);
|
||||||
buffer[address + 1] = (byte)((g << 6) | (g << 4) | (g << 2) | g);
|
//buffer[address + 1] = (byte)((g << 6) | (g << 4) | (g << 2) | g);
|
||||||
buffer[address + 2] = (byte)((r << 6) | (r << 4) | (r << 2) | r);
|
//buffer[address + 2] = (byte)((r << 6) | (r << 4) | (r << 2) | r);
|
||||||
buffer[address + 3] = 0xFF;
|
//buffer[address + 3] = 0xFF;
|
||||||
|
*(buffer + address) = RGB222toBGRA8888Cache_LutR[color];
|
||||||
|
*(buffer + address + 1) = RGB222toBGRA8888Cache_LutR[color];
|
||||||
|
*(buffer + address + 2) = RGB222toBGRA8888Cache_LutR[color];
|
||||||
|
*(buffer + address + 3) = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public static void RGB444toBGRA8888(int color, ref byte[] buffer, int address)
|
//public static void RGB444toBGRA8888(int color, ref byte[] buffer, int address)
|
||||||
@ -35,13 +62,33 @@ namespace Essgee.Emulation
|
|||||||
// buffer[address + 3] = 0xFF;
|
// buffer[address + 3] = 0xFF;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// 预计算所有可能的颜色转换
|
||||||
|
private static readonly byte[] RGB444toBGRA8888Cache_LutR = new byte[32768];
|
||||||
|
private static readonly byte[] RGB444toBGRA8888Cache_LutG = new byte[32768];
|
||||||
|
private static readonly byte[] RGB444toBGRA8888Cache_LutB = new byte[32768];
|
||||||
|
|
||||||
|
static void InitRGB444toBGRA8888Cache() // 静态构造函数初始化LUT
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32768; i++)
|
||||||
|
{
|
||||||
|
byte r = (byte)((i >> 0) & 0xF), g = (byte)((i >> 4) & 0xF), b = (byte)((i >> 8) & 0xF);
|
||||||
|
RGB444toBGRA8888Cache_LutR[i] = (byte)((b << 4) | b);
|
||||||
|
RGB444toBGRA8888Cache_LutG[i] = (byte)((g << 4) | g);
|
||||||
|
RGB444toBGRA8888Cache_LutB[i] = (byte)((r << 4) | r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public unsafe static void RGB444toBGRA8888(int color, ref byte* buffer, int address)
|
public unsafe static void RGB444toBGRA8888(int color, ref byte* buffer, int address)
|
||||||
{
|
{
|
||||||
byte r = (byte)((color >> 0) & 0xF), g = (byte)((color >> 4) & 0xF), b = (byte)((color >> 8) & 0xF);
|
//byte r = (byte)((color >> 0) & 0xF), g = (byte)((color >> 4) & 0xF), b = (byte)((color >> 8) & 0xF);
|
||||||
buffer[address + 0] = (byte)((b << 4) | b);
|
//buffer[address + 0] = (byte)((b << 4) | b);
|
||||||
buffer[address + 1] = (byte)((g << 4) | g);
|
//buffer[address + 1] = (byte)((g << 4) | g);
|
||||||
buffer[address + 2] = (byte)((r << 4) | r);
|
//buffer[address + 2] = (byte)((r << 4) | r);
|
||||||
buffer[address + 3] = 0xFF;
|
//buffer[address + 3] = 0xFF;
|
||||||
|
*(buffer + address) = RGB444toBGRA8888Cache_LutG[color];
|
||||||
|
*(buffer + address + 1) = RGB444toBGRA8888Cache_LutG[color];
|
||||||
|
*(buffer + address + 2) = RGB444toBGRA8888Cache_LutG[color];
|
||||||
|
*(buffer + address + 3) = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public static void RGBCGBtoBGRA8888(int color, ref byte[] buffer, int address)
|
//public static void RGBCGBtoBGRA8888(int color, ref byte[] buffer, int address)
|
||||||
@ -53,14 +100,37 @@ namespace Essgee.Emulation
|
|||||||
// buffer[address + 2] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
// buffer[address + 2] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
||||||
// buffer[address + 3] = 0xFF;
|
// buffer[address + 3] = 0xFF;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// 预计算所有可能的颜色转换
|
||||||
|
private static readonly byte[] RGBCGBtoBGRA8888Cache_LutR = new byte[32768]; // 15位颜色 = 32768种
|
||||||
|
private static readonly byte[] RGBCGBtoBGRA8888Cache_LutG = new byte[32768];
|
||||||
|
private static readonly byte[] RGBCGBtoBGRA8888Cache_LutB = new byte[32768];
|
||||||
|
|
||||||
|
static void InitRGBCGBtoBGRA8888Cache() // 静态构造函数初始化LUT
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32768; i++)
|
||||||
|
{
|
||||||
|
byte r = (byte)(i & 0x1F);
|
||||||
|
byte g = (byte)((i >> 5) & 0x1F);
|
||||||
|
byte b = (byte)((i >> 10) & 0x1F);
|
||||||
|
RGBCGBtoBGRA8888Cache_LutR[i] = (byte)(Math.Min(960, (r * 6) + (g * 4) + (b * 22)) >> 2);
|
||||||
|
RGBCGBtoBGRA8888Cache_LutG[i] = (byte)(Math.Min(960, (g * 24) + (b * 8)) >> 2);
|
||||||
|
RGBCGBtoBGRA8888Cache_LutB[i] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void RGBCGBtoBGRA8888(int color, ref byte* buffer, int address)
|
public static void RGBCGBtoBGRA8888(int color, ref byte* buffer, int address)
|
||||||
{
|
{
|
||||||
/* https://byuu.net/video/color-emulation -- "LCD emulation: Game Boy Color" */
|
/* https://byuu.net/video/color-emulation -- "LCD emulation: Game Boy Color" */
|
||||||
byte r = (byte)((color >> 0) & 0x1F), g = (byte)((color >> 5) & 0x1F), b = (byte)((color >> 10) & 0x1F);
|
//byte r = (byte)((color >> 0) & 0x1F), g = (byte)((color >> 5) & 0x1F), b = (byte)((color >> 10) & 0x1F);
|
||||||
buffer[address + 0] = (byte)(Math.Min(960, (r * 6) + (g * 4) + (b * 22)) >> 2);
|
//buffer[address + 0] = (byte)(Math.Min(960, (r * 6) + (g * 4) + (b * 22)) >> 2);
|
||||||
buffer[address + 1] = (byte)(Math.Min(960, (g * 24) + (b * 8)) >> 2);
|
//buffer[address + 1] = (byte)(Math.Min(960, (g * 24) + (b * 8)) >> 2);
|
||||||
buffer[address + 2] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
//buffer[address + 2] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
||||||
buffer[address + 3] = 0xFF;
|
//buffer[address + 3] = 0xFF;
|
||||||
|
*(buffer + address) = RGBCGBtoBGRA8888Cache_LutR[color];
|
||||||
|
*(buffer + address + 1) = RGBCGBtoBGRA8888Cache_LutG[color];
|
||||||
|
*(buffer + address + 2) = RGBCGBtoBGRA8888Cache_LutB[color];
|
||||||
|
*(buffer + address + 3) = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,8 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
bool hdmaIsActive;
|
bool hdmaIsActive;
|
||||||
byte hdmaBytesLeft;
|
byte hdmaBytesLeft;
|
||||||
|
|
||||||
public int GDMAWaitCycles { get; set; }
|
//public int GDMAWaitCycles { get; set; }
|
||||||
|
public int GDMAWaitCycles;
|
||||||
|
|
||||||
protected const byte screenUsageBackgroundHighPriority = (1 << 3);
|
protected const byte screenUsageBackgroundHighPriority = (1 << 3);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user