完美像素!

This commit is contained in:
ALIENJACK\alien 2024-11-14 12:02:11 +08:00
parent 43e7ba8332
commit a064078d0d
4 changed files with 43 additions and 45 deletions

View File

@ -13413,10 +13413,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_UiScaleMode: 0 m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100 m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1 m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600} m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 0 m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0 m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3 m_PhysicalUnit: 3

View File

@ -12,7 +12,6 @@ namespace AxibugEmuOnline.Client
public RawImage Image; public RawImage Image;
private UInt32[] wrapTexBuffer;
private IntPtr wrapTexBufferPointer; private IntPtr wrapTexBufferPointer;
private Texture2D wrapTex; private Texture2D wrapTex;
private int TexBufferSize; private int TexBufferSize;
@ -24,7 +23,7 @@ namespace AxibugEmuOnline.Client
DrawCanvas.worldCamera = Camera.main; DrawCanvas.worldCamera = Camera.main;
} }
public unsafe void SetDrawData(byte* screenData, byte[] lineColorMode, int screenWidth, int screenHeight) public unsafe void SetDrawData(uint* screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
{ {
if (wrapTex == null) if (wrapTex == null)
{ {
@ -32,16 +31,12 @@ namespace AxibugEmuOnline.Client
wrapTex = new Texture2D(272, 240, TextureFormat.RGBA32, false); wrapTex = new Texture2D(272, 240, TextureFormat.RGBA32, false);
wrapTex.filterMode = FilterMode.Point; wrapTex.filterMode = FilterMode.Point;
wrapTexBuffer = new uint[screenWidth * screenHeight]; wrapTexBufferPointer = (IntPtr)screenData;
// 固定数组,防止垃圾回收器移动它
GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
// 获取数组的指针
wrapTexBufferPointer = handle.AddrOfPinnedObject();
Image.texture = wrapTex; Image.texture = wrapTex;
Image.material.SetTexture("_MainTex", wrapTex); Image.material.SetTexture("_MainTex", wrapTex);
TexBufferSize = wrapTexBuffer.Length * 4; TexBufferSize = screenWidth * screenHeight * 4;
var palRaw = PaletteDefine.m_cnPalette[0]; var palRaw = PaletteDefine.m_cnPalette[0];
pPal = new Texture2D(palRaw.Length, 1, TextureFormat.RGBA32, false); pPal = new Texture2D(palRaw.Length, 1, TextureFormat.RGBA32, false);
@ -61,11 +56,6 @@ namespace AxibugEmuOnline.Client
Image.material.SetTexture("_PalTex", pPal); Image.material.SetTexture("_PalTex", pPal);
} }
for (int i = 0; i < wrapTexBuffer.Length; i++)
{
wrapTexBuffer[i] = screenData[i];
}
wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize); wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
wrapTex.Apply(); wrapTex.Apply();
} }

View File

@ -221,7 +221,7 @@ namespace VirtualNes.Core
Debuger.Log("Allocating PPU..."); Debuger.Log("Allocating PPU...");
ppu = new PPU(this); ppu = new PPU(this);
var screenBuffer = new byte[PPU.SCREEN_WIDTH * PPU.SCREEN_HEIGHT]; var screenBuffer = new uint[PPU.SCREEN_WIDTH * PPU.SCREEN_HEIGHT];
var colormode = new byte[PPU.SCREEN_HEIGHT]; var colormode = new byte[PPU.SCREEN_HEIGHT];
ppu.SetScreenPtr(screenBuffer, colormode); ppu.SetScreenPtr(screenBuffer, colormode);

View File

@ -119,9 +119,9 @@ namespace VirtualNes.Core
private ushort loopy_shift; private ushort loopy_shift;
private GCHandle lpScreenGCH; private GCHandle lpScreenGCH;
private byte* lpScreen; private uint* lpScreen;
/// <summary> 作为lpScreen数组的索引 </summary> /// <summary> 作为lpScreen数组的索引 </summary>
private byte* lpScanline; private uint* lpScanline;
private int ScanlineNo; private int ScanlineNo;
private byte[] lpColormode; private byte[] lpColormode;
@ -479,7 +479,7 @@ namespace VirtualNes.Core
if (!bExtLatch) if (!bExtLatch)
{ {
// Without Extension Latch // Without Extension Latch
byte* pScn = lpScanline + (8 - loopy_shift); uint* pScn = lpScanline + (8 - loopy_shift);
byte* pBGw = BGwrite; byte* pBGw = BGwrite;
int tileofs = (MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8; int tileofs = (MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8;
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF); int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
@ -503,8 +503,8 @@ namespace VirtualNes.Core
if (cache_tile == tileadr && cache_attr == attr) if (cache_tile == tileadr && cache_attr == attr)
{ {
*(uint*)(pScn + 0) = *(uint*)(pScn - 8); *(UInt128*)(pScn + 0) = *(UInt128*)(pScn - 8);
*(uint*)(pScn + 4) = *(uint*)(pScn - 4); *(UInt128*)(pScn + 4) = *(UInt128*)(pScn - 4);
*(pBGw + 0) = *(pBGw - 1); *(pBGw + 0) = *(pBGw - 1);
} }
else else
@ -554,7 +554,7 @@ namespace VirtualNes.Core
else else
{ {
// With Extension Latch(For MMC5) // With Extension Latch(For MMC5)
byte* pScn = lpScanline + (8 - loopy_shift); uint* pScn = lpScanline + (8 - loopy_shift);
byte* pBGw = BGwrite; byte* pBGw = BGwrite;
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF); int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
@ -594,8 +594,8 @@ namespace VirtualNes.Core
} }
else else
{ {
*(uint*)(pScn + 0) = *(uint*)(pScn - 8); *(UInt128*)(pScn + 0) = *(UInt128*)(pScn - 8);
*(uint*)(pScn + 4) = *(uint*)(pScn - 4); *(UInt128*)(pScn + 4) = *(UInt128*)(pScn - 4);
*(pBGw + 0) = *(pBGw - 1); *(pBGw + 0) = *(pBGw - 1);
} }
pScn += 8; pScn += 8;
@ -620,7 +620,7 @@ namespace VirtualNes.Core
// Without Extension Latch // Without Extension Latch
if (!bExtNameTable) if (!bExtNameTable)
{ {
byte* pScn = lpScanline + (8 - loopy_shift); uint* pScn = lpScanline + (8 - loopy_shift);
byte* pBGw = BGwrite; byte* pBGw = BGwrite;
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF); int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
@ -671,8 +671,8 @@ namespace VirtualNes.Core
} }
else else
{ {
*(uint*)(pScn + 0) = *(uint*)(pScn - 8); *(UInt128*)(pScn + 0) = *(UInt128*)(pScn - 8);
*(uint*)(pScn + 4) = *(uint*)(pScn - 4); *(UInt128*)(pScn + 4) = *(UInt128*)(pScn - 4);
*(pBGw + 0) = *(pBGw - 1); *(pBGw + 0) = *(pBGw - 1);
} }
pScn += 8; pScn += 8;
@ -699,7 +699,7 @@ namespace VirtualNes.Core
} }
else else
{ {
byte* pScn = lpScanline + (8 - loopy_shift); uint* pScn = lpScanline + (8 - loopy_shift);
byte* pBGw = BGwrite; byte* pBGw = BGwrite;
int ntbladr; int ntbladr;
@ -747,8 +747,8 @@ namespace VirtualNes.Core
} }
else else
{ {
*(uint*)(pScn + 0) = *(uint*)(pScn - 8); *(UInt128*)(pScn + 0) = *(UInt128*)(pScn - 8);
*(uint*)(pScn + 4) = *(uint*)(pScn - 4); *(UInt128*)(pScn + 4) = *(UInt128*)(pScn - 4);
*(pBGw + 0) = *(pBGw - 1); *(pBGw + 0) = *(pBGw - 1);
} }
pScn += 8; pScn += 8;
@ -775,7 +775,7 @@ namespace VirtualNes.Core
else else
{ {
// With Extension Latch(For MMC5) // With Extension Latch(For MMC5)
byte* pScn = lpScanline + (8 - loopy_shift); uint* pScn = lpScanline + (8 - loopy_shift);
byte* pBGw = BGwrite; byte* pBGw = BGwrite;
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF); int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
@ -819,8 +819,8 @@ namespace VirtualNes.Core
} }
else else
{ {
*(uint*)(pScn + 0) = *(uint*)(pScn - 8); *(UInt128*)(pScn + 0) = *(UInt128*)(pScn - 8);
*(uint*)(pScn + 4) = *(uint*)(pScn - 4); *(UInt128*)(pScn + 4) = *(UInt128*)(pScn - 4);
*(pBGw + 0) = *(pBGw - 1); *(pBGw + 0) = *(pBGw - 1);
} }
pScn += 8; pScn += 8;
@ -840,7 +840,7 @@ namespace VirtualNes.Core
} }
if ((MMU.PPUREG[1] & PPU_BGCLIP_BIT) == 0 && bLeftClip) if ((MMU.PPUREG[1] & PPU_BGCLIP_BIT) == 0 && bLeftClip)
{ {
byte* pScn = lpScanline + 8; uint* pScn = lpScanline + 8;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
pScn[i] = MMU.BGPAL[0]; pScn[i] = MMU.BGPAL[0];
@ -960,7 +960,7 @@ namespace VirtualNes.Core
fixed (byte* pSPPAL = &MMU.SPPAL[(sp.attr & SP_COLOR_BIT) << 2]) fixed (byte* pSPPAL = &MMU.SPPAL[(sp.attr & SP_COLOR_BIT) << 2])
{ {
// Ptr // Ptr
byte* pScn = lpScanline + sp.x + 8; uint* pScn = lpScanline + sp.x + 8;
if (!bExtMono) if (!bExtMono)
{ {
@ -982,13 +982,13 @@ namespace VirtualNes.Core
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA); int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA); int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
if ((SPpat & 0x80) != 0) pScn[0] = (byte)(pSPPAL[c1>>6] |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 & 0x08) != 0) pScn[4] = (byte)(pSPPAL[(c1 >> 2) & 3] | mono);
if ((SPpat & 0x40) != 0) pScn[1] = (byte)(pSPPAL[c2>>6] |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 & 0x04) != 0) pScn[5] = (byte)(pSPPAL[(c2 >> 2) & 3] | mono);
if ((SPpat & 0x20) != 0) pScn[2] = (byte)(pSPPAL[(c1>>4)&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 & 0x02) != 0) pScn[6] = (byte)(pSPPAL[c1 & 3] | mono);
if ((SPpat & 0x10) != 0) pScn[3] = (byte)(pSPPAL[(c2>>4)&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 ((SPpat & 0x01) != 0) pScn[7] = (byte)(pSPPAL[c2 & 3] | mono);
} }
} }
@ -1082,7 +1082,7 @@ namespace VirtualNes.Core
MMU.PPUREG[2] |= PPU_VBLANK_FLAG; MMU.PPUREG[2] |= PPU_VBLANK_FLAG;
} }
public byte* GetScreenPtr() public uint* GetScreenPtr()
{ {
return lpScreen; return lpScreen;
} }
@ -1092,10 +1092,10 @@ namespace VirtualNes.Core
return lpColormode; return lpColormode;
} }
internal void SetScreenPtr(byte[] screenBuffer, byte[] colormode) internal void SetScreenPtr(uint[] screenBuffer, byte[] colormode)
{ {
lpScreenGCH = GCHandle.Alloc(screenBuffer, GCHandleType.Pinned); lpScreenGCH = GCHandle.Alloc(screenBuffer, GCHandleType.Pinned);
lpScreen = (byte*)lpScreenGCH.AddrOfPinnedObject(); lpScreen = (uint*)lpScreenGCH.AddrOfPinnedObject();
lpColormode = colormode; lpColormode = colormode;
} }
@ -1179,4 +1179,12 @@ namespace VirtualNes.Core
} }
} }
} }
public struct UInt128
{
public UInt32 a;
public UInt32 b;
public UInt32 c;
public UInt32 d;
}
} }