完美像素!

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_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3

View File

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

View File

@ -221,7 +221,7 @@ namespace VirtualNes.Core
Debuger.Log("Allocating PPU...");
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];
ppu.SetScreenPtr(screenBuffer, colormode);

View File

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