Video: Added 60.0/50.0 fps mode

This commit is contained in:
Souryo 2017-09-29 22:09:00 -04:00
parent 99d1728da9
commit ef63dfa816
17 changed files with 69 additions and 15 deletions

View File

@ -1,6 +1,8 @@
#include "stdafx.h"
#include "AviRecorder.h"
#include "MessageManager.h"
#include "Console.h"
#include "EmulationSettings.h"
AviRecorder::AviRecorder()
{
@ -23,18 +25,28 @@ AviRecorder::~AviRecorder()
}
}
bool AviRecorder::StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel)
uint32_t AviRecorder::GetFps()
{
if(Console::GetModel() == NesModel::NTSC) {
return EmulationSettings::CheckFlag(EmulationFlags::IntegerFpsMode) ? 60000000 : 60098812;
} else {
return EmulationSettings::CheckFlag(EmulationFlags::IntegerFpsMode) ? 50000000 : 50006978;
}
}
bool AviRecorder::StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, uint32_t compressionLevel)
{
if(!_recording) {
_outputFile = filename;
_sampleRate = audioSampleRate;
_width = width;
_height = height;
_fps = GetFps();
_frameBufferLength = height * width * bpp;
_frameBuffer = new uint8_t[_frameBufferLength];
_aviWriter.reset(new AviWriter());
if(!_aviWriter->StartWrite(filename, codec, width, height, bpp, fps, audioSampleRate, compressionLevel)) {
if(!_aviWriter->StartWrite(filename, codec, width, height, bpp, _fps, audioSampleRate, compressionLevel)) {
_aviWriter.reset();
return false;
}
@ -76,7 +88,7 @@ void AviRecorder::StopRecording()
void AviRecorder::AddFrame(void* frameBuffer, uint32_t width, uint32_t height)
{
if(_recording) {
if(_width != width || _height != height) {
if(_width != width || _height != height || _fps != GetFps()) {
StopRecording();
} else {
auto lock = _lock.AcquireSafe();

View File

@ -22,14 +22,17 @@ private:
uint32_t _frameBufferLength;
uint32_t _sampleRate;
uint32_t _fps;
uint32_t _width;
uint32_t _height;
uint32_t GetFps();
public:
AviRecorder();
virtual ~AviRecorder();
bool StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel);
bool StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, uint32_t compressionLevel);
void StopRecording();
void AddFrame(void* frameBuffer, uint32_t width, uint32_t height);

View File

@ -531,9 +531,9 @@ double Console::GetFrameDelay()
//60.1fps (NTSC), 50.01fps (PAL/Dendy)
switch(_model) {
default:
case NesModel::NTSC: frameDelay = 16.63926405550947; break;
case NesModel::NTSC: frameDelay = EmulationSettings::CheckFlag(EmulationFlags::IntegerFpsMode) ? 16.6666666666666666667 : 16.63926405550947; break;
case NesModel::PAL:
case NesModel::Dendy: frameDelay = 19.99720920217466; break;
case NesModel::Dendy: frameDelay = EmulationSettings::CheckFlag(EmulationFlags::IntegerFpsMode) ? 20 : 19.99720920217466; break;
}
frameDelay /= (double)emulationSpeed / 100.0;
}

View File

@ -71,6 +71,8 @@ enum EmulationFlags : uint64_t
NsfRepeat = 0x800000000000,
NsfShuffle = 0x1000000000000,
IntegerFpsMode = 0x2000000000000,
ForceMaxSpeed = 0x4000000000000000,
ConsoleMode = 0x8000000000000000,
};

View File

@ -181,6 +181,15 @@ void SoundMixer::UpdateRates(bool forceUpdate)
newRate = (uint32_t)(newRate * (double)EmulationSettings::GetOverclockRate() / 100);
}
if(EmulationSettings::CheckFlag(EmulationFlags::IntegerFpsMode)) {
//Adjust sample rate when running at 60.0 fps instead of 60.1
if(_model == NesModel::NTSC) {
newRate = (uint32_t)(newRate * 60.0 / 60.0988118623484);
} else {
newRate = (uint32_t)(newRate * 50.0 / 50.00697796826829);
}
}
if(_clockRate != newRate || forceUpdate) {
_clockRate = newRate;
blip_set_rates(_blipBufLeft, _clockRate, _sampleRate);

View File

@ -92,7 +92,7 @@ void VideoRenderer::StartRecording(string filename, VideoCodec codec, uint32_t c
shared_ptr<AviRecorder> recorder(new AviRecorder());
FrameInfo frameInfo = VideoDecoder::GetInstance()->GetFrameInfo();
if(recorder->StartRecording(filename, codec, frameInfo.Width, frameInfo.Height, frameInfo.BitsPerPixel, 60098814, EmulationSettings::GetSampleRate(), compressionLevel)) {
if(recorder->StartRecording(filename, codec, frameInfo.Width, frameInfo.Height, frameInfo.BitsPerPixel, EmulationSettings::GetSampleRate(), compressionLevel)) {
_aviRecorder = recorder;
}
}

View File

@ -23,6 +23,7 @@ namespace Mesen.GUI.Config
[MinMax(0.1, 5.0)] public double CustomAspectRatio = 1.0;
public bool VerticalSync = false;
public bool UseHdPacks = false;
public bool IntegerFpsMode = false;
public string PaletteData;
[MinMax(-100, 100)] public Int32 Brightness = 0;
@ -66,6 +67,7 @@ namespace Mesen.GUI.Config
InteropEmu.SetFlag(EmulationFlags.ShowFPS, videoInfo.ShowFPS);
InteropEmu.SetFlag(EmulationFlags.VerticalSync, videoInfo.VerticalSync);
InteropEmu.SetFlag(EmulationFlags.UseHdPacks, videoInfo.UseHdPacks);
InteropEmu.SetFlag(EmulationFlags.IntegerFpsMode, videoInfo.IntegerFpsMode);
InteropEmu.SetFlag(EmulationFlags.DisableBackground, videoInfo.DisableBackground);
InteropEmu.SetFlag(EmulationFlags.DisableSprites, videoInfo.DisableSprites);

View File

@ -243,6 +243,7 @@
<Control ID="tpgGeneral">General</Control>
<Control ID="lblVideoScale">Escala:</Control>
<Control ID="lblVideoFilter">Filtre:</Control>
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
<Control ID="chkVerticalSync">Activa la sincronització vertical</Control>
<Control ID="lblDisplayRatio">Relació d'aspecte:</Control>
<Control ID="lblCustomRatio">Relació personalitzada:</Control>

View File

@ -243,6 +243,7 @@
<Control ID="tpgGeneral">General</Control>
<Control ID="lblVideoScale">Escala:</Control>
<Control ID="lblVideoFilter">Filtro:</Control>
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
<Control ID="chkVerticalSync">Activar la sincronización vertical</Control>
<Control ID="lblDisplayRatio">Formato de imagen:</Control>
<Control ID="lblCustomRatio">Relación personalizada:</Control>

View File

@ -245,6 +245,7 @@
<Control ID="tpgGeneral">Général</Control>
<Control ID="lblVideoScale">Échelle :</Control>
<Control ID="lblVideoFilter">Filtre :</Control>
<Control ID="chkIntegerFpsMode">Activer le mode 60.0/50.0 FPS (au lieu du 60.1/50.1 FPS normalement utilisé)</Control>
<Control ID="chkVerticalSync">Activer la synchronisation verticale</Control>
<Control ID="lblDisplayRatio">Format d'image :</Control>
<Control ID="lblCustomRatio">Ratio personalisé :</Control>

View File

@ -247,6 +247,7 @@
<Control ID="tpgGeneral">全般</Control>
<Control ID="lblVideoScale">画面サイズ:</Control>
<Control ID="lblVideoFilter">画面エフェクト:</Control>
<Control ID="chkIntegerFpsMode">60.0 fpsモードを有効にする 普段の60.1fpsに対して)</Control>
<Control ID="chkBilinearInterpolation">バイリニア補間を有効にする</Control>
<Control ID="chkVerticalSync">垂直同期を有効にする</Control>
<Control ID="lblDisplayRatio">画面アスペクト:</Control>

View File

@ -243,6 +243,7 @@
<Control ID="tpgGeneral">Geral</Control>
<Control ID="lblVideoScale">Escala:</Control>
<Control ID="lblVideoFilter">Filtro:</Control>
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
<Control ID="chkVerticalSync">Ativar a sincronização vertical</Control>
<Control ID="lblDisplayRatio">Formato de imagem:</Control>
<Control ID="lblCustomRatio">Proporção personalizada:</Control>

View File

@ -245,6 +245,7 @@
<Control ID="tpgGeneral">Общие</Control>
<Control ID="lblVideoScale">Размер :</Control>
<Control ID="lblVideoFilter">Фильтр :</Control>
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
<Control ID="chkVerticalSync">Включить вертикальную синхронизацию</Control>
<Control ID="lblDisplayRatio">Соотношение сторон :</Control>
<Control ID="lblCustomRatio">Custom ratio:</Control>

View File

@ -245,6 +245,7 @@
<Control ID="tpgGeneral">Загальнi</Control>
<Control ID="lblVideoScale">Розмір :</Control>
<Control ID="lblVideoFilter">Фiльтр :</Control>
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
<Control ID="chkVerticalSync">Включити вертикальну синхронізацію</Control>
<Control ID="lblDisplayRatio">Співвідношення сторін :</Control>
<Control ID="lblCustomRatio">Користувацьке співвідношення:</Control>

View File

@ -124,6 +124,7 @@ namespace Mesen.GUI.Forms.Config
this.mnuPaletteSonyCxa2025As = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaletteUnsaturated = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaletteYuv = new System.Windows.Forms.ToolStripMenuItem();
this.chkIntegerFpsMode = new System.Windows.Forms.CheckBox();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).BeginInit();
@ -170,16 +171,18 @@ namespace Mesen.GUI.Forms.Config
this.tlpMain.Controls.Add(this.lblVideoScale, 0, 0);
this.tlpMain.Controls.Add(this.chkVerticalSync, 0, 3);
this.tlpMain.Controls.Add(this.lblDisplayRatio, 0, 1);
this.tlpMain.Controls.Add(this.flowLayoutPanel7, 0, 2);
this.tlpMain.Controls.Add(this.flowLayoutPanel7, 0, 4);
this.tlpMain.Controls.Add(this.nudScale, 1, 0);
this.tlpMain.Controls.Add(this.flowLayoutPanel6, 1, 1);
this.tlpMain.Controls.Add(this.chkFullscreenForceIntegerScale, 0, 4);
this.tlpMain.Controls.Add(this.chkShowFps, 0, 5);
this.tlpMain.Controls.Add(this.chkFullscreenForceIntegerScale, 0, 5);
this.tlpMain.Controls.Add(this.chkShowFps, 0, 6);
this.tlpMain.Controls.Add(this.chkIntegerFpsMode, 0, 2);
this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpMain.Location = new System.Drawing.Point(3, 3);
this.tlpMain.Margin = new System.Windows.Forms.Padding(0);
this.tlpMain.Name = "tlpMain";
this.tlpMain.RowCount = 7;
this.tlpMain.RowCount = 8;
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
@ -228,7 +231,7 @@ namespace Mesen.GUI.Forms.Config
this.flowLayoutPanel7.Controls.Add(this.chkUseHdPacks);
this.flowLayoutPanel7.Controls.Add(this.picHdNesTooltip);
this.flowLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 46);
this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 92);
this.flowLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel7.Name = "flowLayoutPanel7";
this.flowLayoutPanel7.Size = new System.Drawing.Size(521, 23);
@ -364,7 +367,7 @@ namespace Mesen.GUI.Forms.Config
this.chkFullscreenForceIntegerScale.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkFullscreenForceIntegerScale.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkFullscreenForceIntegerScale, 2);
this.chkFullscreenForceIntegerScale.Location = new System.Drawing.Point(3, 95);
this.chkFullscreenForceIntegerScale.Location = new System.Drawing.Point(3, 118);
this.chkFullscreenForceIntegerScale.Name = "chkFullscreenForceIntegerScale";
this.chkFullscreenForceIntegerScale.Size = new System.Drawing.Size(289, 17);
this.chkFullscreenForceIntegerScale.TabIndex = 23;
@ -376,7 +379,7 @@ namespace Mesen.GUI.Forms.Config
this.chkShowFps.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkShowFps.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkShowFps, 2);
this.chkShowFps.Location = new System.Drawing.Point(3, 118);
this.chkShowFps.Location = new System.Drawing.Point(3, 141);
this.chkShowFps.Name = "chkShowFps";
this.chkShowFps.Size = new System.Drawing.Size(76, 17);
this.chkShowFps.TabIndex = 9;
@ -1456,6 +1459,18 @@ namespace Mesen.GUI.Forms.Config
this.mnuPaletteYuv.Text = "YUV v3 (by FirebrandX)";
this.mnuPaletteYuv.Click += new System.EventHandler(this.mnuPaletteYuv_Click);
//
// chkIntegerFpsMode
//
this.chkIntegerFpsMode.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkIntegerFpsMode.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkIntegerFpsMode, 2);
this.chkIntegerFpsMode.Location = new System.Drawing.Point(3, 49);
this.chkIntegerFpsMode.Name = "chkIntegerFpsMode";
this.chkIntegerFpsMode.Size = new System.Drawing.Size(295, 17);
this.chkIntegerFpsMode.TabIndex = 24;
this.chkIntegerFpsMode.Text = "Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)";
this.chkIntegerFpsMode.UseVisualStyleBackColor = true;
//
// frmVideoConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1615,5 +1630,6 @@ namespace Mesen.GUI.Forms.Config
private System.Windows.Forms.CheckBox chkFullscreenForceIntegerScale;
private System.Windows.Forms.CheckBox chkShowColorIndexes;
private Debugger.ctrlPaletteDisplay ctrlPaletteDisplay;
private System.Windows.Forms.CheckBox chkIntegerFpsMode;
}
}

View File

@ -29,6 +29,7 @@ namespace Mesen.GUI.Forms.Config
AddBinding("UseBilinearInterpolation", chkBilinearInterpolation);
AddBinding("VerticalSync", chkVerticalSync);
AddBinding("UseHdPacks", chkUseHdPacks);
AddBinding("IntegerFpsMode", chkIntegerFpsMode);
AddBinding("VideoScale", nudScale);
AddBinding("AspectRatio", cboAspectRatio);

View File

@ -1238,6 +1238,8 @@ namespace Mesen.GUI
NsfRepeat = 0x800000000000,
NsfShuffle = 0x1000000000000,
IntegerFpsMode = 0x2000000000000,
ForceMaxSpeed = 0x4000000000000000,
ConsoleMode = 0x8000000000000000,
}