Skip to content

Commit

Permalink
Variable Frame Rate support
Browse files Browse the repository at this point in the history
  • Loading branch information
albertofustinoni committed Jan 6, 2018
1 parent d678d31 commit d10d772
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 89 deletions.
28 changes: 18 additions & 10 deletions LibretroRT.FrontendComponents.Common/CoreCoordinator.cs
Expand Up @@ -78,12 +78,19 @@ private void UnregisterEvents()
if (Core == null)
return;

Core.GeometryChanged = null;
Core.PixelFormatChanged = null;
Core.RenderVideoFrame = null;
if (Renderer != null)
{
Core.GeometryChanged -= Renderer.GeometryChanged;
Core.PixelFormatChanged -= Renderer.PixelFormatChanged;
Core.RenderVideoFrame -= Renderer.RenderVideoFrame;
Core.TimingChanged -= Renderer.TimingChanged;
}

Core.TimingChanged = null;
Core.RenderAudioFrames = null;
if (AudioPlayer != null)
{
Core.TimingChanged -= AudioPlayer.TimingChanged;
Core.RenderAudioFrames -= AudioPlayer.RenderAudioFrames;
}

Core.PollInput = null;
Core.GetInputState = null;
Expand All @@ -96,15 +103,16 @@ private void RegisterEvents()

if (Renderer != null)
{
Core.GeometryChanged = Renderer.GeometryChanged;
Core.PixelFormatChanged = Renderer.PixelFormatChanged;
Core.RenderVideoFrame = Renderer.RenderVideoFrame;
Core.GeometryChanged += Renderer.GeometryChanged;
Core.PixelFormatChanged += Renderer.PixelFormatChanged;
Core.RenderVideoFrame += Renderer.RenderVideoFrame;
Core.TimingChanged += Renderer.TimingChanged;
}

if (AudioPlayer != null)
{
Core.TimingChanged = AudioPlayer.TimingChanged;
Core.RenderAudioFrames = AudioPlayer.RenderAudioFrames;
Core.TimingChanged += AudioPlayer.TimingChanged;
Core.RenderAudioFrames += AudioPlayer.RenderAudioFrames;
}

if (InputManager != null)
Expand Down
1 change: 1 addition & 0 deletions LibretroRT.FrontendComponents.Common/IRenderer.cs
Expand Up @@ -6,6 +6,7 @@ public interface IRenderer
{
void GeometryChanged(GameGeometry geometry);
void PixelFormatChanged(PixelFormats format);
void TimingChanged(SystemTiming timings);
void RenderVideoFrame([ReadOnlyArray] byte[] frameBuffer, uint width, uint height, uint pitch);
}
}
7 changes: 7 additions & 0 deletions LibretroRT.FrontendComponents.Renderer/Renderer.cpp
Expand Up @@ -25,6 +25,7 @@ void Renderer::InitializeVideoParameters(ICore^ core)
{
GeometryChanged(core->Geometry);
PixelFormatChanged(core->PixelFormat);
TimingChanged(core->Timing);
}

void Renderer::GeometryChanged(GameGeometry^ geometry)
Expand Down Expand Up @@ -59,6 +60,12 @@ void Renderer::PixelFormatChanged(PixelFormats format)
PixelFormat = format;
}

void Renderer::TimingChanged(SystemTiming^ timings)
{
TimeSpan newTargetDuration = { 10000000.0 / timings->FPS };
Canvas->TargetElapsedTime = newTargetDuration;
}

void Renderer::RenderVideoFrame(const Array<byte>^ frameBuffer, unsigned int width, unsigned int height, unsigned int pitch)
{
//Incomplete initialization
Expand Down
1 change: 1 addition & 0 deletions LibretroRT.FrontendComponents.Renderer/Renderer.h
Expand Up @@ -24,6 +24,7 @@ namespace LibretroRT_FrontendComponents_Renderer
void InitializeVideoParameters(ICore^ core);
virtual void GeometryChanged(GameGeometry^ geometry);
virtual void PixelFormatChanged(PixelFormats format);
virtual void TimingChanged(SystemTiming^ timings);

virtual void RenderVideoFrame(const Array<byte>^ frameBuffer, unsigned int width, unsigned int height, unsigned int pitch);
void CanvasDraw(ICanvasAnimatedControl^ sender, CanvasAnimatedDrawEventArgs^ args);
Expand Down
5 changes: 5 additions & 0 deletions LibretroRT.FrontendComponents.Win2DRenderer/Win2DRenderer.cs
Expand Up @@ -229,5 +229,10 @@ public void PixelFormatChanged(PixelFormats format)
{
RenderTargetManager.CurrentCorePixelFormat = format;
}

public void TimingChanged(SystemTiming timings)
{
RenderPanel.TargetElapsedTime = TimeSpan.FromMilliseconds(1000.0 / timings.FPS);
}
}
}
4 changes: 2 additions & 2 deletions LibretroRT.Test/TestBase.cs
Expand Up @@ -110,7 +110,7 @@ protected async Task ExecutionWorksInternal(string romName)
};

var renderVideoFrameCalled = false;
Target.RenderVideoFrame = (d, e, f, g) =>
Target.RenderVideoFrame += (d, e, f, g) =>
{
Assert.True(e > 0);
Assert.True(f > 0);
Expand All @@ -119,7 +119,7 @@ protected async Task ExecutionWorksInternal(string romName)
};

var renderAudioFrameCalled = false;
Target.RenderAudioFrames = (d) =>
Target.RenderAudioFrames += (d) =>
{
Assert.NotEmpty(d);
Assert.True(d.Length % 2 == 0);
Expand Down
10 changes: 5 additions & 5 deletions LibretroRT/ICore.h
Expand Up @@ -56,13 +56,13 @@ namespace LibretroRT
bool Serialize(WriteOnlyArray<uint8>^ stateData);
bool Unserialize(const Array<uint8>^ stateData);

property RenderVideoFrameDelegate^ RenderVideoFrame;
property RenderAudioFramesDelegate^ RenderAudioFrames;
event RenderVideoFrameDelegate^ RenderVideoFrame;
event RenderAudioFramesDelegate^ RenderAudioFrames;
property PollInputDelegate^ PollInput;
property GetInputStateDelegate^ GetInputState;
property GeometryChangedDelegate^ GeometryChanged;
property TimingChangedDelegate^ TimingChanged;
property PixelFormatChangedDelegate^ PixelFormatChanged;
event GeometryChangedDelegate^ GeometryChanged;
event TimingChangedDelegate^ TimingChanged;
event PixelFormatChangedDelegate^ PixelFormatChanged;
property OpenFileStreamDelegate^ OpenFileStream;
property CloseFileStreamDelegate^ CloseFileStream;
};
Expand Down
6 changes: 0 additions & 6 deletions LibretroRT_Shared/CoreBase.cpp
Expand Up @@ -274,9 +274,6 @@ int16_t CoreBase::RaiseGetInputState(unsigned port, unsigned device, unsigned in

size_t CoreBase::RaiseRenderAudioFrames(const int16_t* data, size_t frames)
{
if (RenderAudioFrames == nullptr)
return 0;

auto dataPtr = const_cast<int16_t*>(data);
auto dataArray = Platform::ArrayReference<int16_t>(dataPtr, frames * 2);
RenderAudioFrames(dataArray);
Expand All @@ -285,9 +282,6 @@ size_t CoreBase::RaiseRenderAudioFrames(const int16_t* data, size_t frames)

void CoreBase::RaiseRenderVideoFrame(const void* data, unsigned width, unsigned height, size_t pitch)
{
if (RenderVideoFrame == nullptr)
return;

//Duped frame
if (data == nullptr)
{
Expand Down
16 changes: 8 additions & 8 deletions LibretroRT_Shared/CoreBase.h
Expand Up @@ -87,32 +87,32 @@ namespace LibretroRT_Shared
{
PixelFormats get() { return pixelFormat; }
private:
void set(PixelFormats value) sealed { pixelFormat = value; if (PixelFormatChanged != nullptr) { PixelFormatChanged(pixelFormat); } }
void set(PixelFormats value) sealed { pixelFormat = value; PixelFormatChanged(pixelFormat); }
}

virtual property GameGeometry^ Geometry
{
GameGeometry^ get() { return geometry; }
private:
void set(GameGeometry^ value) sealed { geometry = value; if (GeometryChanged != nullptr) { GeometryChanged(geometry); } }
void set(GameGeometry^ value) sealed { geometry = value; GeometryChanged(geometry); }
}

virtual property SystemTiming^ Timing
{
SystemTiming^ get() { return timing; }
private:
void set(SystemTiming^ value) sealed { timing = value; if (TimingChanged != nullptr) { TimingChanged(timing); } }
void set(SystemTiming^ value) sealed { timing = value; TimingChanged(timing); }
}

virtual property unsigned int SerializationSize { unsigned int get(); }

virtual property RenderVideoFrameDelegate^ RenderVideoFrame;
virtual property RenderAudioFramesDelegate^ RenderAudioFrames;
virtual event RenderVideoFrameDelegate^ RenderVideoFrame;
virtual event RenderAudioFramesDelegate^ RenderAudioFrames;
virtual property PollInputDelegate^ PollInput;
virtual property GetInputStateDelegate^ GetInputState;
virtual property GeometryChangedDelegate^ GeometryChanged;
virtual property TimingChangedDelegate^ TimingChanged;
virtual property PixelFormatChangedDelegate^ PixelFormatChanged;
virtual event GeometryChangedDelegate^ GeometryChanged;
virtual event TimingChangedDelegate^ TimingChanged;
virtual event PixelFormatChangedDelegate^ PixelFormatChanged;
virtual property OpenFileStreamDelegate^ OpenFileStream;
virtual property CloseFileStreamDelegate^ CloseFileStream;

Expand Down
116 changes: 58 additions & 58 deletions RetriX.UWP/Package.appxmanifest
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
<Identity Name="15612Aftnet.RetriX" Publisher="CN=Alberto Fustinoni, O=AlbertoFustinoni, L=Kawasaki, S=Kanagawa, C=JP" Version="1.9.1.0" />
<Identity Name="15612Aftnet.RetriX" Publisher="CN=Alberto Fustinoni, O=AlbertoFustinoni, L=Kawasaki, S=Kanagawa, C=JP" Version="1.9.2.0" />
<mp:PhoneIdentity PhoneProductId="efc54b08-6566-4c74-810c-e9437145cdf4" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>ms-resource:AppName\Text</DisplayName>
Expand Down Expand Up @@ -28,70 +28,63 @@
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="chdroms">
<uap:DisplayName>ms-resource:CHDRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="pcengineroms">
<uap:DisplayName>ms-resource:PCEngineRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:CHDRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:PCEngineRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.chd</uap:FileType>
<uap:FileType>.pce</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="ndsroms">
<uap:DisplayName>ms-resource:DSRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="ngproms">
<uap:DisplayName>ms-resource:NeoGeoPocketRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:DSRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:NeoGeoPocketRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.nds</uap:FileType>
<uap:FileType>.ngp</uap:FileType>
<uap:FileType>.ngc</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="snesroms">
<uap:DisplayName>ms-resource:SNESRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="ps1roms">
<uap:DisplayName>ms-resource:PlayStationRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:SNESRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:PlayStationRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.smc</uap:FileType>
<uap:FileType>.sfc</uap:FileType>
<uap:FileType>.swc</uap:FileType>
<uap:FileType>.fig</uap:FileType>
<uap:FileType>.pbp</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="nesrom">
<uap:DisplayName>ms-resource:NESRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="sgroms">
<uap:DisplayName>ms-resource:SG1000RomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:NESRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:SG1000RomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.fds</uap:FileType>
<uap:FileType>.nes</uap:FileType>
<uap:FileType>.unf</uap:FileType>
<uap:FileType>.unif</uap:FileType>
<uap:FileType>.sg</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="gbroms">
<uap:DisplayName>ms-resource:GameBoyRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="gamegearroms">
<uap:DisplayName>ms-resource:GameGearRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:GameBoyRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:GameGearRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.gb</uap:FileType>
<uap:FileType>.gbc</uap:FileType>
<uap:FileType>.dmg</uap:FileType>
<uap:FileType>.gg</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="gbaroms">
<uap:DisplayName>ms-resource:GameBoyAdvanceRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="mastersystemroms">
<uap:DisplayName>ms-resource:MasterSystemRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:GameBoyAdvanceRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:MasterSystemRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.gba</uap:FileType>
<uap:FileType>.sms</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
Expand All @@ -109,63 +102,70 @@
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="mastersystemroms">
<uap:DisplayName>ms-resource:MasterSystemRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="gbaroms">
<uap:DisplayName>ms-resource:GameBoyAdvanceRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:MasterSystemRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:GameBoyAdvanceRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.sms</uap:FileType>
<uap:FileType>.gba</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="gamegearroms">
<uap:DisplayName>ms-resource:GameGearRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="gbroms">
<uap:DisplayName>ms-resource:GameBoyRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:GameGearRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:GameBoyRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.gg</uap:FileType>
<uap:FileType>.gb</uap:FileType>
<uap:FileType>.gbc</uap:FileType>
<uap:FileType>.dmg</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="sgroms">
<uap:DisplayName>ms-resource:SG1000RomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="nesrom">
<uap:DisplayName>ms-resource:NESRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:SG1000RomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:NESRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.sg</uap:FileType>
<uap:FileType>.fds</uap:FileType>
<uap:FileType>.nes</uap:FileType>
<uap:FileType>.unf</uap:FileType>
<uap:FileType>.unif</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="ps1roms">
<uap:DisplayName>ms-resource:PlayStationRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="snesroms">
<uap:DisplayName>ms-resource:SNESRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:PlayStationRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:SNESRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.pbp</uap:FileType>
<uap:FileType>.smc</uap:FileType>
<uap:FileType>.sfc</uap:FileType>
<uap:FileType>.swc</uap:FileType>
<uap:FileType>.fig</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="ngproms">
<uap:DisplayName>ms-resource:NeoGeoPocketRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="ndsroms">
<uap:DisplayName>ms-resource:DSRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:NeoGeoPocketRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:DSRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.ngp</uap:FileType>
<uap:FileType>.ngc</uap:FileType>
<uap:FileType>.nds</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="pcengineroms">
<uap:DisplayName>ms-resource:PCEngineRomDescription\Text</uap:DisplayName>
<uap:FileTypeAssociation Name="chdroms">
<uap:DisplayName>ms-resource:CHDRomDescription\Text</uap:DisplayName>
<uap:Logo>Assets\FileIcon.png</uap:Logo>
<uap:InfoTip>ms-resource:PCEngineRomDescription\Text</uap:InfoTip>
<uap:InfoTip>ms-resource:CHDRomDescription\Text</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType>.pce</uap:FileType>
<uap:FileType>.chd</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
Expand Down

0 comments on commit d10d772

Please sign in to comment.