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;
|
sampleCycleCount = frameCycleCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//独立声明,不在函数内部
|
||||||
|
private bool[] channelEnableFlags = new bool[4];
|
||||||
public void Step(int clockCyclesInStep)
|
public void Step(int clockCyclesInStep)
|
||||||
{
|
{
|
||||||
if (!isSoundHwEnabled) return;
|
if (!isSoundHwEnabled) return;
|
||||||
@ -385,10 +387,25 @@ namespace Essgee.Emulation.Audio
|
|||||||
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||||
// mixedSampleBuffer.ToArray());
|
// 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(
|
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||||
numChannels,
|
numChannels,
|
||||||
channelSampleBuffer,
|
channelSampleBuffer,
|
||||||
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
channelEnableFlags,
|
||||||
mixedSampleBuffer,
|
mixedSampleBuffer,
|
||||||
mixedSampleBuffer_writePos);
|
mixedSampleBuffer_writePos);
|
||||||
|
|
||||||
|
|||||||
@ -44,7 +44,16 @@ namespace Essgee.Emulation
|
|||||||
buffer[address + 3] = 0xFF;
|
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" */
|
/* 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);
|
||||||
|
|||||||
@ -346,7 +346,7 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
WriteColorToFramebuffer(c, ((y * displayActiveWidth) + (x % displayActiveWidth)) * 4);
|
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);
|
RGBCGBtoBGRA8888(c, ref outputFramebuffer, address);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ using static Essgee.Emulation.CPU.SM83;
|
|||||||
|
|
||||||
namespace Essgee.Emulation.Video.Nintendo
|
namespace Essgee.Emulation.Video.Nintendo
|
||||||
{
|
{
|
||||||
public class DMGVideo : IVideo
|
public unsafe class DMGVideo : IVideo
|
||||||
{
|
{
|
||||||
protected const int displayActiveWidth = 160;
|
protected const int displayActiveWidth = 160;
|
||||||
protected const int displayActiveHeight = 144;
|
protected const int displayActiveHeight = 144;
|
||||||
@ -109,7 +109,48 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
protected byte[,] screenUsageFlags, screenUsageSpriteXCoords, screenUsageSpriteSlots;
|
protected byte[,] screenUsageFlags, screenUsageSpriteXCoords, screenUsageSpriteSlots;
|
||||||
|
|
||||||
protected int cycleCount, cycleDotPause, currentScanline;
|
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;
|
protected int clockCyclesPerLine;
|
||||||
|
|
||||||
@ -247,7 +288,10 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
screenUsageFlags = new byte[displayActiveWidth, displayActiveHeight];
|
screenUsageFlags = new byte[displayActiveWidth, displayActiveHeight];
|
||||||
screenUsageSpriteXCoords = new byte[displayActiveWidth, displayActiveHeight];
|
screenUsageSpriteXCoords = new byte[displayActiveWidth, displayActiveHeight];
|
||||||
screenUsageSpriteSlots = 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++)
|
for (var y = 0; y < displayActiveHeight; y++)
|
||||||
SetLine(y, 0xFF, 0xFF, 0xFF);
|
SetLine(y, 0xFF, 0xFF, 0xFF);
|
||||||
@ -398,7 +442,8 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GCHandle? lasyRenderHandle;
|
GCHandle? lastRenderHandle;
|
||||||
|
|
||||||
protected virtual void EndHBlank()
|
protected virtual void EndHBlank()
|
||||||
{
|
{
|
||||||
/* End of scanline reached */
|
/* End of scanline reached */
|
||||||
@ -423,16 +468,25 @@ namespace Essgee.Emulation.Video.Nintendo
|
|||||||
|
|
||||||
/* Submit screen for rendering */
|
/* Submit screen for rendering */
|
||||||
|
|
||||||
// 固定数组,防止垃圾回收器移动它
|
//// 固定数组,防止垃圾回收器移动它
|
||||||
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
|
//var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer_src.Clone() as byte[], GCHandleType.Pinned);
|
||||||
// 获取数组的指针
|
//// 获取数组的指针
|
||||||
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
|
//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);
|
var eventArgs = RenderScreenEventArgs.Create(displayActiveWidth, displayActiveHeight, mFrameDataPtr);
|
||||||
OnRenderScreen(eventArgs);
|
OnRenderScreen(eventArgs);
|
||||||
eventArgs.Release();
|
eventArgs.Release();
|
||||||
if (lasyRenderHandle != null)
|
|
||||||
lasyRenderHandle.Value.Free();
|
//if (lastRenderHandle.HasValue)
|
||||||
lasyRenderHandle = bitmapcolorRect_handle;
|
// lastRenderHandle.Value.Free();
|
||||||
|
//lastRenderHandle = bitmapcolorRect_handle;
|
||||||
|
|
||||||
//OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, outputFramebuffer.Clone() as byte[]));
|
//OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, outputFramebuffer.Clone() as byte[]));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user