forked from sin365/AxibugEmuOnline
完美像素!
This commit is contained in:
parent
43e7ba8332
commit
a064078d0d
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user