diff --git a/.gitignore b/.gitignore index 17915f1..44e618d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ /AxibugEmuOnline.Client/ProjectSettings/Packages/ /AxibugEmuOnline.Web/config.cfg /AxibugEmuOnline.Client/ProjectSettings/ProjectVersion.txt +/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset +/AxibugEmuOnline.Client/Logs diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs index 133b7aa..f39d630 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs @@ -5169,6 +5169,7 @@ namespace MyNes.Core { Tracer.WriteLine("Running in a thread ... using custom frame limiter."); FrameLimiterEnabled = true; + currentFrame = 0; mainThread = new Thread(EmuClock); mainThread.Start(); } @@ -5263,9 +5264,6 @@ namespace MyNes.Core if (mainThread != null) { Tracer.WriteLine("Aborting thread .."); - while (mainThread.IsAlive) - { - } mainThread.Abort(); mainThread = null; } @@ -5274,43 +5272,29 @@ namespace MyNes.Core NesEmu.EmuShutdown?.Invoke(null, new EventArgs()); } - internal static void EMUClockFrame() - { - emu_frame_done = false; - while (!emu_frame_done && ON) - { - if (!PAUSED) - { - CPUClock(); - } - else - { - Thread.Sleep(100); - } - } - } - - public static void ExecuteOneFrame() - { - while (!ppu_frame_finished) - { - CPUClock(); - } - - FrameFinished(); - } - + private static Stopwatch sw = new Stopwatch(); + private static double fixTime; + public static int currentFrame; private static void EmuClock() { while (ON) { if (!PAUSED) { - CPUClock(); - if (ppu_frame_finished) + var waitTime = GetTime() + fps_time_period + fixTime; + + while (!ppu_frame_finished) + CPUClock(); + + FrameFinished(); + + fixTime = waitTime - GetTime(); + while (fixTime > 0) { - FrameFinished(); - } + fixTime = waitTime - GetTime(); + }; + + continue; } render_audio_get_is_playing(out render_audio_is_playing); @@ -5408,24 +5392,6 @@ namespace MyNes.Core audio_timer = 0.0; } fps_time_token = GetTime() - fps_time_start; - if (FrameLimiterEnabled) - { - if (fps_time_token > 0.0) - { - fps_time_dead = fps_time_period - fps_time_token; - if (fps_time_dead > 0.0) - { - Thread.Sleep((int)Math.Floor(fps_time_dead * 1000.0)); - fps_time_dead = GetTime() - fps_time_start; - while (fps_time_period - fps_time_dead > 0.0) - { - fps_time_dead = GetTime() - fps_time_start; - } - } - } - fps_time_last = GetTime(); - fps_time_frame_time = fps_time_last - fps_time_start; - } fps_time_start = GetTime(); } @@ -5445,6 +5411,11 @@ namespace MyNes.Core fps_time_period = period; } + public static void RevertFramePeriod() + { + fps_time_period = 1 / emu_time_target_fps; + } + public static void ApplyRegionSetting() { switch ((RegionSetting)MyNesMain.EmuSettings.RegionSetting) diff --git a/AxibugEmuOnline.Client/Assets/Prefabs.meta b/AxibugEmuOnline.Client/Assets/Prefabs.meta new file mode 100644 index 0000000..b05ee29 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Prefabs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8d7ded91aab4c0b42abba5042aaceb39 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab b/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab new file mode 100644 index 0000000..a8a472c --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab @@ -0,0 +1,509 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8662582774585465456 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582774585465455} + - component: {fileID: 8662582774585465453} + - component: {fileID: 8662582774585465454} + m_Layer: 5 + m_Name: canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &8662582774585465455 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774585465456} + 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: 8662582775350046794} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8662582774585465453 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774585465456} + m_CullTransparentMesh: 1 +--- !u!114 &8662582774585465454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774585465456} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, 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_Texture: {fileID: 8400000, guid: 5d4a385f133f9074583d64ab2172a03b, type: 2} + m_UVRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 +--- !u!1 &8662582774971523582 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582774971523581} + - component: {fileID: 8662582774971523580} + - component: {fileID: 8662582774971523579} + m_Layer: 5 + m_Name: Audio + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8662582774971523581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774971523582} + 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: 8662582775439058149} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!82 &8662582774971523580 +AudioSource: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774971523582} + m_Enabled: 1 + serializedVersion: 4 + OutputAudioMixerGroup: {fileID: 0} + m_audioClip: {fileID: 0} + m_PlayOnAwake: 0 + m_Volume: 1 + m_Pitch: 1 + Loop: 0 + Mute: 0 + Spatialize: 0 + SpatializePostEffects: 0 + Priority: 128 + DopplerLevel: 1 + MinDistance: 1 + MaxDistance: 500 + Pan2D: 0 + rolloffMode: 0 + BypassEffects: 0 + BypassListenerEffects: 0 + BypassReverbZones: 0 + rolloffCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + panLevelCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + spreadCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + reverbZoneMixCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 +--- !u!114 &8662582774971523579 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582774971523582} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 765129d4fad76714191795975893ea9c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_coreProxy: {fileID: 8662582775964487075} + m_as: {fileID: 8662582774971523580} +--- !u!1 &8662582775350046795 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582775350046794} + - component: {fileID: 8662582775350046791} + - component: {fileID: 8662582775350046790} + m_Layer: 5 + m_Name: video + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8662582775350046794 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775350046795} + 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: + - {fileID: 8662582774585465455} + - {fileID: 8662582775359084755} + m_Father: {fileID: 8662582775439058149} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8662582775350046791 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775350046795} + m_CullTransparentMesh: 1 +--- !u!114 &8662582775350046790 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775350046795} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f2632911774df3c488ec24b39651c4de, type: 3} + m_Name: + m_EditorClassIdentifier: + m_coreProxy: {fileID: 8662582775964487075} + m_drawCanvas: {fileID: 8662582774585465454} + m_fpsText: {fileID: 8662582775359084754} +--- !u!1 &8662582775359084756 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582775359084755} + - component: {fileID: 8662582775359084753} + - component: {fileID: 8662582775359084754} + m_Layer: 5 + m_Name: fps + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8662582775359084755 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775359084756} + 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: 8662582775350046794} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 1, y: 0} +--- !u!222 &8662582775359084753 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775359084756} + m_CullTransparentMesh: 1 +--- !u!114 &8662582775359084754 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775359084756} + 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: 0.19607843, g: 0.19607843, b: 0.19607843, 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: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 8 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 1 + m_VerticalOverflow: 1 + m_LineSpacing: 1 + m_Text: +--- !u!1 &8662582775439058150 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582775439058149} + - component: {fileID: 8662582775439058146} + - component: {fileID: 8662582775439058147} + - component: {fileID: 8662582775439058148} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8662582775439058149 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775439058150} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 8662582775350046794} + - {fileID: 8662582774971523581} + m_Father: {fileID: 8662582775964487076} + 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: 0} + m_Pivot: {x: 0, y: 0} +--- !u!223 &8662582775439058146 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775439058150} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &8662582775439058147 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775439058150} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!114 &8662582775439058148 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775439058150} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!1 &8662582775964487077 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8662582775964487076} + - component: {fileID: 8662582775964487075} + m_Layer: 0 + m_Name: NesCoreProxy + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8662582775964487076 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775964487077} + 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: + - {fileID: 8662582775439058149} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8662582775964487075 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8662582775964487077} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ac8cd27a180bf3e489b2ca27c821bffe, type: 3} + m_Name: + m_EditorClassIdentifier: + VideoCom: {fileID: 8662582775350046790} + AudioCom: {fileID: 8662582774971523579} diff --git a/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab.meta b/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab.meta new file mode 100644 index 0000000..70b5aae --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Prefabs/NesCoreProxy.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d75df7d1f5a2c824ab5013cbd79da7a4 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes b/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes new file mode 100644 index 0000000..46a85a0 Binary files /dev/null and b/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes differ diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta new file mode 100644 index 0000000..db26e21 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4933f61382c34574db545f3d9e72b51d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity index 451cb5d..a568da5 100644 --- a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity +++ b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity @@ -123,52 +123,6 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} ---- !u!1 &258485946 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 258485947} - - component: {fileID: 258485948} - m_Layer: 0 - m_Name: NesCoreProxy - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &258485947 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 258485946} - 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: - - {fileID: 786008058} - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &258485948 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 258485946} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ac8cd27a180bf3e489b2ca27c821bffe, type: 3} - m_Name: - m_EditorClassIdentifier: - VideoCom: {fileID: 730321753} - AudioCom: {fileID: 1379369700} --- !u!1 &708549044 GameObject: m_ObjectHideFlags: 0 @@ -262,247 +216,6 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &723385291 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 723385292} - - component: {fileID: 723385294} - - component: {fileID: 723385293} - m_Layer: 5 - m_Name: fps - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &723385292 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723385291} - 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: 730321749} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 1, y: 0} - m_AnchorMax: {x: 1, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 1, y: 0} ---- !u!114 &723385293 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723385291} - 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: 0.19607843, g: 0.19607843, b: 0.19607843, 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: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 8 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 1 - m_VerticalOverflow: 1 - m_LineSpacing: 1 - m_Text: ---- !u!222 &723385294 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 723385291} - m_CullTransparentMesh: 1 ---- !u!1 &730321748 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 730321749} - - component: {fileID: 730321752} - - component: {fileID: 730321753} - m_Layer: 5 - m_Name: video - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &730321749 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 730321748} - 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: - - {fileID: 2100984176} - - {fileID: 723385292} - m_Father: {fileID: 786008058} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &730321752 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 730321748} - m_CullTransparentMesh: 1 ---- !u!114 &730321753 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 730321748} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f2632911774df3c488ec24b39651c4de, type: 3} - m_Name: - m_EditorClassIdentifier: - m_drawCanvas: {fileID: 2100984177} - m_fpsText: {fileID: 723385293} ---- !u!1 &786008057 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 786008058} - - component: {fileID: 786008061} - - component: {fileID: 786008060} - - component: {fileID: 786008059} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &786008058 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 786008057} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 730321749} - - {fileID: 1379369698} - m_Father: {fileID: 258485947} - 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: 0} - m_Pivot: {x: 0, y: 0} ---- !u!114 &786008059 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 786008057} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &786008060 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 786008057} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 - m_PresetInfoIsWorld: 0 ---- !u!223 &786008061 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 786008057} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 --- !u!1 &1232273651 GameObject: m_ObjectHideFlags: 0 @@ -652,221 +365,60 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1379369697 -GameObject: +--- !u!1001 &8662582775744815903 +PrefabInstance: m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1379369698} - - component: {fileID: 1379369699} - - component: {fileID: 1379369700} - m_Layer: 5 - m_Name: Audio - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1379369698 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1379369697} - 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: 786008058} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!82 &1379369699 -AudioSource: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1379369697} - m_Enabled: 1 - serializedVersion: 4 - OutputAudioMixerGroup: {fileID: 0} - m_audioClip: {fileID: 0} - m_PlayOnAwake: 0 - m_Volume: 1 - m_Pitch: 1 - Loop: 0 - Mute: 0 - Spatialize: 0 - SpatializePostEffects: 0 - Priority: 128 - DopplerLevel: 1 - MinDistance: 1 - MaxDistance: 500 - Pan2D: 0 - rolloffMode: 0 - BypassEffects: 0 - BypassListenerEffects: 0 - BypassReverbZones: 0 - rolloffCustomCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_RootOrder + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalRotation.w value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 1 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalRotation.x value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - panLevelCustomCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalRotation.y value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - spreadCustomCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalRotation.z value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - reverbZoneMixCustomCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 ---- !u!114 &1379369700 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1379369697} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 765129d4fad76714191795975893ea9c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_as: {fileID: 1379369699} ---- !u!1 &2100984175 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2100984176} - - component: {fileID: 2100984178} - - component: {fileID: 2100984177} - m_Layer: 5 - m_Name: canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &2100984176 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2100984175} - 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: 730321749} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &2100984177 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2100984175} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, 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_Texture: {fileID: 8400000, guid: 5d4a385f133f9074583d64ab2172a03b, type: 2} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &2100984178 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2100984175} - m_CullTransparentMesh: 1 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487076, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8662582775964487077, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} + propertyPath: m_Name + value: NesCoreProxy + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: d75df7d1f5a2c824ab5013cbd79da7a4, type: 3} diff --git a/AxibugEmuOnline.Client/Assets/Script/Emu/AudioProvider.cs b/AxibugEmuOnline.Client/Assets/Script/Emu/AudioProvider.cs index f163ecc..8580c1c 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Emu/AudioProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Emu/AudioProvider.cs @@ -18,12 +18,14 @@ namespace AxibugEmuOnline.Client public bool AllowFrequencyChange => true; private bool m_isPlaying; - + private bool m_started; + [SerializeField] + private NesCoreProxy m_coreProxy; [SerializeField] private AudioSource m_as; private Stopwatch sw = Stopwatch.StartNew(); - private Queue _buffer = new Queue(2048); + private RingBuffer _buffer = new RingBuffer(4096); public double FPS { get; private set; } @@ -41,11 +43,29 @@ namespace AxibugEmuOnline.Client float lastData = 0; void OnAudioFilterRead(float[] data, int channels) { + if (!m_started) return; + int step = channels; + var bufferCount = _buffer.Available(); + if (bufferCount < 4096) + { + NesEmu.SetFramePeriod(ref fps_nes_missle); + } + else if (bufferCount > 8124) + { + NesEmu.SetFramePeriod(ref fps_pl_faster); + } + else + { + NesEmu.RevertFramePeriod(); + } for (int i = 0; i < data.Length; i += step) { - var rawFloat = _buffer.Count <= 0 ? lastData : _buffer.Dequeue() / 124f; + float rawFloat = lastData; + if (_buffer.TryRead(out short rawData)) + rawFloat = rawData / 124f; + data[i] = rawFloat; for (int fill = 1; fill < step; fill++) data[i + fill] = rawFloat; @@ -55,6 +75,9 @@ namespace AxibugEmuOnline.Client } private TimeSpan lastElapsed; + private double fps_nes_missle; + private double fps_pl_faster; + public void SubmitSamples(ref short[] buffer, ref int samples_a) { var current = sw.Elapsed; @@ -63,14 +86,9 @@ namespace AxibugEmuOnline.Client FPS = 1d / delta.TotalSeconds; - if (_buffer.Count > 2048) - { - _buffer.Clear(); - } - for (int i = 0; i < samples_a; i++) { - _buffer.Enqueue(buffer[i]); + _buffer.Write(buffer[i]); } } @@ -84,8 +102,6 @@ namespace AxibugEmuOnline.Client playing = m_isPlaying; } - - public void ShutDown() { } @@ -96,6 +112,23 @@ namespace AxibugEmuOnline.Client public void SignalToggle(bool started) { + if (started) + { + switch (NesEmu.Region) + { + case EmuRegion.NTSC: + fps_nes_missle = 1 / 60.5d; + fps_pl_faster = 1 / 59.5d; + break; + case EmuRegion.PALB: + case EmuRegion.DENDY: + fps_nes_missle = 0.0125; + fps_pl_faster = 0.02; + break; + } + + } + m_started = started; } public void SetVolume(int Vol) diff --git a/AxibugEmuOnline.Client/Assets/Script/Emu/UguiVideoProvider.cs b/AxibugEmuOnline.Client/Assets/Script/Emu/UguiVideoProvider.cs index 0523599..e158880 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Emu/UguiVideoProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Emu/UguiVideoProvider.cs @@ -11,10 +11,13 @@ namespace AxibugEmuOnline.Client { public class UguiVideoProvider : MonoBehaviour, IVideoProvider { + public string Name => "Unity UI Video"; public string ID => nameof(UguiVideoProvider).GetHashCode().ToString(); + [SerializeField] + private NesCoreProxy m_coreProxy; [SerializeField] private RawImage m_drawCanvas; [SerializeField] @@ -30,7 +33,7 @@ namespace AxibugEmuOnline.Client { m_rawBufferWarper = new Texture2D(256, 240); //m_drawCanvas.texture = RenderTexture.GetTemporary(256, 240, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.B8G8R8A8_SRGB); - } + } public void GetColor(uint value, ref Color res) { @@ -51,7 +54,7 @@ namespace AxibugEmuOnline.Client m_rawBufferWarper.Apply(); Graphics.Blit(m_rawBufferWarper, m_drawCanvas.texture as RenderTexture); - m_fpsText.text = $"Audio:{NesCoreProxy.Instance.AudioCom.FPS}"; + m_fpsText.text = $"fps:{m_coreProxy.AudioCom.FPS:00.00}"; } public void WriteErrorNotification(string message, bool instant) diff --git a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs index 75561b6..92750a7 100644 --- a/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs +++ b/AxibugEmuOnline.Client/Assets/Script/Manager/AppEmu.cs @@ -10,12 +10,8 @@ namespace AxibugEmuOnline.Client.Manager public void Init(IVideoProvider videoCom, IAudioProvider audioCom) { MyNesMain.Initialize(this, videoCom, audioCom); - NesEmu.LoadGame("kirby.nes", out var successed, true); - } - public void ExecuteFrameLogic() - { - //NesEmu.ExecuteOneFrame(); + NesEmu.LoadGame("kirby.nes", out var successed, true); } public void Dispose() diff --git a/AxibugEmuOnline.Client/Assets/Script/NesCoreProxy.cs b/AxibugEmuOnline.Client/Assets/Script/NesCoreProxy.cs index 8643eda..dd30dea 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesCoreProxy.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesCoreProxy.cs @@ -8,8 +8,6 @@ namespace AxibugEmuOnline.Client { public class NesCoreProxy : MonoBehaviour { - public static NesCoreProxy Instance { get; private set; } - public UguiVideoProvider VideoCom; public AudioProvider AudioCom; @@ -17,18 +15,11 @@ namespace AxibugEmuOnline.Client private void Start() { - Instance = this; m_appEnum.Init(VideoCom, AudioCom); } - private void Update() - { - m_appEnum.ExecuteFrameLogic(); - } - private void OnDestroy() { - Instance = null; m_appEnum.Dispose(); } } diff --git a/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs b/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs new file mode 100644 index 0000000..20f5613 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading; + +public class RingBuffer +{ + private readonly T[] buffer; + private readonly int capacity; + private int writePos; + private int readPos; + private int count; + + public RingBuffer(int capacity) + { + this.capacity = capacity; + this.buffer = new T[capacity]; + this.writePos = 0; + this.readPos = 0; + this.count = 0; + } + + public void Write(T item) + { + int localWritePos; + int localReadPos; + + do + { + localWritePos = Volatile.Read(ref writePos); + localReadPos = Volatile.Read(ref readPos); + + int nextWritePos = (localWritePos + 1) % capacity; + + if (nextWritePos == localReadPos) + { + // 缓冲区已满,覆盖最旧的未读数据 + Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos); + } + } + while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos); + + buffer[localWritePos] = item; + Interlocked.Increment(ref count); + } + + public bool TryRead(out T item) + { + item = default(T); + + int localReadPos; + int localWritePos; + + do + { + localReadPos = Volatile.Read(ref readPos); + localWritePos = Volatile.Read(ref writePos); + + if (localReadPos == localWritePos) + { + return false; // 缓冲区为空 + } + } + while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos); + + item = buffer[localReadPos]; + Interlocked.Decrement(ref count); + return true; + } + + public int Available() + { + return Volatile.Read(ref count); + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs.meta b/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs.meta new file mode 100644 index 0000000..902ec9a --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/RingBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6bd0f6c1647ed3f49a59e7f06406f49b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: