forked from sin365/AxibugEmuOnline
消灭Essgee中GameBoy/DMG的音视频GC
This commit is contained in:
parent
0b7a11291c
commit
a6178e991c
@ -296,6 +296,8 @@ namespace Essgee.Emulation.Audio
|
||||
sampleCycleCount = frameCycleCount = 0;
|
||||
}
|
||||
|
||||
//独立声明,不在函数内部
|
||||
private bool[] channelEnableFlags = new bool[4];
|
||||
public void Step(int clockCyclesInStep)
|
||||
{
|
||||
if (!isSoundHwEnabled) return;
|
||||
@ -385,10 +387,25 @@ namespace Essgee.Emulation.Audio
|
||||
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||
// mixedSampleBuffer.ToArray());
|
||||
|
||||
//有GC
|
||||
//EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||
// numChannels,
|
||||
// channelSampleBuffer,
|
||||
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||
// mixedSampleBuffer,
|
||||
// mixedSampleBuffer_writePos);
|
||||
|
||||
|
||||
// 在函数中使用
|
||||
channelEnableFlags[0] = !channel1ForceEnable;
|
||||
channelEnableFlags[1] = !channel2ForceEnable;
|
||||
channelEnableFlags[2] = !channel3ForceEnable;
|
||||
channelEnableFlags[3] = !channel4ForceEnable;
|
||||
|
||||
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||
numChannels,
|
||||
channelSampleBuffer,
|
||||
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||
channelEnableFlags,
|
||||
mixedSampleBuffer,
|
||||
mixedSampleBuffer_writePos);
|
||||
|
||||
|
||||
@ -44,7 +44,16 @@ namespace Essgee.Emulation
|
||||
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)
|
||||
//{
|
||||
// /* 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);
|
||||
// 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 + 2] = (byte)(Math.Min(960, (r * 26) + (g * 4) + (b * 2)) >> 2);
|
||||
// buffer[address + 3] = 0xFF;
|
||||
//}
|
||||
public static void RGBCGBtoBGRA8888(int color, ref byte* buffer, int address)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
@ -346,7 +346,7 @@ namespace Essgee.Emulation.Video.Nintendo
|
||||
WriteColorToFramebuffer(c, ((y * displayActiveWidth) + (x % displayActiveWidth)) * 4);
|
||||
}
|
||||
|
||||
private void WriteColorToFramebuffer(ushort c, int address)
|
||||
private unsafe void WriteColorToFramebuffer(ushort c, int address)
|
||||
{
|
||||
RGBCGBtoBGRA8888(c, ref outputFramebuffer, address);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ using static Essgee.Emulation.CPU.SM83;
|
||||
|
||||
namespace Essgee.Emulation.Video.Nintendo
|
||||
{
|
||||
public class DMGVideo : IVideo
|
||||
public unsafe class DMGVideo : IVideo
|
||||
{
|
||||
protected const int displayActiveWidth = 160;
|
||||
protected const int displayActiveHeight = 144;
|
||||
@ -109,7 +109,48 @@ namespace Essgee.Emulation.Video.Nintendo
|
||||
protected byte[,] screenUsageFlags, screenUsageSpriteXCoords, screenUsageSpriteSlots;
|
||||
|
||||
protected int cycleCount, cycleDotPause, currentScanline;
|
||||
protected byte[] outputFramebuffer;
|
||||
//protected byte[] outputFramebuffer;
|
||||
|
||||
#region //指针化 outputFramebuffer
|
||||
byte[] outputFramebuffer_src;
|
||||
protected GCHandle outputFramebuffer_handle;
|
||||
public byte* outputFramebuffer;
|
||||
public int outputFramebufferLength;
|
||||
public bool outputFramebuffer_IsNull => outputFramebuffer == null;
|
||||
public byte[] outputFramebuffer_set
|
||||
{
|
||||
set
|
||||
{
|
||||
outputFramebuffer_handle.ReleaseGCHandle();
|
||||
outputFramebuffer_src = value;
|
||||
outputFramebufferLength = value.Length;
|
||||
outputFramebuffer_src.GetObjectPtr(ref outputFramebuffer_handle, ref outputFramebuffer);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region //指针化 outputFramebufferCopy
|
||||
byte[] outputFramebufferCopy_src;
|
||||
GCHandle outputFramebufferCopy_handle;
|
||||
public byte* outputFramebufferCopy;
|
||||
public int outputFramebufferCopyLength;
|
||||
public bool outputFramebufferCopy_IsNull => outputFramebufferCopy == null;
|
||||
private IntPtr outputFramebufferCopy_IntPtr;
|
||||
public byte[] outputFramebufferCopy_set
|
||||
{
|
||||
set
|
||||
{
|
||||
outputFramebufferCopy_handle.ReleaseGCHandle();
|
||||
outputFramebufferCopy_src = value;
|
||||
outputFramebufferCopyLength = value.Length;
|
||||
outputFramebufferCopy_src.GetObjectPtr(ref outputFramebufferCopy_handle, ref outputFramebufferCopy);
|
||||
outputFramebufferCopy_IntPtr = outputFramebufferCopy_handle.AddrOfPinnedObject();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
protected int clockCyclesPerLine;
|
||||
|
||||
@ -247,7 +288,10 @@ namespace Essgee.Emulation.Video.Nintendo
|
||||
screenUsageFlags = new byte[displayActiveWidth, displayActiveHeight];
|
||||
screenUsageSpriteXCoords = new byte[displayActiveWidth, displayActiveHeight];
|
||||
screenUsageSpriteSlots = new byte[displayActiveWidth, displayActiveHeight];
|
||||
outputFramebuffer = new byte[numDisplayPixels * 4];
|
||||
//outputFramebuffer = new byte[numDisplayPixels * 4];
|
||||
outputFramebuffer_set = new byte[numDisplayPixels * 4];
|
||||
|
||||
outputFramebufferCopy_set = new byte[numDisplayPixels * 4];
|
||||
|
||||
for (var y = 0; y < displayActiveHeight; y++)
|
||||
SetLine(y, 0xFF, 0xFF, 0xFF);
|
||||
@ -398,7 +442,8 @@ namespace Essgee.Emulation.Video.Nintendo
|
||||
}
|
||||
|
||||
|
||||
GCHandle? lasyRenderHandle;
|
||||
GCHandle? lastRenderHandle;
|
||||
|
||||
protected virtual void EndHBlank()
|
||||
{
|
||||
/* End of scanline reached */
|
||||
@ -423,16 +468,25 @@ namespace Essgee.Emulation.Video.Nintendo
|
||||
|
||||
/* Submit screen for rendering */
|
||||
|
||||
// 固定数组,防止垃圾回收器移动它
|
||||
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
|
||||
// 获取数组的指针
|
||||
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
|
||||
//// 固定数组,防止垃圾回收器移动它
|
||||
//var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer_src.Clone() as byte[], GCHandleType.Pinned);
|
||||
//// 获取数组的指针
|
||||
//IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
|
||||
|
||||
|
||||
for (int i = 0; i < outputFramebufferLength; i++)
|
||||
{
|
||||
outputFramebufferCopy[i] = outputFramebuffer[i];
|
||||
}
|
||||
IntPtr mFrameDataPtr = outputFramebufferCopy_IntPtr;
|
||||
|
||||
var eventArgs = RenderScreenEventArgs.Create(displayActiveWidth, displayActiveHeight, mFrameDataPtr);
|
||||
OnRenderScreen(eventArgs);
|
||||
eventArgs.Release();
|
||||
if (lasyRenderHandle != null)
|
||||
lasyRenderHandle.Value.Free();
|
||||
lasyRenderHandle = bitmapcolorRect_handle;
|
||||
|
||||
//if (lastRenderHandle.HasValue)
|
||||
// lastRenderHandle.Value.Free();
|
||||
//lastRenderHandle = bitmapcolorRect_handle;
|
||||
|
||||
//OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, outputFramebuffer.Clone() as byte[]));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user