AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/NesEmulator/VideoProvider.cs

68 lines
2.0 KiB
C#

using AxibugEmuOnline.Client.Assets.Script.NesEmulator;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client
{
public class VideoProvider : MonoBehaviour
{
public RawImage Image;
private UInt32[] wrapTexBuffer;
private IntPtr wrapTexBufferPointer;
private Texture2D wrapTex;
private int TexBufferSize;
private uint[] pPal;
public void SetDrawData(byte[] screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
{
if (wrapTex == null)
{
wrapTex = new Texture2D(screenWidth, screenHeight, TextureFormat.BGRA32, false);
wrapTexBuffer = new UInt32[screenWidth * screenHeight];
// 固定数组,防止垃圾回收器移动它
GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
// 获取数组的指针
wrapTexBufferPointer = handle.AddrOfPinnedObject();
Image.texture = wrapTex;
pPal = PaletteDefine.m_cnPalette[0];
TexBufferSize = wrapTexBuffer.Length * 4;
}
int pScn = 0;
int width;
var Dst = wrapTexBuffer;
var pDst = 0;
for (int line = 0; line < screenHeight; line++)
{
width = screenWidth;
while (width > 0)
{
var edx = screenData[pScn + 8];
int index = edx & 0xFF;
var colorData = pPal[index];
Dst[pDst] = 0xFF000000 | colorData;
pScn += 1;
pDst += 1;
width -= 1;
}
pScn += 16;// PPU.SCREEN_WIDTH - screenWidth;
}
wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
wrapTex.Apply();
}
}
}