From 0021aa9cfa92fb734ebc8930cbb4112da79f4693 Mon Sep 17 00:00:00 2001 From: Alberto Fustinoni Date: Thu, 14 Sep 2017 22:53:55 +0900 Subject: [PATCH] Various fixes --- .../AudioGraphPlayer.cs | 5 +- .../Win2DCoreRunner.cs | 148 +++++++++++------- LibretroRT_Tools/CoreBase.cpp | 2 +- ParallelN64RT/ParallelN64CoreInternal.cpp | 5 + ParallelN64RT/ParallelN64CoreInternal.h | 2 + RetriX.UWP/Package.appxmanifest | 120 +++++++------- RetriX.UWP/RetriX.UWP.csproj | 6 +- RetriX.UWP/Services/EmulationService.cs | 2 +- 8 files changed, 166 insertions(+), 124 deletions(-) diff --git a/LibretroRT.FrontendComponents.AudioGraphPlayer/AudioGraphPlayer.cs b/LibretroRT.FrontendComponents.AudioGraphPlayer/AudioGraphPlayer.cs index 02bfa3a..2ce0f80 100644 --- a/LibretroRT.FrontendComponents.AudioGraphPlayer/AudioGraphPlayer.cs +++ b/LibretroRT.FrontendComponents.AudioGraphPlayer/AudioGraphPlayer.cs @@ -11,6 +11,7 @@ namespace LibretroRT.FrontendComponents.AudioGraphPlayer { public sealed class AudioGraphPlayer : IDisposable, IAudioPlayer { + private const uint MaxSamplesQueueSize = 44100 * 4; private const uint NumChannels = 2; private const float PlaybackDelaySeconds = 0.1f; //Have some buffer to avoid crackling private const float MaxAllowedDelaySeconds = 0.3f; //Limit maximum delay @@ -87,9 +88,9 @@ public void RenderAudioFrames([ReadOnlyArray] short[] samples) lock (SamplesBuffer) { - foreach (var i in samples) + for (var i = 0; i < Math.Min(samples.Length, Math.Max(0, MaxSamplesQueueSize - SamplesBuffer.Count)); i++) { - SamplesBuffer.Enqueue(i); + SamplesBuffer.Enqueue(samples[i]); } if (SamplesBuffer.Count >= MinNumSamplesForPlayback) diff --git a/LibretroRT.FrontendComponents.Win2DCoreRunner/Win2DCoreRunner.cs b/LibretroRT.FrontendComponents.Win2DCoreRunner/Win2DCoreRunner.cs index 206c0a4..a57ea22 100644 --- a/LibretroRT.FrontendComponents.Win2DCoreRunner/Win2DCoreRunner.cs +++ b/LibretroRT.FrontendComponents.Win2DCoreRunner/Win2DCoreRunner.cs @@ -16,6 +16,8 @@ public sealed class Win2DCoreRunner : ICoreRunner, IDisposable private readonly IAudioPlayer AudioPlayer; private readonly IInputManager InputManager; + private TaskCompletionSource RequestedCoreOperationTCS; + private CoreCoordinator Coordinator; public string GameID { get; private set; } @@ -61,64 +63,74 @@ public void Dispose() public IAsyncOperation LoadGameAsync(ICore core, string mainGameFilePath) { - return Task.Run(async () => + if (RequestedCoreOperationTCS != null) { - while (Coordinator == null) + return Task.FromResult(false).AsAsyncOperation(); + } + + Func state = () => + { + GameID = null; + CoreIsExecuting = false; + Coordinator.AudioPlayer?.Stop(); + + if (Coordinator.Core != core) { - //Ensure core doesn't try rendering before Win2D is ready. - //Some games load faster than the Win2D canvas is initialized - await Task.Delay(100); + Coordinator.Core?.UnloadGame(); + Coordinator.Core = core; } - lock (Coordinator) + if (core.LoadGame(mainGameFilePath) == false) { - GameID = null; - CoreIsExecuting = false; - Coordinator.AudioPlayer?.Stop(); - - if (Coordinator.Core != core) - { - Coordinator.Core?.UnloadGame(); - Coordinator.Core = core; - } + return false; + } - if (core.LoadGame(mainGameFilePath) == false) - { - return false; - } + RenderTargetManager.InitializeVideoParameters(core); + GameID = mainGameFilePath; + CoreIsExecuting = true; + return true; + }; - RenderTargetManager.InitializeVideoParameters(core); - GameID = mainGameFilePath; - CoreIsExecuting = true; - return true; - } - }).AsAsyncOperation(); + RequestedCoreOperationTCS = new TaskCompletionSource(state); + return RequestedCoreOperationTCS.Task.AsAsyncOperation(); } public IAsyncAction UnloadGameAsync() { - return Task.Run(() => + if (RequestedCoreOperationTCS != null) { - lock (Coordinator) - { - GameID = null; - CoreIsExecuting = false; - Coordinator.Core?.UnloadGame(); - Coordinator.AudioPlayer?.Stop(); - } - }).AsAsyncAction(); + return Task.FromResult(false).AsAsyncAction(); + } + + Func state = () => + { + GameID = null; + CoreIsExecuting = false; + Coordinator.Core?.UnloadGame(); + Coordinator.AudioPlayer?.Stop(); + return true; + }; + + RequestedCoreOperationTCS = new TaskCompletionSource(state); + return RequestedCoreOperationTCS.Task.AsAsyncAction(); } public IAsyncAction ResetGameAsync() { - return Task.Run(() => + if (RequestedCoreOperationTCS != null) { - lock (Coordinator) - { - Coordinator.AudioPlayer?.Stop(); - Coordinator.Core?.Reset(); - } - }).AsAsyncAction(); + return Task.FromResult(false).AsAsyncAction(); + } + + Func state = () => + { + Coordinator.AudioPlayer?.Stop(); + Coordinator.Core?.Reset(); + return true; + }; + + RequestedCoreOperationTCS = new TaskCompletionSource(state); + return RequestedCoreOperationTCS.Task.AsAsyncAction(); } public IAsyncAction PauseCoreExecutionAsync() @@ -146,32 +158,42 @@ public IAsyncAction ResumeCoreExecutionAsync() public IAsyncOperation SaveGameStateAsync([WriteOnlyArray] byte[] stateData) { - return Task.Run(() => + if (RequestedCoreOperationTCS != null) { - lock (Coordinator) - { - var core = Coordinator.Core; - if (core == null) - return false; + return Task.FromResult(false).AsAsyncOperation(); + } - return core.Serialize(stateData); - } - }).AsAsyncOperation(); + Func state = () => + { + var core = Coordinator.Core; + if (core == null) + return false; + + return core.Serialize(stateData); + }; + + RequestedCoreOperationTCS = new TaskCompletionSource(state); + return RequestedCoreOperationTCS.Task.AsAsyncOperation(); } public IAsyncOperation LoadGameStateAsync([ReadOnlyArray] byte[] stateData) { - return Task.Run(() => + if (RequestedCoreOperationTCS != null) { - lock (Coordinator) - { - var core = Coordinator.Core; - if (core == null) - return false; + return Task.FromResult(false).AsAsyncOperation(); + } - return core.Unserialize(stateData); - } - }).AsAsyncOperation(); + Func state = () => + { + var core = Coordinator.Core; + if (core == null) + return false; + + return core.Unserialize(stateData); + }; + + RequestedCoreOperationTCS = new TaskCompletionSource(state); + return RequestedCoreOperationTCS.Task.AsAsyncOperation(); } private void RenderPanelUnloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) @@ -207,6 +229,14 @@ private void RenderPanelUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpda { lock (Coordinator) { + if (RequestedCoreOperationTCS != null) + { + var requestedOperation = (Func)RequestedCoreOperationTCS.Task.AsyncState; + var result = requestedOperation.Invoke(); + RequestedCoreOperationTCS.SetResult(result); + RequestedCoreOperationTCS = null; + } + if (CoreIsExecuting && !Coordinator.AudioPlayerRequestsFrameDelay) { try diff --git a/LibretroRT_Tools/CoreBase.cpp b/LibretroRT_Tools/CoreBase.cpp index 6421e87..6ab0a8d 100644 --- a/LibretroRT_Tools/CoreBase.cpp +++ b/LibretroRT_Tools/CoreBase.cpp @@ -354,7 +354,7 @@ void CoreBase::RunFrame() } catch (...) { - //throw ref new Platform::FailureException(L"Core runtime error"); + throw ref new Platform::FailureException(L"Core runtime error"); } } diff --git a/ParallelN64RT/ParallelN64CoreInternal.cpp b/ParallelN64RT/ParallelN64CoreInternal.cpp index 2d0635c..c6e975f 100644 --- a/ParallelN64RT/ParallelN64CoreInternal.cpp +++ b/ParallelN64RT/ParallelN64CoreInternal.cpp @@ -36,4 +36,9 @@ ParallelN64CoreInternal::ParallelN64CoreInternal() : LibretroRT_Tools::CoreBase( ParallelN64CoreInternal::~ParallelN64CoreInternal() { coreInstance = nullptr; +} + +void ParallelN64CoreInternal::OverrideDefaultOptions(IMapView^ options) +{ + options->Lookup(L"parallel-n64-framerate")->SelectedValueIx = 1; } \ No newline at end of file diff --git a/ParallelN64RT/ParallelN64CoreInternal.h b/ParallelN64RT/ParallelN64CoreInternal.h index a1e82cb..7adcf75 100644 --- a/ParallelN64RT/ParallelN64CoreInternal.h +++ b/ParallelN64RT/ParallelN64CoreInternal.h @@ -11,6 +11,8 @@ namespace ParallelN64RT private ref class ParallelN64CoreInternal sealed : public CoreBase { protected private: + virtual void OverrideDefaultOptions(IMapView^ options) override; + ParallelN64CoreInternal(); public: diff --git a/RetriX.UWP/Package.appxmanifest b/RetriX.UWP/Package.appxmanifest index 6629a3f..4cce3ac 100644 --- a/RetriX.UWP/Package.appxmanifest +++ b/RetriX.UWP/Package.appxmanifest @@ -1,6 +1,6 @@  - + ms-resource:AppName\Text @@ -28,63 +28,60 @@ - - ms-resource:PCEngineRomDescription\Text - Assets\FileIcon.png - ms-resource:PCEngineRomDescription\Text - - .pce - - - - - - ms-resource:NeoGeoPocketRomDescription\Text + + ms-resource:DSRomDescription\Text Assets\FileIcon.png - ms-resource:NeoGeoPocketRomDescription\Text + ms-resource:DSRomDescription\Text - .ngp - .ngc + .nds - - ms-resource:PlayStationRomDescription\Text + + ms-resource:SNESRomDescription\Text Assets\FileIcon.png - ms-resource:PlayStationRomDescription\Text + ms-resource:SNESRomDescription\Text - .pbp + .smc + .sfc + .swc + .fig - - ms-resource:SG1000RomDescription\Text + + ms-resource:NESRomDescription\Text Assets\FileIcon.png - ms-resource:SG1000RomDescription\Text + ms-resource:NESRomDescription\Text - .sg + .fds + .nes + .unf + .unif - - ms-resource:GameGearRomDescription\Text + + ms-resource:GameBoyRomDescription\Text Assets\FileIcon.png - ms-resource:GameGearRomDescription\Text + ms-resource:GameBoyRomDescription\Text - .gg + .gb + .gbc + .dmg - - ms-resource:MasterSystemRomDescription\Text + + ms-resource:GameBoyAdvanceRomDescription\Text Assets\FileIcon.png - ms-resource:MasterSystemRomDescription\Text + ms-resource:GameBoyAdvanceRomDescription\Text - .sms + .gba @@ -102,60 +99,63 @@ - - ms-resource:GameBoyAdvanceRomDescription\Text + + ms-resource:MasterSystemRomDescription\Text Assets\FileIcon.png - ms-resource:GameBoyAdvanceRomDescription\Text + ms-resource:MasterSystemRomDescription\Text - .gba + .sms - - ms-resource:GameBoyRomDescription\Text + + ms-resource:GameGearRomDescription\Text Assets\FileIcon.png - ms-resource:GameBoyRomDescription\Text + ms-resource:GameGearRomDescription\Text - .gb - .gbc - .dmg + .gg - - ms-resource:NESRomDescription\Text + + ms-resource:SG1000RomDescription\Text Assets\FileIcon.png - ms-resource:NESRomDescription\Text + ms-resource:SG1000RomDescription\Text - .fds - .nes - .unf - .unif + .sg - - ms-resource:SNESRomDescription\Text + + ms-resource:PlayStationRomDescription\Text Assets\FileIcon.png - ms-resource:SNESRomDescription\Text + ms-resource:PlayStationRomDescription\Text - .smc - .sfc - .swc - .fig + .pbp - - ms-resource:DSRomDescription\Text + + ms-resource:NeoGeoPocketRomDescription\Text Assets\FileIcon.png - ms-resource:DSRomDescription\Text + ms-resource:NeoGeoPocketRomDescription\Text - .nds + .ngp + .ngc + + + + + + ms-resource:PCEngineRomDescription\Text + Assets\FileIcon.png + ms-resource:PCEngineRomDescription\Text + + .pce diff --git a/RetriX.UWP/RetriX.UWP.csproj b/RetriX.UWP/RetriX.UWP.csproj index 6299cc3..f1b2c4c 100644 --- a/RetriX.UWP/RetriX.UWP.csproj +++ b/RetriX.UWP/RetriX.UWP.csproj @@ -23,7 +23,7 @@ True Always x86|x64|arm - False + True true @@ -353,6 +353,10 @@ {a1897c60-c8ca-45ac-8917-a4dcfbcae523} NestopiaRT + + {95540631-8e61-475d-bd82-bafb7874eaca} + ParallelN64RT + {58b82d57-a956-4492-96fb-3e82fa82798a} RetriX.Shared diff --git a/RetriX.UWP/Services/EmulationService.cs b/RetriX.UWP/Services/EmulationService.cs index 4703613..01783bd 100644 --- a/RetriX.UWP/Services/EmulationService.cs +++ b/RetriX.UWP/Services/EmulationService.cs @@ -77,7 +77,7 @@ public EmulationService(IUserDialogs dialogsService, ILocalizationService locali { new ViewModels.GameSystemVM(FCEUMMRT.FCEUMMCore.Instance, LocalizationService, "SystemNameNES", "ManufacturerNameNintendo", "\uf118"), new ViewModels.GameSystemVM(Snes9XRT.Snes9XCore.Instance, LocalizationService, "SystemNameSNES", "ManufacturerNameNintendo", "\uf119"), - //new ViewModels.GameSystemVM(ParallelN64RT.ParallelN64Core.Instance, LocalizationService, "SystemNameNintendo64", "ManufacturerNameNintendo", "\uf116"), + new ViewModels.GameSystemVM(ParallelN64RT.ParallelN64Core.Instance, LocalizationService, "SystemNameNintendo64", "ManufacturerNameNintendo", "\uf116"), new ViewModels.GameSystemVM(GambatteRT.GambatteCore.Instance, LocalizationService, "SystemNameGameBoy", "ManufacturerNameNintendo", "\uf11b"), new ViewModels.GameSystemVM(VBAMRT.VBAMCore.Instance, LocalizationService, "SystemNameGameBoyAdvance", "ManufacturerNameNintendo", "\uf115"), new ViewModels.GameSystemVM(MelonDSRT.MelonDSCore.Instance, LocalizationService, "SystemNameDS", "ManufacturerNameNintendo", "\uf117"),