175 lines
5.7 KiB
C#
175 lines
5.7 KiB
C#
|
using System;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.UI;
|
|||
|
using VirtualNes.Core;
|
|||
|
|
|||
|
namespace AxibugEmuOnline.Client
|
|||
|
{
|
|||
|
public class VideoProvider : MonoBehaviour
|
|||
|
{
|
|||
|
#region UI_REF
|
|||
|
public NesEmulator NesEmu;
|
|||
|
public Canvas DrawCanvas;
|
|||
|
public RawImage Image;
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#region GPU_TURBO
|
|||
|
//ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
private int TexBufferSize_gpu;
|
|||
|
//ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
private IntPtr wrapTexBufferPointer_gpu;
|
|||
|
//Unity 2D<32><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>UI<55>ϻ<EFBFBD><CFBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
private Texture2D wrapTex_gpu;
|
|||
|
//nes<65><73>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ת<EFBFBD><D7AA>Ϊunity<74><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
private Texture2D pPal_gpu;
|
|||
|
private Material GPUTurboMat_gpu;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region CPU
|
|||
|
//ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
private int TexBufferSize_cpu;
|
|||
|
//ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
private GCHandle wrapTexBufferGH;
|
|||
|
private IntPtr wrapTexBufferPointer_cpu;
|
|||
|
//Unity 2D<32><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>UI<55>ϻ<EFBFBD><CFBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
private Texture2D wrapTex_cpu;
|
|||
|
#endregion
|
|||
|
|
|||
|
public bool GPUTurbo = true;
|
|||
|
|
|||
|
private void Awake()
|
|||
|
{
|
|||
|
DrawCanvas.worldCamera = Camera.main;
|
|||
|
GPUTurboMat_gpu = Image.material;
|
|||
|
}
|
|||
|
|
|||
|
private void OnDestroy()
|
|||
|
{
|
|||
|
if (wrapTexBufferGH.IsAllocated)
|
|||
|
wrapTexBufferGH.Free();
|
|||
|
}
|
|||
|
|
|||
|
public unsafe void SetDrawData(uint* screenData)
|
|||
|
{
|
|||
|
PrepareUI(screenData);
|
|||
|
if (GPUTurbo) PrepareForGPU(screenData);//<2F>ж<EFBFBD>ʹ<EFBFBD><CAB9>GPU<50><55><EFBFBD><EFBFBD>CPU
|
|||
|
else PrepareForCPU(screenData);//ʹ<><CAB9>CPU
|
|||
|
|
|||
|
if (GPUTurbo)
|
|||
|
{
|
|||
|
wrapTex_gpu.LoadRawTextureData(wrapTexBufferPointer_gpu, TexBufferSize_gpu);
|
|||
|
wrapTex_gpu.Apply();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
wrapTex_cpu.LoadRawTextureData(wrapTexBufferPointer_cpu, TexBufferSize_cpu);
|
|||
|
wrapTex_cpu.Apply();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void PrepareUI(uint* screenData)
|
|||
|
{
|
|||
|
if (GPUTurbo)
|
|||
|
{
|
|||
|
if (Image.material != GPUTurboMat_gpu) Image.material = GPUTurboMat_gpu;
|
|||
|
|
|||
|
if (wrapTex_gpu == null)
|
|||
|
{
|
|||
|
wrapTex_gpu = new Texture2D(PPU.SCREEN_WIDTH, PPU.SCREEN_HEIGHT, TextureFormat.RGBA32, false);
|
|||
|
wrapTex_gpu.filterMode = FilterMode.Point;
|
|||
|
wrapTexBufferPointer_gpu = (IntPtr)screenData;
|
|||
|
|
|||
|
TexBufferSize_gpu = wrapTex_gpu.width * wrapTex_gpu.height * 4;
|
|||
|
}
|
|||
|
|
|||
|
if (Image.texture != wrapTex_gpu) Image.texture = wrapTex_gpu;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Image.material == GPUTurboMat_gpu) Image.material = null;
|
|||
|
|
|||
|
if (wrapTex_cpu == null)
|
|||
|
{
|
|||
|
wrapTex_cpu = new Texture2D(PPU.SCREEN_WIDTH - 16, PPU.SCREEN_HEIGHT, TextureFormat.RGBA32, false);
|
|||
|
wrapTex_cpu.filterMode = FilterMode.Point;
|
|||
|
|
|||
|
uint[] cpuTexBuffer = new uint[wrapTex_cpu.width * wrapTex_cpu.height];
|
|||
|
|
|||
|
wrapTexBufferGH = GCHandle.Alloc(cpuTexBuffer, GCHandleType.Pinned);
|
|||
|
wrapTexBufferPointer_cpu = wrapTexBufferGH.AddrOfPinnedObject();
|
|||
|
TexBufferSize_cpu = cpuTexBuffer.Length * 4;
|
|||
|
}
|
|||
|
if (Image.texture != wrapTex_cpu) Image.texture = wrapTex_cpu;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void PrepareForGPU(uint* screenData)
|
|||
|
{
|
|||
|
if (pPal_gpu == null)
|
|||
|
{
|
|||
|
var palRaw = PaletteDefine.m_cnPalette[0];
|
|||
|
|
|||
|
pPal_gpu = new Texture2D(palRaw.Length, 1, TextureFormat.RGBA32, false);
|
|||
|
pPal_gpu.filterMode = FilterMode.Point;
|
|||
|
|
|||
|
for (int i = 0; i < palRaw.Length; i++)
|
|||
|
{
|
|||
|
uint colorRaw = palRaw[i];
|
|||
|
var argbColor = BitConverter.GetBytes(colorRaw);
|
|||
|
Color temp = Color.white;
|
|||
|
temp.r = argbColor[2] / 255f;
|
|||
|
temp.g = argbColor[1] / 255f;
|
|||
|
temp.b = argbColor[0] / 255f;
|
|||
|
temp.a = 1;
|
|||
|
pPal_gpu.SetPixel(i, 0, temp);
|
|||
|
}
|
|||
|
pPal_gpu.Apply();
|
|||
|
GPUTurboMat_gpu.SetTexture("_PalTex", pPal_gpu);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void PrepareForCPU(uint* screenData)
|
|||
|
{
|
|||
|
int pScn = 0;
|
|||
|
int width;
|
|||
|
|
|||
|
var Dst = (uint*)wrapTexBufferPointer_cpu;
|
|||
|
var pDst = 0;
|
|||
|
var palRaw = PaletteDefine.m_cnPalette[0];
|
|||
|
|
|||
|
for (int line = 0; line < PPU.SCREEN_HEIGHT; line++)
|
|||
|
{
|
|||
|
//PS<50><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CPU<50><55><EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>16<31>IJ<EFBFBD><C4B2><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD>
|
|||
|
width = PPU.SCREEN_WIDTH - 16;
|
|||
|
|
|||
|
while (width > 0)
|
|||
|
{
|
|||
|
var edx = screenData[pScn + 8];
|
|||
|
|
|||
|
uint index = edx & 0xFF;
|
|||
|
//<2F><><EFBFBD>±<EFBFBD><C2B1><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ұ<EFBFBD><D2B1><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>ɫ
|
|||
|
var colorData = palRaw[index];
|
|||
|
//dst<73><74><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>Ϊabgr,<2C><>colorData<74><61><EFBFBD><EFBFBD>Ϊargb
|
|||
|
uint r = (colorData & 0x00FF0000) >> 16; // <20><>ȡRedͨ<64><CDA8>
|
|||
|
uint g = (colorData & 0x0000FF00) >> 8; // <20><>ȡGreenͨ<6E><CDA8>
|
|||
|
uint b = (colorData & 0x000000FF); // <20><>ȡBlueͨ<65><CDA8>
|
|||
|
|
|||
|
//<2F><>rgb<67><62><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>unity <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rgb <20><><EFBFBD><EFBFBD>System.Drawing.Color <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
uint abgr = 0xFF000000 | (b << 16) | (g << 8) | (r << 0);
|
|||
|
|
|||
|
//<2F>Ž<EFBFBD><C5BD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
|||
|
Dst[pDst] = abgr;
|
|||
|
|
|||
|
pScn += 1;
|
|||
|
pDst += 1;
|
|||
|
width -= 1;
|
|||
|
}
|
|||
|
|
|||
|
pScn += 16;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|