Add blargg NTSC filter settings

For specifying a custom YIQ to RGB decoding
matrix and a toggle to use external RGB palette.

Todo: Add textboxes for specifying a custom
decoding matrix in the video config dialog.
This commit is contained in:
Persune 2022-09-13 22:56:20 +08:00
parent 3c8533adec
commit 039c735436
No known key found for this signature in database
GPG key ID: 19B8E06A64948FF6
9 changed files with 112 additions and 16 deletions

View file

@ -232,10 +232,18 @@ struct NtscFilterSettings
bool VerticalBlend = false;
bool KeepVerticalResolution = false;
bool ColorimetryCorrection = true;
bool UseExternalPalette = true;
double YFilterLength = 0;
double IFilterLength = 0;
double QFilterLength = 0;
double DecodeMatrixIR = 0.956f;
double DecodeMatrixQR = 0.621f;
double DecodeMatrixIG = -0.272f;
double DecodeMatrixQG = -0.647f;
double DecodeMatrixIB = -1.105f;
double DecodeMatrixQB = 1.702f;
};
enum class RamPowerOnState
@ -1224,7 +1232,27 @@ public:
return _pictureSettings;
}
void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, bool verticalBlend, bool keepVerticalResolution, bool colorimetryCorrection)
void SetNtscFilterSettings(
double artifacts,
double bleed,
double fringing,
double gamma,
double resolution,
double sharpness,
bool mergeFields,
double yFilterLength,
double iFilterLength,
double qFilterLength,
double decodeMatrixIR,
double decodeMatrixQR,
double decodeMatrixIG,
double decodeMatrixQG,
double decodeMatrixIB,
double decodeMatrixQB,
bool verticalBlend,
bool keepVerticalResolution,
bool colorimetryCorrection,
bool useExternalPalette)
{
_ntscFilterSettings.Artifacts = artifacts;
_ntscFilterSettings.Bleed = bleed;
@ -1239,6 +1267,15 @@ public:
_ntscFilterSettings.IFilterLength = iFilterLength;
_ntscFilterSettings.QFilterLength = qFilterLength;
_ntscFilterSettings.DecodeMatrixIR = decodeMatrixIR;
_ntscFilterSettings.DecodeMatrixQR = decodeMatrixQR;
_ntscFilterSettings.DecodeMatrixIG = decodeMatrixIG;
_ntscFilterSettings.DecodeMatrixQG = decodeMatrixQG;
_ntscFilterSettings.DecodeMatrixIB = decodeMatrixIB;
_ntscFilterSettings.DecodeMatrixQB = decodeMatrixQB;
_ntscFilterSettings.UseExternalPalette = useExternalPalette;
_ntscFilterSettings.VerticalBlend = verticalBlend;
_ntscFilterSettings.KeepVerticalResolution = keepVerticalResolution;
_ntscFilterSettings.ColorimetryCorrection = colorimetryCorrection;

View file

@ -59,10 +59,25 @@ void NtscFilter::OnBeforeApplyFilter()
NtscFilterSettings ntscSettings = _console->GetSettings()->GetNtscFilterSettings();
_keepVerticalRes = ntscSettings.KeepVerticalResolution;
if (ntscSettings.UseExternalPalette != _useExternalPalette) {
paletteChanged = true;
_useExternalPalette = ntscSettings.UseExternalPalette;
}
if(paletteChanged || _ntscSetup.hue != pictureSettings.Hue || _ntscSetup.saturation != pictureSettings.Saturation || _ntscSetup.brightness != pictureSettings.Brightness || _ntscSetup.contrast != pictureSettings.Contrast ||
_ntscSetup.artifacts != ntscSettings.Artifacts || _ntscSetup.bleed != ntscSettings.Bleed || _ntscSetup.fringing != ntscSettings.Fringing || _ntscSetup.gamma != ntscSettings.Gamma ||
(_ntscSetup.merge_fields == 1) != ntscSettings.MergeFields || _ntscSetup.resolution != ntscSettings.Resolution || _ntscSetup.sharpness != ntscSettings.Sharpness) {
if(
paletteChanged ||
_ntscSetup.hue != pictureSettings.Hue ||
_ntscSetup.saturation != pictureSettings.Saturation ||
_ntscSetup.brightness != pictureSettings.Brightness ||
_ntscSetup.contrast != pictureSettings.Contrast ||
_ntscSetup.artifacts != ntscSettings.Artifacts ||
_ntscSetup.bleed != ntscSettings.Bleed ||
_ntscSetup.fringing != ntscSettings.Fringing ||
_ntscSetup.gamma != ntscSettings.Gamma ||
(_ntscSetup.merge_fields == 1) != ntscSettings.MergeFields ||
_ntscSetup.resolution != ntscSettings.Resolution ||
_ntscSetup.sharpness != ntscSettings.Sharpness
) {
_ntscSetup.hue = pictureSettings.Hue;
_ntscSetup.saturation = pictureSettings.Saturation;
_ntscSetup.brightness = pictureSettings.Brightness;
@ -76,11 +91,29 @@ void NtscFilter::OnBeforeApplyFilter()
_ntscSetup.resolution = ntscSettings.Resolution;
_ntscSetup.sharpness = ntscSettings.Sharpness;
if(_console->GetSettings()->IsFullColorPalette()) {
float decodermatrix[6] = {
(float)ntscSettings.DecodeMatrixIR,
(float)ntscSettings.DecodeMatrixQR,
(float)ntscSettings.DecodeMatrixIG,
(float)ntscSettings.DecodeMatrixQG,
(float)ntscSettings.DecodeMatrixIB,
(float)ntscSettings.DecodeMatrixQB
};
_ntscSetup.decoder_matrix = decodermatrix;
if (_useExternalPalette) {
if (_console->GetSettings()->IsFullColorPalette()) {
_ntscSetup.base_palette = nullptr;
_ntscSetup.palette = _palette;
}
else {
_ntscSetup.base_palette = _palette;
_ntscSetup.palette = nullptr;
}
}
else {
_ntscSetup.base_palette = nullptr;
_ntscSetup.palette = _palette;
} else {
_ntscSetup.base_palette = _palette;
_ntscSetup.palette = nullptr;
}

View file

@ -11,6 +11,7 @@ private:
nes_ntsc_setup_t _ntscSetup;
nes_ntsc_t _ntscData;
bool _keepVerticalRes = false;
bool _useExternalPalette = true;
uint8_t _palette[512 * 3];
uint32_t* _ntscBuffer;

View file

@ -42,11 +42,19 @@ namespace Mesen.GUI.Config
public bool NtscMergeFields = false;
public bool NtscVerticalBlend = true;
public bool NtscColorimetryCorrection = true;
public bool NtscUseExternalPalette = true;
[MinMax(-50, 400)] public Int32 NtscYFilterLength = 0;
[MinMax(0, 400)] public Int32 NtscIFilterLength = 50;
[MinMax(0, 400)] public Int32 NtscQFilterLength = 50;
public double NtscDecodeMatrixIR = 0.956;
public double NtscDecodeMatrixQR = 0.621;
public double NtscDecodeMatrixIG = -0.272;
public double NtscDecodeMatrixQG = -0.647;
public double NtscDecodeMatrixIB = -1.105;
public double NtscDecodeMatrixQB = 1.702;
public bool RemoveSpriteLimit = false;
public bool AdaptiveSpriteLimit = true;
public bool DisableBackground = false;
@ -110,7 +118,7 @@ namespace Mesen.GUI.Config
InteropEmu.SetVideoAspectRatio(videoInfo.AspectRatio, videoInfo.CustomAspectRatio);
InteropEmu.SetPictureSettings(videoInfo.Brightness / 100.0, videoInfo.Contrast / 100.0, videoInfo.Saturation / 100.0, videoInfo.Hue / 100.0, videoInfo.ScanlineIntensity / 100.0);
InteropEmu.SetNtscFilterSettings(videoInfo.NtscArtifacts / 100.0, videoInfo.NtscBleed / 100.0, videoInfo.NtscFringing / 100.0, videoInfo.NtscGamma / 100.0, videoInfo.NtscResolution / 100.0, videoInfo.NtscSharpness / 100.0, videoInfo.NtscMergeFields, videoInfo.NtscYFilterLength / 100.0, videoInfo.NtscIFilterLength / 100.0, videoInfo.NtscQFilterLength / 100.0, videoInfo.NtscVerticalBlend, videoInfo.NtscColorimetryCorrection);
InteropEmu.SetNtscFilterSettings(videoInfo.NtscArtifacts / 100.0, videoInfo.NtscBleed / 100.0, videoInfo.NtscFringing / 100.0, videoInfo.NtscGamma / 100.0, videoInfo.NtscResolution / 100.0, videoInfo.NtscSharpness / 100.0, videoInfo.NtscMergeFields, videoInfo.NtscYFilterLength / 100.0, videoInfo.NtscIFilterLength / 100.0, videoInfo.NtscQFilterLength / 100.0, videoInfo.NtscDecodeMatrixIR, videoInfo.NtscDecodeMatrixQR, videoInfo.NtscDecodeMatrixIG, videoInfo.NtscDecodeMatrixQG, videoInfo.NtscDecodeMatrixIB, videoInfo.NtscDecodeMatrixQB, videoInfo.NtscVerticalBlend, videoInfo.NtscColorimetryCorrection, videoInfo.NtscUseExternalPalette);
if(!string.IsNullOrWhiteSpace(videoInfo.PaletteData)) {
try {

View file

@ -78,6 +78,7 @@ namespace Mesen.GUI.Forms.Config
this.chkMergeFields = new System.Windows.Forms.CheckBox();
this.chkVerticalBlend = new System.Windows.Forms.CheckBox();
this.chkColorimetryCorrection = new System.Windows.Forms.CheckBox();
this.chkUseExternalPalette = new System.Windows.Forms.CheckBox();
this.grpCommon = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.chkBilinearInterpolation = new System.Windows.Forms.CheckBox();
@ -880,6 +881,7 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel6.Controls.Add(this.chkMergeFields, 0, 0);
this.tableLayoutPanel6.Controls.Add(this.chkVerticalBlend, 0, 1);
this.tableLayoutPanel6.Controls.Add(this.chkColorimetryCorrection, 1, 1);
this.tableLayoutPanel6.Controls.Add(this.chkUseExternalPalette, 1, 0);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 300);
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
@ -920,6 +922,16 @@ namespace Mesen.GUI.Forms.Config
this.chkColorimetryCorrection.Text = "Color Correction";
this.chkColorimetryCorrection.UseVisualStyleBackColor = true;
//
// chkUseExternalPalette
//
this.chkUseExternalPalette.AutoSize = true;
this.chkUseExternalPalette.Location = new System.Drawing.Point(143, 3);
this.chkUseExternalPalette.Name = "chkUseExternalPalette";
this.chkUseExternalPalette.Size = new System.Drawing.Size(100, 17);
this.chkUseExternalPalette.TabIndex = 33;
this.chkUseExternalPalette.Text = "External Palette";
this.chkUseExternalPalette.UseVisualStyleBackColor = true;
//
// grpCommon
//
this.grpCommon.Controls.Add(this.tableLayoutPanel4);
@ -2262,10 +2274,6 @@ namespace Mesen.GUI.Forms.Config
private ctrlRiskyOption chkForceBackgroundFirstColumn;
private ctrlRiskyOption chkForceSpritesFirstColumn;
private System.Windows.Forms.ToolStripMenuItem mnuPaletteNesClassic;
private System.Windows.Forms.TableLayoutPanel tlpNtscFilter2;
private Controls.ctrlHorizontalTrackbar trkYFilterLength;
private Controls.ctrlHorizontalTrackbar trkIFilterLength;
private Controls.ctrlHorizontalTrackbar trkQFilterLength;
private System.Windows.Forms.ToolStripMenuItem mnuPaletteSonyCxa2025As;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel6;
private System.Windows.Forms.Label lblCustomRatio;
@ -2318,5 +2326,10 @@ namespace Mesen.GUI.Forms.Config
private System.Windows.Forms.Label lblRequestedRefreshRate2;
private System.Windows.Forms.ComboBox cboRefreshRate2;
private System.Windows.Forms.CheckBox chkColorimetryCorrection;
private System.Windows.Forms.TableLayoutPanel tlpNtscFilter2;
private ctrlHorizontalTrackbar trkYFilterLength;
private ctrlHorizontalTrackbar trkIFilterLength;
private ctrlHorizontalTrackbar trkQFilterLength;
private System.Windows.Forms.CheckBox chkUseExternalPalette;
}
}

View file

@ -65,6 +65,7 @@ namespace Mesen.GUI.Forms.Config
AddBinding("NtscMergeFields", chkMergeFields);
AddBinding("NtscVerticalBlend", chkVerticalBlend);
AddBinding("NtscColorimetryCorrection", chkColorimetryCorrection);
AddBinding("NtscUseExternalPalette", chkUseExternalPalette);
AddBinding("NtscYFilterLength", trkYFilterLength);
AddBinding("NtscIFilterLength", trkIFilterLength);
@ -166,12 +167,14 @@ namespace Mesen.GUI.Forms.Config
tlpNtscFilter2.Visible = false;
chkMergeFields.Visible = true;
chkColorimetryCorrection.Visible = false;
chkUseExternalPalette.Visible = true;
grpNtscFilter.Visible = true;
} else if(filter == VideoFilterType.BisqwitNtsc || filter == VideoFilterType.BisqwitNtscHalfRes || filter == VideoFilterType.BisqwitNtscQuarterRes) {
tlpNtscFilter1.Visible = true;
tlpNtscFilter2.Visible = true;
chkMergeFields.Visible = false;
chkColorimetryCorrection.Visible = true;
chkUseExternalPalette.Visible = false;
grpNtscFilter.Visible = true;
} else {
grpNtscFilter.Visible = false;
@ -300,6 +303,7 @@ namespace Mesen.GUI.Forms.Config
chkMergeFields.Checked = false;
chkVerticalBlend.Checked = true;
chkColorimetryCorrection.Checked = true;
chkUseExternalPalette.Checked = true;
trkYFilterLength.Value = 0;
trkIFilterLength.Value = 50;

View file

@ -128,7 +128,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACs
BQAAAk1TRnQBSQFMAwEBAAFwAQABcAEAARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMA
BQAAAk1TRnQBSQFMAwEBAAGIAQABiAEAARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMA
ARADAAEBAQABGAYAAQweAAH5AvgB1QHBAbsBqAFyAWEBkAFHATABkAFHATABpgFuAVwB0gG8AbUB+AL2
pQAB1QHAAbkBlgFNATIBqgFaASwBuwFkASsBwAFpASkBwAFpASkBuwFlASwBqwFbAS0BmAFMATAB0wG9
AbWfAAHRAbgBrwGlAVgBMgHAAW0BLgHCAW0BLQHCAW0BLQHCAW0BLQHCAW0BLQHCAW0BLQHCAW0BLQHA

View file

@ -232,7 +232,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetVideoResizeFilter(VideoResizeFilter filter);
[DllImport(DLLPath)] public static extern void SetRgbPalette(byte[] palette, UInt32 paletteSize);
[DllImport(DLLPath)] public static extern void SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity);
[DllImport(DLLPath)] public static extern void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, [MarshalAs(UnmanagedType.I1)]bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, [MarshalAs(UnmanagedType.I1)]bool verticalBlend, [MarshalAs(UnmanagedType.I1)] bool colorimetryCorrection);
[DllImport(DLLPath)] public static extern void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, [MarshalAs(UnmanagedType.I1)]bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, double decodeMatrixIR, double decodeMatrixQR, double decodeMatrixIG, double decodeMatrixQG, double decodeMatrixIB, double decodeMatrixQB, [MarshalAs(UnmanagedType.I1)]bool verticalBlend, [MarshalAs(UnmanagedType.I1)] bool colorimetryCorrection, [MarshalAs(UnmanagedType.I1)] bool useExternalPalette);
[DllImport(DLLPath)] public static extern void SetInputDisplaySettings(byte visiblePorts, InputDisplayPosition displayPosition, [MarshalAs(UnmanagedType.I1)]bool displayHorizontally);
[DllImport(DLLPath)] public static extern void SetAutoSaveOptions(UInt32 delayInMinutes, [MarshalAs(UnmanagedType.I1)]bool showMessage);
[DllImport(DLLPath)] public static extern void SetPauseScreenMessage([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string message);

View file

@ -661,7 +661,7 @@ namespace InteropEmu {
DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { _settings->GetUserRgbPalette(paletteBuffer); }
DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer, uint32_t paletteSize) { _settings->SetUserRgbPalette(paletteBuffer, paletteSize); }
DllExport void __stdcall SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity) { _settings->SetPictureSettings(brightness, contrast, saturation, hue, scanlineIntensity); }
DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, bool verticalBlend, bool colorimetryCorrection) { _settings->SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields, yFilterLength, iFilterLength, qFilterLength, verticalBlend, false, colorimetryCorrection); }
DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields, double yFilterLength, double iFilterLength, double qFilterLength, double decodeMatrixIR, double decodeMatrixQR, double decodeMatrixIG, double decodeMatrixQG, double decodeMatrixIB, double decodeMatrixQB, bool verticalBlend, bool colorimetryCorrection, bool useExternalPalette) { _settings->SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields, yFilterLength, iFilterLength, qFilterLength, decodeMatrixIR, decodeMatrixQR, decodeMatrixIG, decodeMatrixQG, decodeMatrixIB, decodeMatrixQB, verticalBlend, false, colorimetryCorrection, useExternalPalette); }
DllExport void __stdcall SetPauseScreenMessage(char* message) { _settings->SetPauseScreenMessage(message); }
DllExport void __stdcall SetInputDisplaySettings(uint8_t visiblePorts, InputDisplayPosition displayPosition, bool displayHorizontally) { _settings->SetInputDisplaySettings(visiblePorts, displayPosition, displayHorizontally); }