diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs
index 1dee7cf..0db022f 100644
--- a/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiReplay/NetReplay.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using UnityEngine;
namespace AxiReplay
{
@@ -113,7 +114,7 @@ namespace AxiReplay
if (frameGap > 10000) return 0;
int skip = 0;
-
+
if (frameGap <= 2) skip = 0;
if (frameGap > 2 && frameGap < 6) skip = 1 + 1;
else if (frameGap > 7 && frameGap < 12) skip = 2 + 1;
diff --git a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/XMBTopGroup.prefab b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/XMBTopGroup.prefab
index 8cdad0a..9baf683 100644
--- a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/XMBTopGroup.prefab
+++ b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/XMBTopGroup.prefab
@@ -265,6 +265,7 @@ RectTransform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
+ - {fileID: 4541943946029862829}
- {fileID: 2005113594707322973}
- {fileID: 4195056312044822544}
- {fileID: 1746243318642131728}
@@ -320,6 +321,7 @@ MonoBehaviour:
imgPower2: {fileID: 7232861150095392420}
imgPower3: {fileID: 6694955234077232327}
DelayValue: {fileID: 6486398873987280650}
+ FPS: {fileID: 2545793518460288919}
--- !u!1 &5629957813601835122
GameObject:
m_ObjectHideFlags: 0
@@ -352,7 +354,7 @@ RectTransform:
m_Children:
- {fileID: 1735688216191931001}
m_Father: {fileID: 5353336693430589123}
- m_RootOrder: 2
+ m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -417,6 +419,85 @@ MonoBehaviour:
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
+--- !u!1 &5634255875545658264
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 4541943946029862829}
+ - component: {fileID: 3282993275160308839}
+ - component: {fileID: 2545793518460288919}
+ m_Layer: 5
+ m_Name: FPS
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &4541943946029862829
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5634255875545658264}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 5353336693430589123}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 0, y: 0}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 53}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3282993275160308839
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5634255875545658264}
+ m_CullTransparentMesh: 1
+--- !u!114 &2545793518460288919
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5634255875545658264}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_FontData:
+ m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+ m_FontSize: 30
+ m_FontStyle: 0
+ m_BestFit: 0
+ m_MinSize: 3
+ m_MaxSize: 55
+ m_Alignment: 5
+ m_AlignByGeometry: 0
+ m_RichText: 1
+ m_HorizontalOverflow: 0
+ m_VerticalOverflow: 0
+ m_LineSpacing: 1
+ m_Text: FPS:60
--- !u!1 &6140890295709974557
GameObject:
m_ObjectHideFlags: 0
@@ -523,7 +604,7 @@ RectTransform:
- {fileID: 1777012203952456443}
- {fileID: 7158194035478552859}
m_Father: {fileID: 5353336693430589123}
- m_RootOrder: 0
+ m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
@@ -586,7 +667,7 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 5353336693430589123}
- m_RootOrder: 1
+ m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
diff --git a/AxibugEmuOnline.Client/Assets/Script/IEmuCore.cs b/AxibugEmuOnline.Client/Assets/Script/IEmuCore.cs
index 1a8d20e..68a5df8 100644
--- a/AxibugEmuOnline.Client/Assets/Script/IEmuCore.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/IEmuCore.cs
@@ -15,6 +15,7 @@ namespace AxibugEmuOnline.Client
void SetupScheme();
void StartGame(RomFile romFile);
void DoReset();
+ uint Frame { get; }
}
public static class IEnumCoreTool
diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs
index 3a7df7d..b16b04f 100644
--- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs
@@ -13,6 +13,11 @@ namespace AxibugEmuOnline.Client.Manager
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
///
private IEmuCore m_emuCore;
+ ///
+ /// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
+ /// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
+ ///
+ public IEmuCore Core => m_emuCore;
public AppEmu()
{
diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppSettings/BgColorSettings.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppSettings/BgColorSettings.cs
index 8d0ac3f..4055080 100644
--- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppSettings/BgColorSettings.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppSettings/BgColorSettings.cs
@@ -5,6 +5,7 @@ using UnityEngine;
namespace AxibugEmuOnline.Client
{
+ /// 颜色设置
public class BgColorSettings
{
public delegate void OnColorChangedHandle(XMBColor color);
diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs
index 1d325f0..bd6fc1d 100644
--- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs
@@ -112,21 +112,17 @@ namespace AxibugEmuOnline.Client
}
m_sampledState = FromNet(replayData);
- var localState = NesControllerMapper.Get().CreateState();
- var rawData = ToNet(localState);
- if (LastTestInput != rawData)
- {
- LastTestInput = rawData;
- App.log.Debug($"{DateTime.Now.ToString("hh:mm:ss.fff")} Input F:{App.roomMgr.netReplay.mCurrClientFrameIdx} | I:{rawData}");
- }
- App.roomMgr.SendRoomSingelPlayerInput(frameIndex, rawData);
}
- else
+ else m_sampledState = default;
+
+ var localState = NesControllerMapper.Get().CreateState();
+ var rawData = ToNet(localState);
+ if (LastTestInput != rawData)
{
- //App.log.Error($"Server Lag remoteFrame->{App.roomMgr.netReplay.mRemoteFrameIdx} diff->{frameDiff} " +
- // $"frame=>{replayData.FrameStartID} InPut=>{replayData.InPut}");
- m_sampledState = default;
+ LastTestInput = rawData;
+ App.log.Debug($"{DateTime.Now.ToString("hh:mm:ss.fff")} Input F:{App.roomMgr.netReplay.mCurrClientFrameIdx} | I:{rawData}");
}
+ App.roomMgr.SendRoomSingelPlayerInput(frameIndex, rawData);
}
else
{
diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs
index 8991bb1..5ff5c18 100644
--- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs
@@ -76,8 +76,7 @@ namespace AxibugEmuOnline.Client
FixEmulatorFrame();
var screenBuffer = NesCore.ppu.GetScreenPtr();
- var lineColorMode = NesCore.ppu.GetLineColorMode();
- VideoProvider.SetDrawData(screenBuffer, lineColorMode, 277, 240);
+ VideoProvider.SetDrawData(screenBuffer);
}
}
@@ -197,5 +196,7 @@ namespace AxibugEmuOnline.Client
UnityEditor.EditorUtility.SetDirty(db);
UnityEditor.AssetDatabase.SaveAssets();
}
+
+ public uint Frame => NesCore.FrameCount;
}
}
diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/VideoProvider.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/VideoProvider.cs
index 6d4196f..72de272 100644
--- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/VideoProvider.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/VideoProvider.cs
@@ -1,5 +1,7 @@
+using AxibugEmuOnline.Client.Common;
using System;
using System.Runtime.InteropServices;
+using System.Text;
using UnityEngine;
using UnityEngine.UI;
@@ -23,11 +25,10 @@ namespace AxibugEmuOnline.Client
DrawCanvas.worldCamera = Camera.main;
}
- public unsafe void SetDrawData(uint* screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
+ public unsafe void SetDrawData(uint* screenData)
{
if (wrapTex == null)
{
- //wrapTex = new Texture2D(272, 240, TextureFormat.BGRA32, false);
wrapTex = new Texture2D(272, 240, TextureFormat.RGBA32, false);
wrapTex.filterMode = FilterMode.Point;
@@ -36,7 +37,7 @@ namespace AxibugEmuOnline.Client
Image.texture = wrapTex;
Image.material.SetTexture("_MainTex", wrapTex);
- TexBufferSize = screenWidth * screenHeight * 4;
+ TexBufferSize = wrapTex.width * wrapTex.height * 4;
var palRaw = PaletteDefine.m_cnPalette[0];
pPal = new Texture2D(palRaw.Length, 1, TextureFormat.RGBA32, false);
diff --git a/AxibugEmuOnline.Client/Assets/Script/UI/XMBTopGroupUI/XMBTopGroup.cs b/AxibugEmuOnline.Client/Assets/Script/UI/XMBTopGroupUI/XMBTopGroup.cs
index 2076b6d..811a23d 100644
--- a/AxibugEmuOnline.Client/Assets/Script/UI/XMBTopGroupUI/XMBTopGroup.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/UI/XMBTopGroupUI/XMBTopGroup.cs
@@ -12,6 +12,7 @@ public class XMBTopGroup : MonoBehaviour
public Image imgPower2;
public Image imgPower3;
public Text DelayValue;
+ public Text FPS;
void OnEnable()
{
@@ -29,6 +30,25 @@ public class XMBTopGroup : MonoBehaviour
RefreshTime();
RefreshPower();
RefreshDelay();
+ RefreshFps();
+ }
+
+ (uint lastFrame, float lastTime) m_lastFrameInfo;
+ private void RefreshFps()
+ {
+ if (App.emu.Core.IsNull())
+ FPS.gameObject.SetActiveEx(false);
+ else
+ {
+ FPS.gameObject.SetActiveEx(true);
+ var gap = App.emu.Core.Frame - m_lastFrameInfo.lastFrame;
+ var time = Time.realtimeSinceStartup - m_lastFrameInfo.lastTime;
+ var fps = gap / time;
+ FPS.text = $"FPS:{fps:.#}";
+
+ m_lastFrameInfo.lastFrame = App.emu.Core.Frame;
+ m_lastFrameInfo.lastTime = Time.realtimeSinceStartup;
+ }
}
private void RefreshDelay()
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/MemoryUtility.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/MemoryUtility.cs
index 1f9b1a1..f0bf58a 100644
--- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/MemoryUtility.cs
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/MemoryUtility.cs
@@ -41,6 +41,34 @@ namespace VirtualNes.Core
}
}
+ public unsafe static void memset(byte* ptr, int offset, byte value, int length)
+ {
+ var offsetptr = ptr + offset;
+ for (int i = 0; i < length; i++)
+ {
+ offsetptr[i] = value;
+ }
+ }
+
+ public unsafe static void memset(byte* ptr, byte value, int length)
+ {
+ memset(ptr, 0, value, length);
+ }
+
+ public unsafe static void memset(uint* ptr, int offset, uint value, int length)
+ {
+ var offsetptr = ptr + offset;
+ for (int i = 0; i < length; i++)
+ {
+ offsetptr[i] = value;
+ }
+ }
+
+ public unsafe static void memset(uint* ptr, uint value, int length)
+ {
+ memset(ptr, 0, value, length);
+ }
+
public static void memcpy(Array dst, Array src, int length)
{
Array.Copy(src, dst, length);
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs
index 276aa57..7303287 100644
--- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs
@@ -221,10 +221,7 @@ namespace VirtualNes.Core
Debuger.Log("Allocating PPU...");
ppu = new PPU(this);
- var screenBuffer = new uint[PPU.SCREEN_WIDTH * PPU.SCREEN_HEIGHT];
- var colormode = new byte[PPU.SCREEN_HEIGHT];
-
- ppu.SetScreenPtr(screenBuffer, colormode);
+ ppu.InitBuffer();
Debuger.Log("Allocating APU...");
apu = new APU(this);
@@ -766,71 +763,9 @@ namespace VirtualNes.Core
}
}
- if (bDraw)
- {
- DrawPad();
- }
-
FrameCount++;
}
- private void DrawPad()
- {
- if (m_bMoviePlay)
- {
- int offset_h = 12;
- int offset_v = Supporter.Config.graphics.bAllLine ? (240 - 18) : (240 - 22);
-
- if (Supporter.Config.movie.bPadDisplay)
- {
- uint dwData = pad.GetSyncData();
- for (int i = 0; i < 4; i++)
- {
- byte Data = (byte)(dwData >> (i * 8));
- if ((m_MovieControl & (1 << i)) != 0)
- {
- DrawBitmap(offset_h, offset_v, m_PadImg);
-
- // KEY
- if ((Data & (1 << 4)) != 0) DrawBitmap(offset_h + 3, offset_v + 1, m_KeyImg0); // U
- if ((Data & (1 << 5)) != 0) DrawBitmap(offset_h + 3, offset_v + 5, m_KeyImg0); // D
- if ((Data & (1 << 6)) != 0) DrawBitmap(offset_h + 1, offset_v + 3, m_KeyImg0); // L
- if ((Data & (1 << 7)) != 0) DrawBitmap(offset_h + 5, offset_v + 3, m_KeyImg0); // R
-
- // START,SELECT
- if ((Data & (1 << 2)) != 0) DrawBitmap(offset_h + 9, offset_v + 5, m_KeyImg1); // SELECT
- if ((Data & (1 << 3)) != 0) DrawBitmap(offset_h + 13, offset_v + 5, m_KeyImg1); // START
-
- // A,B
- if ((Data & (1 << 0)) != 0) DrawBitmap(offset_h + 23, offset_v + 3, m_KeyImg2); // A
- if ((Data & (1 << 1)) != 0) DrawBitmap(offset_h + 18, offset_v + 3, m_KeyImg2); // B
-
- offset_h += 30;
- }
- }
- }
-
- if (Supporter.Config.movie.bTimeDisplay)
- {
- // Time display
- int t = m_MovieStep;
- int h = t / 216000;
- t -= h * 216000;
- int m = t / 3600;
- t -= m * 3600;
- int s = t / 60;
- t -= s * 60;
-
- string szTemp = $"{h:00}:{m:00}:{s:00}.{t * 100 / 60:00}";
- DrawString(256 - 80 + 0, offset_v - 1, szTemp, 0x1F);
- DrawString(256 - 80 + 0, offset_v + 1, szTemp, 0x1F);
- DrawString(256 - 80 - 1, offset_v + 0, szTemp, 0x1F);
- DrawString(256 - 80 + 1, offset_v + 0, szTemp, 0x1F);
- DrawString(256 - 80, offset_v, szTemp, 0x30);
- }
- }
- }
-
internal void DrawString(int x, int y, string str, byte col)
{
foreach (var @char in str)
@@ -866,33 +801,6 @@ namespace VirtualNes.Core
}
}
- private unsafe void DrawBitmap(int x, int y, byte[] bitMap)
- {
- int i, j;
- int h, v;
- var Scn = ppu.GetScreenPtr();
- int pScn = 8 + (256 + 16) * y + x;
- int pPtr;
-
- int lpBitmap = 0;
- h = bitMap[lpBitmap++];
- v = bitMap[lpBitmap++];
-
- for (j = 0; j < v; j++)
- {
- pPtr = pScn;
- for (i = 0; i < h; i++)
- {
- if (bitMap[lpBitmap] != 0xFF)
- {
- Scn[pPtr] = bitMap[lpBitmap];
- }
- lpBitmap++;
- pPtr++;
- }
- pScn += 256 + 16;
- }
- }
int CPU_CALL_COUNT = 0;
internal void EmulationCPU(int basecycles)
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs
index 3c7ca00..c26f10c 100644
--- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs
@@ -386,7 +386,7 @@ namespace VirtualNes.Core
loopy_shift = 0;
if (lpScreen != null)
- Unsafe.InitBlockUnaligned(lpScreen, 0, SCREEN_WIDTH * SCREEN_HEIGHT);
+ MemoryUtility.memset(lpScreen, 0, 0, SCREEN_WIDTH * SCREEN_HEIGHT);
if (lpColormode != null)
MemoryUtility.memset(lpColormode, 0, SCREEN_HEIGHT);
}
@@ -402,7 +402,7 @@ namespace VirtualNes.Core
if (lpScreen != null)
{
- Unsafe.InitBlockUnaligned(lpScreen, 0x3F, SCREEN_WIDTH);
+ MemoryUtility.memset(lpScreen, 0, 0x3f, SCREEN_WIDTH);
}
if (lpColormode != null)
{
@@ -457,8 +457,8 @@ namespace VirtualNes.Core
{
byte chr_h = 0, chr_l = 0, attr = 0;
- Unsafe.InitBlockUnaligned(BGwrite, 0, 34);
- Unsafe.InitBlockUnaligned(BGmono, 0, 34);
+ MemoryUtility.memset(BGwrite, 0, 34);
+ MemoryUtility.memset(BGmono, 0, 34);
// Linecolor mode
lpColormode[scanline] = (byte)(((MMU.PPUREG[1] & PPU_BGCOLOR_BIT) >> 5) | ((MMU.PPUREG[1] & PPU_COLORMODE_BIT) << 7));
@@ -466,7 +466,7 @@ namespace VirtualNes.Core
// Render BG
if ((MMU.PPUREG[1] & PPU_BGDISP_BIT) == 0)
{
- Unsafe.InitBlockUnaligned(lpScanline, MMU.BGPAL[0], SCREEN_WIDTH);
+ MemoryUtility.memset(lpScanline, MMU.BGPAL[0], SCREEN_WIDTH);
if (nes.GetRenderMethod() == EnumRenderMethod.TILE_RENDER)
{
nes.EmulationCPU(NES.FETCH_CYCLES * 4 * 32);
@@ -869,7 +869,7 @@ namespace VirtualNes.Core
{
byte* pBGw = BGwrite;
byte* pSPw = SPwrite;
- Unsafe.InitBlockUnaligned(pSPw, 0, 34);
+ MemoryUtility.memset(pSPw, 0, 34);
spmax = 0;
Sprite sp = new Sprite(MMU.SPRAM, 0);
@@ -1092,8 +1092,11 @@ namespace VirtualNes.Core
return lpColormode;
}
- internal void SetScreenPtr(uint[] screenBuffer, byte[] colormode)
+ internal void InitBuffer()
{
+ var screenBuffer = new uint[SCREEN_WIDTH * SCREEN_HEIGHT];
+ var colormode = new byte[SCREEN_HEIGHT];
+
lpScreenGCH = GCHandle.Alloc(screenBuffer, GCHandleType.Pinned);
lpScreen = (uint*)lpScreenGCH.AddrOfPinnedObject();
lpColormode = colormode;
@@ -1180,11 +1183,16 @@ namespace VirtualNes.Core
}
}
+ [StructLayout(LayoutKind.Explicit, Size = 16)]
public struct UInt128
{
+ [FieldOffset(0)]
public UInt32 a;
+ [FieldOffset(4)]
public UInt32 b;
+ [FieldOffset(8)]
public UInt32 c;
+ [FieldOffset(12)]
public UInt32 d;
}
}