Video Filters: Added "Prescale" filter to allow limiting the blur factor when using bilinear interpolation

This commit is contained in:
Souryo 2016-07-09 09:06:34 -04:00
parent c14599b747
commit 0944bff478
10 changed files with 123 additions and 19 deletions

View file

@ -72,6 +72,9 @@ enum class VideoFilterType
_2xSai = 13,
Super2xSai = 14,
SuperEagle = 15,
Prescale2x = 16,
Prescale3x = 17,
Prescale4x = 18,
HdPack = 999
};

View file

@ -31,6 +31,29 @@ FrameInfo ScaleFilter::GetFrameInfo()
return{ overscan.GetScreenWidth()*_filterScale, overscan.GetScreenHeight()*_filterScale, 4 };
}
void ScaleFilter::ApplyPrescaleFilter()
{
uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer();
OverscanDimensions overscan = GetOverscan();
uint32_t height = overscan.GetScreenHeight();
uint32_t width = overscan.GetScreenWidth();
uint32_t *inputBuffer = _decodedPpuBuffer;
for(uint32_t y = 0; y < height; y++) {
for(uint32_t x = 0; x < width; x++) {
for(uint32_t i = 0; i < _filterScale; i++) {
*(outputBuffer++) = *inputBuffer;
}
inputBuffer++;
}
for(uint32_t i = 1; i< _filterScale; i++) {
memcpy(outputBuffer, outputBuffer - width*_filterScale, width*_filterScale *4);
outputBuffer += width*_filterScale;
}
}
}
void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{
DecodePpuBuffer(ppuOutputBuffer, _decodedPpuBuffer, false);
@ -56,6 +79,8 @@ void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
supertwoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::SuperEagle) {
supereagle_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::Prescale) {
ApplyPrescaleFilter();
}
double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity;

View file

@ -11,6 +11,7 @@ enum class ScaleFilterType
_2xSai,
Super2xSai,
SuperEagle,
Prescale,
};
class ScaleFilter : public DefaultVideoFilter
@ -21,6 +22,8 @@ private:
uint32_t _filterScale;
ScaleFilterType _scaleFilterType;
void ApplyPrescaleFilter();
public:
ScaleFilter(ScaleFilterType scaleFilterType, uint32_t scale);
virtual ~ScaleFilter();

View file

@ -68,6 +68,10 @@ void VideoDecoder::UpdateVideoFilter()
case VideoFilterType::Super2xSai: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Super2xSai, 2)); break;
case VideoFilterType::SuperEagle: _videoFilter.reset(new ScaleFilter(ScaleFilterType::SuperEagle, 2)); break;
case VideoFilterType::Prescale2x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 2)); break;
case VideoFilterType::Prescale3x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 3)); break;
case VideoFilterType::Prescale4x: _videoFilter.reset(new ScaleFilter(ScaleFilterType::Prescale, 4)); break;
case VideoFilterType::HdPack: _videoFilter.reset(new HdVideoFilter()); break;
}
}

View file

@ -76,6 +76,9 @@
<Value ID="_2xSai">2xSai</Value>
<Value ID="Super2xSai">Super2xSai</Value>
<Value ID="SuperEagle">SuperEagle</Value>
<Value ID="Prescale2x">Prescale 2x</Value>
<Value ID="Prescale3x">Prescale 3x</Value>
<Value ID="Prescale4x">Prescale 4x</Value>
</Enum>
<Enum ID="ConsoleType">
<Value ID="Nes">NES</Value>

View file

@ -431,6 +431,9 @@
<Value ID="_2xSai">2xSai</Value>
<Value ID="Super2xSai">Super2xSai</Value>
<Value ID="SuperEagle">SuperEagle</Value>
<Value ID="Prescale2x">Prescale 2x</Value>
<Value ID="Prescale3x">Prescale 3x</Value>
<Value ID="Prescale4x">Prescale 4x</Value>
</Enum>
<Enum ID="ConsoleType">
<Value ID="Nes">NES</Value>

View file

@ -423,6 +423,9 @@
<Value ID="_2xSai">2xSai</Value>
<Value ID="Super2xSai">Super2xSai</Value>
<Value ID="SuperEagle">SuperEagle</Value>
<Value ID="Prescale2x">Prescale 2x</Value>
<Value ID="Prescale3x">Prescale 3x</Value>
<Value ID="Prescale4x">Prescale 4x</Value>
</Enum>
<Enum ID="ConsoleType">
<Value ID="Nes">NES</Value>

View file

@ -33,6 +33,7 @@ namespace Mesen.GUI.Forms
this.components = new System.ComponentModel.Container();
this.menuTimer = new System.Windows.Forms.Timer(this.components);
this.panelRenderer = new System.Windows.Forms.Panel();
this.ctrlLoading = new Mesen.GUI.Controls.ctrlLoadingRom();
this.ctrlNsfPlayer = new Mesen.GUI.Controls.ctrlNsfPlayer();
this.ctrlRenderer = new Mesen.GUI.Controls.ctrlRenderer();
this.menuStrip = new System.Windows.Forms.MenuStrip();
@ -158,7 +159,10 @@ namespace Mesen.GUI.Forms
this.mnuCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
this.ctrlLoading = new Mesen.GUI.Controls.ctrlLoadingRom();
this.mnuPrescale3xFilter = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPrescale2xFilter = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPrescale4xFilter = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem23 = new System.Windows.Forms.ToolStripSeparator();
this.panelRenderer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
@ -182,6 +186,16 @@ namespace Mesen.GUI.Forms
this.panelRenderer.DoubleClick += new System.EventHandler(this.ctrlRenderer_DoubleClick);
this.panelRenderer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlRenderer_MouseMove);
//
// ctrlLoading
//
this.ctrlLoading.BackColor = System.Drawing.Color.Black;
this.ctrlLoading.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlLoading.Location = new System.Drawing.Point(0, 0);
this.ctrlLoading.Name = "ctrlLoading";
this.ctrlLoading.Size = new System.Drawing.Size(360, 239);
this.ctrlLoading.TabIndex = 4;
this.ctrlLoading.Visible = false;
//
// ctrlNsfPlayer
//
this.ctrlNsfPlayer.BackColor = System.Drawing.Color.Black;
@ -241,50 +255,50 @@ namespace Mesen.GUI.Forms
this.mnuOpen.Image = global::Mesen.GUI.Properties.Resources.FolderOpen;
this.mnuOpen.Name = "mnuOpen";
this.mnuOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.mnuOpen.Size = new System.Drawing.Size(152, 22);
this.mnuOpen.Size = new System.Drawing.Size(146, 22);
this.mnuOpen.Text = "Open";
this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
//
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem4.Size = new System.Drawing.Size(143, 6);
//
// mnuSaveState
//
this.mnuSaveState.Name = "mnuSaveState";
this.mnuSaveState.Size = new System.Drawing.Size(152, 22);
this.mnuSaveState.Size = new System.Drawing.Size(146, 22);
this.mnuSaveState.Text = "Save State";
this.mnuSaveState.DropDownOpening += new System.EventHandler(this.mnuSaveState_DropDownOpening);
//
// mnuLoadState
//
this.mnuLoadState.Name = "mnuLoadState";
this.mnuLoadState.Size = new System.Drawing.Size(152, 22);
this.mnuLoadState.Size = new System.Drawing.Size(146, 22);
this.mnuLoadState.Text = "Load State";
this.mnuLoadState.DropDownOpening += new System.EventHandler(this.mnuLoadState_DropDownOpening);
//
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem7.Size = new System.Drawing.Size(143, 6);
//
// mnuRecentFiles
//
this.mnuRecentFiles.Name = "mnuRecentFiles";
this.mnuRecentFiles.Size = new System.Drawing.Size(152, 22);
this.mnuRecentFiles.Size = new System.Drawing.Size(146, 22);
this.mnuRecentFiles.Text = "Recent Files";
//
// toolStripMenuItem6
//
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
this.toolStripMenuItem6.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem6.Size = new System.Drawing.Size(143, 6);
//
// mnuExit
//
this.mnuExit.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuExit.Name = "mnuExit";
this.mnuExit.Size = new System.Drawing.Size(152, 22);
this.mnuExit.Size = new System.Drawing.Size(146, 22);
this.mnuExit.Text = "Exit";
this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
//
@ -627,10 +641,14 @@ namespace Mesen.GUI.Forms
this.mnuScale2xFilter,
this.mnuScale3xFilter,
this.mnuScale4xFilter,
this.toolStripMenuItem18,
this.toolStripMenuItem23,
this.mnu2xSaiFilter,
this.mnuSuper2xSaiFilter,
this.mnuSuperEagleFilter,
this.toolStripMenuItem18,
this.mnuPrescale2xFilter,
this.mnuPrescale3xFilter,
this.mnuPrescale4xFilter,
this.toolStripMenuItem19,
this.mnuBilinearInterpolation});
this.mnuVideoFilter.Name = "mnuVideoFilter";
@ -740,7 +758,7 @@ namespace Mesen.GUI.Forms
//
this.mnuScale4xFilter.Name = "mnuScale4xFilter";
this.mnuScale4xFilter.Size = new System.Drawing.Size(206, 22);
this.mnuScale4xFilter.Text = "Scale4x";
this.mnuScale4xFilter.Text = "Scale 4x";
this.mnuScale4xFilter.Click += new System.EventHandler(this.mnuScale4xFilter_Click);
//
// toolStripMenuItem18
@ -1212,14 +1230,31 @@ namespace Mesen.GUI.Forms
this.mnuAbout.Text = "About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
// ctrlLoading
// mnuPrescale3xFilter
//
this.ctrlLoading.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlLoading.Location = new System.Drawing.Point(0, 0);
this.ctrlLoading.Name = "ctrlLoading";
this.ctrlLoading.Size = new System.Drawing.Size(360, 239);
this.ctrlLoading.TabIndex = 4;
this.ctrlLoading.Visible = false;
this.mnuPrescale3xFilter.Name = "mnuPrescale3xFilter";
this.mnuPrescale3xFilter.Size = new System.Drawing.Size(206, 22);
this.mnuPrescale3xFilter.Text = "Prescale 3x";
this.mnuPrescale3xFilter.Click += new System.EventHandler(this.mnuPrescale3xFilter_Click);
//
// mnuPrescale2xFilter
//
this.mnuPrescale2xFilter.Name = "mnuPrescale2xFilter";
this.mnuPrescale2xFilter.Size = new System.Drawing.Size(206, 22);
this.mnuPrescale2xFilter.Text = "Prescale 2x";
this.mnuPrescale2xFilter.Click += new System.EventHandler(this.mnuPrescale2xFilter_Click);
//
// mnuPrescale4xFilter
//
this.mnuPrescale4xFilter.Name = "mnuPrescale4xFilter";
this.mnuPrescale4xFilter.Size = new System.Drawing.Size(206, 22);
this.mnuPrescale4xFilter.Text = "Prescale 4x";
this.mnuPrescale4xFilter.Click += new System.EventHandler(this.mnuPrescale4xFilter_Click);
//
// toolStripMenuItem23
//
this.toolStripMenuItem23.Name = "toolStripMenuItem23";
this.toolStripMenuItem23.Size = new System.Drawing.Size(203, 6);
//
// frmMain
//
@ -1375,6 +1410,10 @@ namespace Mesen.GUI.Forms
private System.Windows.Forms.ToolStripMenuItem mnuEmulationConfig;
private Controls.ctrlNsfPlayer ctrlNsfPlayer;
private Controls.ctrlLoadingRom ctrlLoading;
private System.Windows.Forms.ToolStripMenuItem mnuPrescale4xFilter;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem23;
private System.Windows.Forms.ToolStripMenuItem mnuPrescale2xFilter;
private System.Windows.Forms.ToolStripMenuItem mnuPrescale3xFilter;
}
}

View file

@ -1056,6 +1056,9 @@ namespace Mesen.GUI.Forms
mnu2xSaiFilter.Checked = (filterType == VideoFilterType._2xSai);
mnuSuper2xSaiFilter.Checked = (filterType == VideoFilterType.Super2xSai);
mnuSuperEagleFilter.Checked = (filterType == VideoFilterType.SuperEagle);
mnuPrescale2xFilter.Checked = (filterType == VideoFilterType.Prescale2x);
mnuPrescale3xFilter.Checked = (filterType == VideoFilterType.Prescale3x);
mnuPrescale4xFilter.Checked = (filterType == VideoFilterType.Prescale4x);
ConfigManager.Config.VideoInfo.VideoFilter = filterType;
ConfigManager.ApplyChanges();
@ -1162,6 +1165,21 @@ namespace Mesen.GUI.Forms
{
SetVideoFilter(VideoFilterType.SuperEagle);
}
private void mnuPrescale2xFilter_Click(object sender, EventArgs e)
{
SetVideoFilter(VideoFilterType.Prescale2x);
}
private void mnuPrescale3xFilter_Click(object sender, EventArgs e)
{
SetVideoFilter(VideoFilterType.Prescale3x);
}
private void mnuPrescale4xFilter_Click(object sender, EventArgs e)
{
SetVideoFilter(VideoFilterType.Prescale4x);
}
private void InitializeFdsDiskMenu()
{

View file

@ -809,7 +809,10 @@ namespace Mesen.GUI
Scale4x = 12,
_2xSai = 13,
Super2xSai = 14,
SuperEagle = 15
SuperEagle = 15,
Prescale2x = 16,
Prescale3x = 17,
Prescale4x = 18
}
public enum VideoResizeFilter