forked from sin365/AxibugEmuOnline
ppu lpScreen改为指针版本
This commit is contained in:
parent
3913595b18
commit
43e7ba8332
@ -51,7 +51,7 @@ namespace AxibugEmuOnline.Client
|
||||
NesCore = null;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
private unsafe void Update()
|
||||
{
|
||||
if (m_bPause) return;
|
||||
|
||||
@ -63,7 +63,7 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
var screenBuffer = NesCore.ppu.GetScreenPtr();
|
||||
var lineColorMode = NesCore.ppu.GetLineColorMode();
|
||||
VideoProvider.SetDrawData(screenBuffer, lineColorMode, 256, 240);
|
||||
VideoProvider.SetDrawData(screenBuffer, lineColorMode, 277, 240);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,15 @@ namespace AxibugEmuOnline.Client
|
||||
DrawCanvas.worldCamera = Camera.main;
|
||||
}
|
||||
|
||||
public void SetDrawData(uint[] screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
|
||||
public unsafe void SetDrawData(byte* screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
|
||||
{
|
||||
if (wrapTex == null)
|
||||
{
|
||||
//wrapTex = new Texture2D(272, 240, TextureFormat.BGRA32, false);
|
||||
wrapTex = new Texture2D(272, 240, TextureFormat.RGBA32, false);
|
||||
wrapTex.filterMode = FilterMode.Point;
|
||||
wrapTexBuffer = screenData;
|
||||
|
||||
wrapTexBuffer = new uint[screenWidth * screenHeight];
|
||||
// 固定数组,防止垃圾回收器移动它
|
||||
GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
|
||||
// 获取数组的指针
|
||||
@ -44,7 +44,6 @@ namespace AxibugEmuOnline.Client
|
||||
TexBufferSize = wrapTexBuffer.Length * 4;
|
||||
|
||||
var palRaw = PaletteDefine.m_cnPalette[0];
|
||||
//pPal = new Texture2D(palRaw.Length, 1, TextureFormat.BGRA32, 1, true);
|
||||
pPal = new Texture2D(palRaw.Length, 1, TextureFormat.RGBA32, false);
|
||||
pPal.filterMode = FilterMode.Point;
|
||||
for (int i = 0; i < palRaw.Length; i++)
|
||||
@ -62,6 +61,11 @@ namespace AxibugEmuOnline.Client
|
||||
Image.material.SetTexture("_PalTex", pPal);
|
||||
}
|
||||
|
||||
for (int i = 0; i < wrapTexBuffer.Length; i++)
|
||||
{
|
||||
wrapTexBuffer[i] = screenData[i];
|
||||
}
|
||||
|
||||
wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
|
||||
wrapTex.Apply();
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ namespace VirtualNes.Core
|
||||
Debuger.Log("Allocating PPU...");
|
||||
ppu = new PPU(this);
|
||||
|
||||
var screenBuffer = new uint[PPU.SCREEN_WIDTH * PPU.SCREEN_HEIGHT];
|
||||
var screenBuffer = new byte[PPU.SCREEN_WIDTH * PPU.SCREEN_HEIGHT];
|
||||
var colormode = new byte[PPU.SCREEN_HEIGHT];
|
||||
|
||||
ppu.SetScreenPtr(screenBuffer, colormode);
|
||||
@ -840,7 +840,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
}
|
||||
|
||||
internal void DrawFont(int x, int y, byte chr, byte col)
|
||||
internal unsafe void DrawFont(int x, int y, byte chr, byte col)
|
||||
{
|
||||
int i;
|
||||
int pFnt;
|
||||
@ -866,7 +866,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBitmap(int x, int y, byte[] bitMap)
|
||||
private unsafe void DrawBitmap(int x, int y, byte[] bitMap)
|
||||
{
|
||||
int i, j;
|
||||
int h, v;
|
||||
|
@ -1,10 +1,24 @@
|
||||
namespace VirtualNes.Core
|
||||
using Codice.CM.Client.Differences;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class PPU
|
||||
public unsafe class PPU
|
||||
{
|
||||
public const int SCREEN_WIDTH = 256 + 16;
|
||||
public const int SCREEN_WIDTH = 272;
|
||||
public const int SCREEN_HEIGHT = 240;
|
||||
|
||||
private GCHandle BGwriteGCH;
|
||||
private GCHandle BGmonoGCH;
|
||||
private GCHandle SPwriteGCH;
|
||||
|
||||
private byte* BGwrite;
|
||||
private byte* BGmono;
|
||||
private byte* SPwrite;
|
||||
|
||||
private static byte[][] CreateCOLORMAP()
|
||||
{
|
||||
byte[][] res = new byte[5][];
|
||||
@ -104,9 +118,10 @@
|
||||
private ushort loopy_y;
|
||||
private ushort loopy_shift;
|
||||
|
||||
private uint[] lpScreen;
|
||||
private GCHandle lpScreenGCH;
|
||||
private byte* lpScreen;
|
||||
/// <summary> 作为lpScreen数组的索引 </summary>
|
||||
private int lpScanline;
|
||||
private byte* lpScanline;
|
||||
private int ScanlineNo;
|
||||
private byte[] lpColormode;
|
||||
|
||||
@ -137,9 +152,22 @@
|
||||
}
|
||||
Bit2Rev[i] = c;
|
||||
}
|
||||
|
||||
BGwriteGCH = GCHandle.Alloc(new byte[33 + 1], GCHandleType.Pinned);
|
||||
BGmonoGCH = GCHandle.Alloc(new byte[33 + 1], GCHandleType.Pinned);
|
||||
SPwriteGCH = GCHandle.Alloc(new byte[33 + 1], GCHandleType.Pinned);
|
||||
BGwrite = (byte*)BGwriteGCH.AddrOfPinnedObject();
|
||||
BGmono = (byte*)BGmonoGCH.AddrOfPinnedObject();
|
||||
SPwrite = (byte*)SPwriteGCH.AddrOfPinnedObject();
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
public void Dispose()
|
||||
{
|
||||
lpScreenGCH.Free();
|
||||
BGwriteGCH.Free();
|
||||
BGmonoGCH.Free();
|
||||
SPwriteGCH.Free();
|
||||
}
|
||||
|
||||
internal byte Read(ushort addr)
|
||||
{
|
||||
@ -199,7 +227,7 @@
|
||||
ScanlineNo = scanline;
|
||||
if (scanline < 240)
|
||||
{
|
||||
lpScanline = (SCREEN_WIDTH) * scanline;
|
||||
lpScanline = lpScreen + SCREEN_WIDTH * scanline;
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +386,7 @@
|
||||
loopy_shift = 0;
|
||||
|
||||
if (lpScreen != null)
|
||||
MemoryUtility.memset(lpScreen, 0, 0x3F, SCREEN_WIDTH * SCREEN_HEIGHT);
|
||||
Unsafe.InitBlockUnaligned(lpScreen, 0, SCREEN_WIDTH * SCREEN_HEIGHT);
|
||||
if (lpColormode != null)
|
||||
MemoryUtility.memset(lpColormode, 0, SCREEN_HEIGHT);
|
||||
}
|
||||
@ -374,7 +402,7 @@
|
||||
|
||||
if (lpScreen != null)
|
||||
{
|
||||
MemoryUtility.memset(lpScreen, 0, 0x3F, SCREEN_WIDTH);
|
||||
Unsafe.InitBlockUnaligned(lpScreen, 0x3F, SCREEN_WIDTH);
|
||||
}
|
||||
if (lpColormode != null)
|
||||
{
|
||||
@ -425,18 +453,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] BGwrite = new byte[33 + 1];
|
||||
private byte[] BGmono = new byte[33 + 1];
|
||||
private byte[] SPwrite = new byte[33 + 1];
|
||||
|
||||
internal void Scanline(int scanline, bool bMax, bool bLeftClip)
|
||||
{
|
||||
int pScn = 0;
|
||||
int pBGw = 0;
|
||||
byte chr_h = 0, chr_l = 0, attr = 0;
|
||||
|
||||
MemoryUtility.ZEROMEMORY(BGwrite, BGwrite.Length);
|
||||
MemoryUtility.ZEROMEMORY(BGmono, BGmono.Length);
|
||||
Unsafe.InitBlockUnaligned(BGwrite, 0, 34);
|
||||
Unsafe.InitBlockUnaligned(BGmono, 0, 34);
|
||||
|
||||
// Linecolor mode
|
||||
lpColormode[scanline] = (byte)(((MMU.PPUREG[1] & PPU_BGCOLOR_BIT) >> 5) | ((MMU.PPUREG[1] & PPU_COLORMODE_BIT) << 7));
|
||||
@ -444,7 +466,7 @@
|
||||
// Render BG
|
||||
if ((MMU.PPUREG[1] & PPU_BGDISP_BIT) == 0)
|
||||
{
|
||||
MemoryUtility.memset(lpScreen, lpScanline, MMU.BGPAL[0], SCREEN_WIDTH);
|
||||
Unsafe.InitBlockUnaligned(lpScanline, MMU.BGPAL[0], SCREEN_WIDTH);
|
||||
if (nes.GetRenderMethod() == EnumRenderMethod.TILE_RENDER)
|
||||
{
|
||||
nes.EmulationCPU(NES.FETCH_CYCLES * 4 * 32);
|
||||
@ -457,9 +479,8 @@
|
||||
if (!bExtLatch)
|
||||
{
|
||||
// Without Extension Latch
|
||||
pScn = lpScanline + (8 - loopy_shift);
|
||||
pBGw = 0;
|
||||
|
||||
byte* pScn = lpScanline + (8 - loopy_shift);
|
||||
byte* pBGw = BGwrite;
|
||||
int tileofs = (MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8;
|
||||
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||
int attradr = 0x23C0 + (MMU.loopy_v & 0x0C00) + ((MMU.loopy_v & 0x0380) >> 4);
|
||||
@ -475,7 +496,6 @@
|
||||
|
||||
attradr &= 0x3FF;
|
||||
|
||||
|
||||
for (int i = 0; i < 33; i++)
|
||||
{
|
||||
tileadr = tileofs + pNTBL[ntbladr & 0x03FF] * 0x10 + loopy_y;
|
||||
@ -483,17 +503,9 @@
|
||||
|
||||
if (cache_tile == tileadr && cache_attr == attr)
|
||||
{
|
||||
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||
|
||||
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||
|
||||
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||
*(uint*)(pScn + 0) = *(uint*)(pScn - 8);
|
||||
*(uint*)(pScn + 4) = *(uint*)(pScn - 4);
|
||||
*(pBGw + 0) = *(pBGw - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -501,20 +513,20 @@
|
||||
cache_attr = attr;
|
||||
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
BGwrite[pBGw] = (byte)(chr_h | chr_l);
|
||||
*pBGw = (byte)(chr_h | chr_l);
|
||||
|
||||
int pBGPAL = attr;
|
||||
fixed (byte* pBGPAL = &MMU.BGPAL[attr])
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c1 >> 6))];
|
||||
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||
pScn[0] = pBGPAL[(c1 >> 6)];
|
||||
pScn[4] = pBGPAL[(c1 >> 2) & 3];
|
||||
pScn[1] = pBGPAL[(c2 >> 6)];
|
||||
pScn[5] = pBGPAL[(c2 >> 2) & 3];
|
||||
pScn[2] = pBGPAL[(c1 >> 4) & 3];
|
||||
pScn[6] = pBGPAL[c1 & 3];
|
||||
pScn[3] = pBGPAL[(c2 >> 4) & 3];
|
||||
pScn[7] = pBGPAL[c2 & 3];
|
||||
}
|
||||
}
|
||||
pScn += 8;
|
||||
@ -542,8 +554,8 @@
|
||||
else
|
||||
{
|
||||
// With Extension Latch(For MMC5)
|
||||
pScn = lpScanline + (8 - loopy_shift);
|
||||
pBGw = 0;
|
||||
byte* pScn = lpScanline + (8 - loopy_shift);
|
||||
byte* pBGw = BGwrite;
|
||||
|
||||
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||
int ntbl_x = ntbladr & 0x1F;
|
||||
@ -564,35 +576,27 @@
|
||||
{
|
||||
cache_tile = ((chr_h << 8) + chr_l);
|
||||
cache_attr = attr;
|
||||
BGwrite[pBGw] = (byte)(chr_h | chr_l);
|
||||
*pBGw = (byte)(chr_h | chr_l);
|
||||
|
||||
int pBGPAL = attr;
|
||||
fixed (byte* pBGPAL = &MMU.BGPAL[attr])
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + (c2 >> 6)];
|
||||
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||
pScn[0] = pBGPAL[(c1 >> 6)];
|
||||
pScn[4] = pBGPAL[(c1 >> 2) & 3];
|
||||
pScn[1] = pBGPAL[(c2 >> 6)];
|
||||
pScn[5] = pBGPAL[(c2 >> 2) & 3];
|
||||
pScn[2] = pBGPAL[(c1 >> 4) & 3];
|
||||
pScn[6] = pBGPAL[c1 & 3];
|
||||
pScn[3] = pBGPAL[(c2 >> 4) & 3];
|
||||
pScn[7] = pBGPAL[c2 & 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||
|
||||
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||
|
||||
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||
*(uint*)(pScn + 0) = *(uint*)(pScn - 8);
|
||||
*(uint*)(pScn + 4) = *(uint*)(pScn - 4);
|
||||
*(pBGw + 0) = *(pBGw - 1);
|
||||
}
|
||||
pScn += 8;
|
||||
pBGw++;
|
||||
@ -616,8 +620,8 @@
|
||||
// Without Extension Latch
|
||||
if (!bExtNameTable)
|
||||
{
|
||||
pScn = lpScanline + (8 - loopy_shift);
|
||||
pBGw = 0;
|
||||
byte* pScn = lpScanline + (8 - loopy_shift);
|
||||
byte* pBGw = BGwrite;
|
||||
|
||||
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||
int attradr = 0x03C0 + ((MMU.loopy_v & 0x0380) >> 4);
|
||||
@ -649,35 +653,27 @@
|
||||
|
||||
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
lpScreen[pBGw] = (byte)(chr_l | chr_h);
|
||||
*pBGw = (byte)(chr_l | chr_h);
|
||||
|
||||
int pBGPAL = attr;
|
||||
fixed (byte* pBGPAL = &MMU.BGPAL[attr])
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c2 >> 6))];
|
||||
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||
pScn[0] = pBGPAL[(c1 >> 6)];
|
||||
pScn[4] = pBGPAL[(c1 >> 2) & 3];
|
||||
pScn[1] = pBGPAL[(c2 >> 6)];
|
||||
pScn[5] = pBGPAL[(c2 >> 2) & 3];
|
||||
pScn[2] = pBGPAL[(c1 >> 4) & 3];
|
||||
pScn[6] = pBGPAL[c1 & 3];
|
||||
pScn[3] = pBGPAL[(c2 >> 4) & 3];
|
||||
pScn[7] = pBGPAL[c2 & 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||
|
||||
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||
|
||||
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||
*(uint*)(pScn + 0) = *(uint*)(pScn - 8);
|
||||
*(uint*)(pScn + 4) = *(uint*)(pScn - 4);
|
||||
*(pBGw + 0) = *(pBGw - 1);
|
||||
}
|
||||
pScn += 8;
|
||||
pBGw++;
|
||||
@ -703,8 +699,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
pScn = lpScanline + (8 - loopy_shift);
|
||||
pBGw = 0;
|
||||
byte* pScn = lpScanline + (8 - loopy_shift);
|
||||
byte* pBGw = BGwrite;
|
||||
|
||||
int ntbladr;
|
||||
int tileadr;
|
||||
@ -733,35 +729,27 @@
|
||||
|
||||
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
BGwrite[pBGw] = (byte)(chr_l | chr_h);
|
||||
*pBGw = (byte)(chr_l | chr_h);
|
||||
|
||||
int pBGPAL = attr;
|
||||
fixed (byte* pBGPAL = &MMU.BGPAL[attr])
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + (c2 >> 6)];
|
||||
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||
pScn[0] = pBGPAL[(c1 >> 6)];
|
||||
pScn[4] = pBGPAL[(c1 >> 2) & 3];
|
||||
pScn[1] = pBGPAL[(c2 >> 6)];
|
||||
pScn[5] = pBGPAL[(c2 >> 2) & 3];
|
||||
pScn[2] = pBGPAL[(c1 >> 4) & 3];
|
||||
pScn[6] = pBGPAL[c1 & 3];
|
||||
pScn[3] = pBGPAL[(c2 >> 4) & 3];
|
||||
pScn[7] = pBGPAL[c2 & 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||
|
||||
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||
|
||||
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||
*(uint*)(pScn + 0) = *(uint*)(pScn - 8);
|
||||
*(uint*)(pScn + 4) = *(uint*)(pScn - 4);
|
||||
*(pBGw + 0) = *(pBGw - 1);
|
||||
}
|
||||
pScn += 8;
|
||||
pBGw++;
|
||||
@ -787,8 +775,8 @@
|
||||
else
|
||||
{
|
||||
// With Extension Latch(For MMC5)
|
||||
pScn = lpScanline + (8 - loopy_shift);
|
||||
pBGw = 0;
|
||||
byte* pScn = lpScanline + (8 - loopy_shift);
|
||||
byte* pBGw = BGwrite;
|
||||
|
||||
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||
int ntbl_x = ntbladr & 0x1F;
|
||||
@ -813,35 +801,27 @@
|
||||
{
|
||||
cache_tile = ((chr_h << 8) + chr_l);
|
||||
cache_attr = attr;
|
||||
BGwrite[pBGw] = (byte)(chr_l | chr_h);
|
||||
*pBGw = (byte)(chr_l | chr_h);
|
||||
|
||||
int pBGPAL = attr;
|
||||
fixed (byte* pBGPAL = &MMU.BGPAL[attr])
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + ((c1 >> 6))];
|
||||
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c2 >> 6))];
|
||||
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||
pScn[0] = pBGPAL[(c1 >> 6)];
|
||||
pScn[4] = pBGPAL[(c1 >> 2) & 3];
|
||||
pScn[1] = pBGPAL[(c2 >> 6)];
|
||||
pScn[5] = pBGPAL[(c2 >> 2) & 3];
|
||||
pScn[2] = pBGPAL[(c1 >> 4) & 3];
|
||||
pScn[6] = pBGPAL[c1 & 3];
|
||||
pScn[3] = pBGPAL[(c2 >> 4) & 3];
|
||||
pScn[7] = pBGPAL[c2 & 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||
|
||||
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||
|
||||
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||
*(uint*)(pScn + 0) = *(uint*)(pScn - 8);
|
||||
*(uint*)(pScn + 4) = *(uint*)(pScn - 4);
|
||||
*(pBGw + 0) = *(pBGw - 1);
|
||||
}
|
||||
pScn += 8;
|
||||
pBGw++;
|
||||
@ -860,17 +840,17 @@
|
||||
}
|
||||
if ((MMU.PPUREG[1] & PPU_BGCLIP_BIT) == 0 && bLeftClip)
|
||||
{
|
||||
pScn = lpScanline + 8;
|
||||
byte* pScn = lpScanline + 8;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
lpScreen[i] = MMU.BGPAL[0];
|
||||
pScn[i] = MMU.BGPAL[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render sprites
|
||||
var temp = ~PPU_SPMAX_FLAG;
|
||||
MMU.PPUREG[2] = (byte)(MMU.PPUREG[2] & temp);
|
||||
MMU.PPUREG[2] &= (byte)(MMU.PPUREG[2] & temp);
|
||||
|
||||
// 昞帵婜娫奜偱偁傟偽僉儍儞僙儖
|
||||
if (scanline > 239)
|
||||
@ -885,12 +865,11 @@
|
||||
int spraddr = 0, sp_y = 0, sp_h = 0;
|
||||
chr_h = chr_l = 0;
|
||||
|
||||
|
||||
pBGw = 0;
|
||||
int pSPw = 0;
|
||||
int pBit2Rev = 0;
|
||||
|
||||
MemoryUtility.ZEROMEMORY(SPwrite, SPwrite.Length);
|
||||
fixed (byte* pBit2Rev = &Bit2Rev[0])
|
||||
{
|
||||
byte* pBGw = BGwrite;
|
||||
byte* pSPw = SPwrite;
|
||||
Unsafe.InitBlockUnaligned(pSPw, 0, 34);
|
||||
|
||||
spmax = 0;
|
||||
Sprite sp = new Sprite(MMU.SPRAM, 0);
|
||||
@ -940,8 +919,8 @@
|
||||
// pattern mask
|
||||
if ((sp.attr & SP_HMIRROR_BIT) != 0)
|
||||
{
|
||||
chr_l = Bit2Rev[pBit2Rev + chr_l];
|
||||
chr_h = Bit2Rev[pBit2Rev + chr_h];
|
||||
chr_l = pBit2Rev[chr_l];
|
||||
chr_h = pBit2Rev[chr_h];
|
||||
}
|
||||
byte SPpat = (byte)(chr_l | chr_h);
|
||||
|
||||
@ -950,10 +929,7 @@
|
||||
{
|
||||
int BGpos = ((sp.x & 0xF8) + ((loopy_shift + (sp.x & 7)) & 8)) >> 3;
|
||||
int BGsft = 8 - ((loopy_shift + sp.x) & 7);
|
||||
|
||||
var temp1 = BGwrite[pBGw + BGpos + 0] << 8;
|
||||
var temp2 = BGwrite[pBGw + BGpos + 1];
|
||||
byte BGmsk = (byte)((temp1 | temp2) >> BGsft);
|
||||
byte BGmsk = (byte)(((pBGw[BGpos + 0] << 8) | pBGw[BGpos + 1]) >> BGsft);
|
||||
|
||||
if ((SPpat & BGmsk) != 0)
|
||||
{
|
||||
@ -964,10 +940,10 @@
|
||||
// Sprite mask
|
||||
int SPpos = sp.x / 8;
|
||||
int SPsft = 8 - (sp.x & 7);
|
||||
byte SPmsk = (byte)((SPwrite[pSPw + SPpos + 0] << 8 | SPwrite[pSPw + SPpos + 1]) >> SPsft);
|
||||
byte SPmsk = (byte)(((pSPw[SPpos + 0] << 8) | pSPw[SPpos + 1]) >> SPsft);
|
||||
ushort SPwrt = (ushort)(SPpat << SPsft);
|
||||
SPwrite[pSPw + SPpos + 0] = (byte)(SPwrite[pSPw + SPpos + 0] | SPwrt >> 8);
|
||||
SPwrite[pSPw + SPpos + 1] = (byte)(SPwrite[pSPw + SPpos + 1] | SPwrt & 0xFF);
|
||||
pSPw[SPpos + 0] = (byte)((pSPw[SPpos + 0]) | (SPwrt >> 8));
|
||||
pSPw[SPpos + 1] = (byte)((pSPw[SPpos + 1]) | (SPwrt & 0xFF));
|
||||
SPpat = (byte)(SPpat & ~SPmsk);
|
||||
|
||||
if ((sp.attr & SP_PRIORITY_BIT) != 0)
|
||||
@ -975,28 +951,29 @@
|
||||
// BG > SP priority
|
||||
int BGpos = ((sp.x & 0xF8) + ((loopy_shift + (sp.x & 7)) & 8)) >> 3;
|
||||
int BGsft = 8 - ((loopy_shift + sp.x) & 7);
|
||||
byte BGmsk = (byte)(((BGwrite[pBGw + BGpos + 0] << 8) | BGwrite[pBGw + BGpos + 1]) >> BGsft);
|
||||
byte BGmsk = (byte)(((pBGw[BGpos + 0] << 8) | pBGw[BGpos + 1]) >> BGsft);
|
||||
|
||||
SPpat = (byte)(SPpat & ~BGmsk);
|
||||
}
|
||||
|
||||
// Attribute
|
||||
int pSPPAL = (sp.attr & SP_COLOR_BIT) << 2;
|
||||
fixed (byte* pSPPAL = &MMU.SPPAL[(sp.attr & SP_COLOR_BIT) << 2])
|
||||
{
|
||||
// Ptr
|
||||
pScn = lpScanline + sp.x + 8;
|
||||
byte* pScn = lpScanline + sp.x + 8;
|
||||
|
||||
if (!bExtMono)
|
||||
{
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
if ((SPpat & 0x80) != 0) lpScreen[pScn + 0] = MMU.SPPAL[pSPPAL + (c1 >> 6)];
|
||||
if ((SPpat & 0x08) != 0) lpScreen[pScn + 4] = MMU.SPPAL[pSPPAL + ((c1 >> 2) & 3)];
|
||||
if ((SPpat & 0x40) != 0) lpScreen[pScn + 1] = MMU.SPPAL[pSPPAL + ((c2 >> 6))];
|
||||
if ((SPpat & 0x04) != 0) lpScreen[pScn + 5] = MMU.SPPAL[pSPPAL + ((c2 >> 2) & 3)];
|
||||
if ((SPpat & 0x20) != 0) lpScreen[pScn + 2] = MMU.SPPAL[pSPPAL + ((c1 >> 4) & 3)];
|
||||
if ((SPpat & 0x02) != 0) lpScreen[pScn + 6] = MMU.SPPAL[pSPPAL + (c1 & 3)];
|
||||
if ((SPpat & 0x10) != 0) lpScreen[pScn + 3] = MMU.SPPAL[pSPPAL + ((c2 >> 4) & 3)];
|
||||
if ((SPpat & 0x01) != 0) lpScreen[pScn + 7] = MMU.SPPAL[pSPPAL + (c2 & 3)];
|
||||
if ((SPpat & 0x80) != 0) pScn[0] = pSPPAL[(c1 >> 6)];
|
||||
if ((SPpat & 0x08) != 0) pScn[4] = pSPPAL[(c1 >> 2) & 3];
|
||||
if ((SPpat & 0x40) != 0) pScn[1] = pSPPAL[(c2 >> 6)];
|
||||
if ((SPpat & 0x04) != 0) pScn[5] = pSPPAL[(c2 >> 2) & 3];
|
||||
if ((SPpat & 0x20) != 0) pScn[2] = pSPPAL[(c1 >> 4) & 3];
|
||||
if ((SPpat & 0x02) != 0) pScn[6] = pSPPAL[c1 & 3];
|
||||
if ((SPpat & 0x10) != 0) pScn[3] = pSPPAL[(c2 >> 4) & 3];
|
||||
if ((SPpat & 0x01) != 0) pScn[7] = pSPPAL[c2 & 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1005,14 +982,15 @@
|
||||
|
||||
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||
if ((SPpat & 0x80) != 0) lpScreen[pScn + 0] = (byte)(MMU.SPPAL[pSPPAL + (c1 >> 6)] | mono);
|
||||
if ((SPpat & 0x08) != 0) lpScreen[pScn + 4] = (byte)(MMU.SPPAL[pSPPAL + ((c1 >> 2) & 3)] | mono);
|
||||
if ((SPpat & 0x40) != 0) lpScreen[pScn + 1] = (byte)(MMU.SPPAL[pSPPAL + (c2 >> 6)] | mono);
|
||||
if ((SPpat & 0x04) != 0) lpScreen[pScn + 5] = (byte)(MMU.SPPAL[pSPPAL + ((c2 >> 2) & 3)] | mono);
|
||||
if ((SPpat & 0x20) != 0) lpScreen[pScn + 2] = (byte)(MMU.SPPAL[pSPPAL + ((c1 >> 4) & 3)] | mono);
|
||||
if ((SPpat & 0x02) != 0) lpScreen[pScn + 6] = (byte)(MMU.SPPAL[pSPPAL + (c1 & 3)] | mono);
|
||||
if ((SPpat & 0x10) != 0) lpScreen[pScn + 3] = (byte)(MMU.SPPAL[pSPPAL + ((c2 >> 4) & 3)] | mono);
|
||||
if ((SPpat & 0x01) != 0) lpScreen[pScn + 7] = (byte)(MMU.SPPAL[pSPPAL + (c2 & 3)] | mono);
|
||||
if ((SPpat & 0x80) != 0) pScn[0] = (byte)(pSPPAL[c1>>6] |mono);
|
||||
if ((SPpat & 0x08) != 0) pScn[4] = (byte)(pSPPAL[(c1>>2)&3] |mono);
|
||||
if ((SPpat & 0x40) != 0) pScn[1] = (byte)(pSPPAL[c2>>6] |mono);
|
||||
if ((SPpat & 0x04) != 0) pScn[5] = (byte)(pSPPAL[(c2>>2)&3] |mono);
|
||||
if ((SPpat & 0x20) != 0) pScn[2] = (byte)(pSPPAL[(c1>>4)&3] |mono);
|
||||
if ((SPpat & 0x02) != 0) pScn[6] = (byte)(pSPPAL[c1&3] |mono);
|
||||
if ((SPpat & 0x10) != 0) pScn[3] = (byte)(pSPPAL[(c2>>4)&3] |mono);
|
||||
if ((SPpat & 0x01) != 0) pScn[7] = (byte)(pSPPAL[c2 & 3] | mono);
|
||||
}
|
||||
}
|
||||
|
||||
if (++spmax > 8 - 1)
|
||||
@ -1026,6 +1004,7 @@
|
||||
MMU.PPUREG[2] |= PPU_SPMAX_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsSprite0(int scanline)
|
||||
{
|
||||
@ -1103,7 +1082,7 @@
|
||||
MMU.PPUREG[2] |= PPU_VBLANK_FLAG;
|
||||
}
|
||||
|
||||
public uint[] GetScreenPtr()
|
||||
public byte* GetScreenPtr()
|
||||
{
|
||||
return lpScreen;
|
||||
}
|
||||
@ -1113,9 +1092,10 @@
|
||||
return lpColormode;
|
||||
}
|
||||
|
||||
internal void SetScreenPtr(uint[] screenBuffer, byte[] colormode)
|
||||
internal void SetScreenPtr(byte[] screenBuffer, byte[] colormode)
|
||||
{
|
||||
lpScreen = screenBuffer;
|
||||
lpScreenGCH = GCHandle.Alloc(screenBuffer, GCHandleType.Pinned);
|
||||
lpScreen = (byte*)lpScreenGCH.AddrOfPinnedObject();
|
||||
lpColormode = colormode;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user