From 3655def9038cbf187ef76896449d0003b8d4823d Mon Sep 17 00:00:00 2001 From: Persune <54422576+Gumball2415@users.noreply.github.com> Date: Sun, 5 Sep 2021 16:00:25 +0800 Subject: [PATCH 1/2] Add SMPTE C colorimetry --- Core/BisqwitNtscFilter.cpp | 39 +++++++++++++++++++++++++++----------- Core/BisqwitNtscFilter.h | 5 +++-- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Core/BisqwitNtscFilter.cpp b/Core/BisqwitNtscFilter.cpp index b3a3f39fe..a343c599d 100644 --- a/Core/BisqwitNtscFilter.cpp +++ b/Core/BisqwitNtscFilter.cpp @@ -89,6 +89,7 @@ void BisqwitNtscFilter::OnBeforeApplyFilter() NtscFilterSettings ntscSettings = _console->GetSettings()->GetNtscFilterSettings(); _keepVerticalRes = ntscSettings.KeepVerticalResolution; + //_SMPTE_C = ntscSettings.NtscSmpteC; const double pi = std::atan(1.0) * 4; int contrast = (int)((pictureSettings.Contrast + 1.0) * (pictureSettings.Contrast + 1.0) * 167941); @@ -103,14 +104,30 @@ void BisqwitNtscFilter::OnBeforeApplyFilter() _y = contrast / _yWidth; - _ir = (int)(contrast * 1.994681e-6 * saturation / _iWidth); - _qr = (int)(contrast * 9.915742e-7 * saturation / _qWidth); - - _ig = (int)(contrast * 9.151351e-8 * saturation / _iWidth); - _qg = (int)(contrast * -6.334805e-7 * saturation / _qWidth); - - _ib = (int)(contrast * -1.012984e-6 * saturation / _iWidth); - _qb = (int)(contrast * 1.667217e-6 * saturation / _qWidth); + // magic numbers is corresponding values from the YIQ to RGB formula + // but divided by 13,995 * [arbitrary value] +/* + _ir = (int)(( 0.95599 / (13995 * 34.2457747)) * contrast * saturation / _iWidth); + _ig = (int)((-0.27201 / (13995 * 212.3864250)) * contrast * saturation / _iWidth); + _ib = (int)((-1.10674 / (13995 * 78.0674723)) * contrast * saturation / _iWidth); + _qr = (int)(( 0.62082 / (13995 * 44.7370743)) * contrast * saturation / _qWidth); + _qg = (int)((-0.64720 / (13995 * 73.0015960)) * contrast * saturation / _qWidth); + _qb = (int)(( 1.70423 / (13995 * 73.0404051)) * contrast * saturation / _qWidth); +*/ + _ir = (int)(contrast * 1.994681e-6 * saturation / _iWidth); + _ig = (int)(contrast * 9.151351e-8 * saturation / _iWidth); + _ib = (int)(contrast * -1.012984e-6 * saturation / _iWidth); + _qr = (int)(contrast * 9.915742e-7 * saturation / _qWidth); + _qg = (int)(contrast * -6.334805e-7 * saturation / _qWidth); + _qb = (int)(contrast * 1.667217e-6 * saturation / _qWidth); + + // alternate values based on the SMPTE C color primaries + _irC = (int)((0.95599 / (13995 * 80)) * contrast * saturation / _iWidth); + _igC = (int)((-0.27201 / (13995 * 80)) * contrast * saturation / _iWidth); + _ibC = (int)((-1.10674 / (13995 * 80)) * contrast * saturation / _iWidth); + _qrC = (int)((0.62082 / (13995 * 80)) * contrast * saturation / _qWidth); + _qgC = (int)((-0.64720 / (13995 * 80)) * contrast * saturation / _qWidth); + _qbC = (int)((1.70423 / (13995 * 80)) * contrast * saturation / _qWidth); } void BisqwitNtscFilter::RecursiveBlend(int iterationCount, uint64_t *output, uint64_t *currentLine, uint64_t *nextLine, int pixelsPerCycle, bool verticalBlend) @@ -282,9 +299,9 @@ void BisqwitNtscFilter::NtscDecodeLine(int width, const int8_t* signal, uint32_t qsum += Read(s) * Sin(s) - Read(s - _qWidth) * Sin(s - _qWidth); if(!(s % _resDivider) && s >= leftOverscan) { - int r = std::min(255, std::max(0, (ysum*_y + isum*_ir + qsum*_qr) / 65536)); - int g = std::min(255, std::max(0, (ysum*_y + isum*_ig + qsum*_qg) / 65536)); - int b = std::min(255, std::max(0, (ysum*_y + isum*_ib + qsum*_qb) / 65536)); + int r = std::min(255, std::max(0, (ysum*_y + isum*_irC + qsum*_qrC) / 65536)); + int g = std::min(255, std::max(0, (ysum*_y + isum*_igC + qsum*_qgC) / 65536)); + int b = std::min(255, std::max(0, (ysum*_y + isum*_ibC + qsum*_qbC) / 65536)); *target = 0xFF000000 | (r << 16) | (g << 8) | b; target++; diff --git a/Core/BisqwitNtscFilter.h b/Core/BisqwitNtscFilter.h index 4cf556b3d..15c54a854 100644 --- a/Core/BisqwitNtscFilter.h +++ b/Core/BisqwitNtscFilter.h @@ -20,6 +20,7 @@ class BisqwitNtscFilter : public BaseVideoFilter atomic _workDone; bool _keepVerticalRes = false; + bool _SMPTE_C = false; int _resDivider = 1; uint16_t *_ppuOutputBuffer = nullptr; @@ -33,8 +34,8 @@ class BisqwitNtscFilter : public BaseVideoFilter */ int _yWidth, _iWidth, _qWidth; int _y; - int _ir, _ig, _ib; - int _qr, _qg, _qb; + int _ir, _ig, _ib, _irC, _igC, _ibC; + int _qr, _qg, _qb, _qrC, _qgC, _qbC; //To finetune hue, you would have to recalculate sinetable[]. (Coarse changes can be made with Phase0.) int8_t _sinetable[27]; // 8*sin(x*2pi/12) From 5890ad3495d943724896b8a4cf0bc5b1376323ca Mon Sep 17 00:00:00 2001 From: Persune Date: Sun, 27 Feb 2022 05:41:05 +0800 Subject: [PATCH 2/2] Toggle between old and new colorimetries --- Core/BisqwitNtscFilter.cpp | 20 ++++++++--------- Core/BisqwitNtscFilter.h | 6 +++--- Core/EmulationSettings.h | 3 +++ Core/ScaleFilter.cpp | 3 +++ Core/VideoDecoder.cpp | 9 +++++--- GUI.NET/Forms/Config/frmVideoConfig.cs | 7 +++++- GUI.NET/Forms/frmMain.Designer.cs | 30 ++++++++++++++++++++++++++ GUI.NET/Forms/frmMain.Options.cs | 18 ++++++++++++++++ GUI.NET/Forms/frmMain.cs | 3 +++ GUI.NET/InteropEmu.cs | 3 +++ 10 files changed, 85 insertions(+), 17 deletions(-) diff --git a/Core/BisqwitNtscFilter.cpp b/Core/BisqwitNtscFilter.cpp index a343c599d..e1846b218 100644 --- a/Core/BisqwitNtscFilter.cpp +++ b/Core/BisqwitNtscFilter.cpp @@ -8,11 +8,12 @@ #include "EmulationSettings.h" #include "Console.h" -BisqwitNtscFilter::BisqwitNtscFilter(shared_ptr console, int resDivider) : BaseVideoFilter(console) +BisqwitNtscFilter::BisqwitNtscFilter(shared_ptr console, int resDivider, bool SMPTE_C) : BaseVideoFilter(console) { _resDivider = resDivider; _stopThread = false; _workDone = false; + _SMPTE_C = SMPTE_C; const int8_t signalLumaLow[4] = { -29, -15, 22, 71 }; const int8_t signalLumaHigh[4] = { 32, 66, 105, 105 }; @@ -49,7 +50,7 @@ BisqwitNtscFilter::BisqwitNtscFilter(shared_ptr console, int resDivider outputBuffer += GetOverscan().GetScreenWidth() * 64 / _resDivider / _resDivider * (120 - GetOverscan().Top); } - DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, (IsOddFrame() ? 8 : 0) + 327360); + DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, (IsOddFrame() ? 8 : 0) + 327360, SMPTE_C); _workDone = true; } @@ -69,7 +70,7 @@ void BisqwitNtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer) _workDone = false; _waitWork.Signal(); - DecodeFrame(GetOverscan().Top, 120, ppuOutputBuffer, GetOutputBuffer(), (IsOddFrame() ? 8 : 0) + GetOverscan().Top*341*8); + DecodeFrame(GetOverscan().Top, 120, ppuOutputBuffer, GetOutputBuffer(), (IsOddFrame() ? 8 : 0) + GetOverscan().Top*341*8, _SMPTE_C); while(!_workDone) {} } @@ -89,7 +90,6 @@ void BisqwitNtscFilter::OnBeforeApplyFilter() NtscFilterSettings ntscSettings = _console->GetSettings()->GetNtscFilterSettings(); _keepVerticalRes = ntscSettings.KeepVerticalResolution; - //_SMPTE_C = ntscSettings.NtscSmpteC; const double pi = std::atan(1.0) * 4; int contrast = (int)((pictureSettings.Contrast + 1.0) * (pictureSettings.Contrast + 1.0) * 167941); @@ -209,7 +209,7 @@ void BisqwitNtscFilter::GenerateNtscSignal(int8_t *ntscSignal, int &phase, int r phase += (341 - 256 - _paddingSize * 2) * _signalsPerPixel; } -void BisqwitNtscFilter::DecodeFrame(int startRow, int endRow, uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, int startPhase) +void BisqwitNtscFilter::DecodeFrame(int startRow, int endRow, uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, int startPhase, bool SMPTE_C) { int pixelsPerCycle = 8 / _resDivider; int phase = startPhase; @@ -229,7 +229,7 @@ void BisqwitNtscFilter::DecodeFrame(int startRow, int endRow, uint16_t *ppuOutpu GenerateNtscSignal(rowSignal, phase, y); //Convert the NTSC signal to RGB - NtscDecodeLine(lineWidth * _signalsPerPixel, rowSignal, outputBuffer, (startCycle + 7) % 12); + NtscDecodeLine(lineWidth * _signalsPerPixel, rowSignal, outputBuffer, (startCycle + 7) % 12, SMPTE_C); outputBuffer += rowPixelGap; } @@ -281,7 +281,7 @@ void BisqwitNtscFilter::DecodeFrame(int startRow, int endRow, uint16_t *ppuOutpu * In essence it conveys in one integer the same information that real NTSC signal * would convey in the colorburst period in the beginning of each scanline. */ -void BisqwitNtscFilter::NtscDecodeLine(int width, const int8_t* signal, uint32_t* target, int phase0) +void BisqwitNtscFilter::NtscDecodeLine(int width, const int8_t* signal, uint32_t* target, int phase0, bool SMPTE_C) { auto Read = [=](int pos) -> char { return pos >= 0 ? signal[pos] : 0; }; auto Cos = [=](int pos) -> char { return _sinetable[(pos + 36) % 12 + phase0]; }; @@ -299,9 +299,9 @@ void BisqwitNtscFilter::NtscDecodeLine(int width, const int8_t* signal, uint32_t qsum += Read(s) * Sin(s) - Read(s - _qWidth) * Sin(s - _qWidth); if(!(s % _resDivider) && s >= leftOverscan) { - int r = std::min(255, std::max(0, (ysum*_y + isum*_irC + qsum*_qrC) / 65536)); - int g = std::min(255, std::max(0, (ysum*_y + isum*_igC + qsum*_qgC) / 65536)); - int b = std::min(255, std::max(0, (ysum*_y + isum*_ibC + qsum*_qbC) / 65536)); + int r = std::min(255, std::max(0, (ysum*_y + isum*(SMPTE_C ? _irC : _ir) + qsum*(SMPTE_C ? _qrC : _qr)) / 65536)); + int g = std::min(255, std::max(0, (ysum*_y + isum*(SMPTE_C ? _igC : _ig) + qsum*(SMPTE_C ? _qgC : _qg)) / 65536)); + int b = std::min(255, std::max(0, (ysum*_y + isum*(SMPTE_C ? _ibC : _ib) + qsum*(SMPTE_C ? _qbC : _qb)) / 65536)); *target = 0xFF000000 | (r << 16) | (g << 8) | b; target++; diff --git a/Core/BisqwitNtscFilter.h b/Core/BisqwitNtscFilter.h index 15c54a854..3890fa9e6 100644 --- a/Core/BisqwitNtscFilter.h +++ b/Core/BisqwitNtscFilter.h @@ -44,14 +44,14 @@ class BisqwitNtscFilter : public BaseVideoFilter void RecursiveBlend(int iterationCount, uint64_t *output, uint64_t *currentLine, uint64_t *nextLine, int pixelsPerCycle, bool verticalBlend); - void NtscDecodeLine(int width, const int8_t* signal, uint32_t* target, int phase0); + void NtscDecodeLine(int width, const int8_t* signal, uint32_t* target, int phase0, bool SMPTE_C); void GenerateNtscSignal(int8_t *ntscSignal, int &phase, int rowNumber); - void DecodeFrame(int startRow, int endRow, uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, int startPhase); + void DecodeFrame(int startRow, int endRow, uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, int startPhase, bool SMPTE_C); void OnBeforeApplyFilter(); public: - BisqwitNtscFilter(shared_ptr console, int resDivider); + BisqwitNtscFilter(shared_ptr console, int resDivider, bool SMPTE_C); virtual ~BisqwitNtscFilter(); virtual void ApplyFilter(uint16_t *ppuOutputBuffer); diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h index e7075c225..e23f399f8 100644 --- a/Core/EmulationSettings.h +++ b/Core/EmulationSettings.h @@ -171,6 +171,9 @@ enum class VideoFilterType Prescale8x = 23, Prescale10x = 24, Raw = 25, + BisqwitNtscSMPTECQuarterRes = 26, + BisqwitNtscSMPTECHalfRes = 27, + BisqwitNtscSMPTEC = 28, HdPack = 999 }; diff --git a/Core/ScaleFilter.cpp b/Core/ScaleFilter.cpp index 70230cbdd..5ff76ccb2 100644 --- a/Core/ScaleFilter.cpp +++ b/Core/ScaleFilter.cpp @@ -107,6 +107,9 @@ shared_ptr ScaleFilter::GetScaleFilter(VideoFilterType filter) case VideoFilterType::BisqwitNtsc: case VideoFilterType::BisqwitNtscHalfRes: case VideoFilterType::BisqwitNtscQuarterRes: + case VideoFilterType::BisqwitNtscSMPTEC: + case VideoFilterType::BisqwitNtscSMPTECHalfRes: + case VideoFilterType::BisqwitNtscSMPTECQuarterRes: case VideoFilterType::NTSC: case VideoFilterType::HdPack: case VideoFilterType::Raw: diff --git a/Core/VideoDecoder.cpp b/Core/VideoDecoder.cpp index ee4a94cb2..de0f5e734 100644 --- a/Core/VideoDecoder.cpp +++ b/Core/VideoDecoder.cpp @@ -70,9 +70,12 @@ void VideoDecoder::UpdateVideoFilter() switch(_videoFilterType) { case VideoFilterType::None: break; case VideoFilterType::NTSC: _videoFilter.reset(new NtscFilter(_console)); break; - case VideoFilterType::BisqwitNtsc: _videoFilter.reset(new BisqwitNtscFilter(_console, 1)); break; - case VideoFilterType::BisqwitNtscHalfRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 2)); break; - case VideoFilterType::BisqwitNtscQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 4)); break; + case VideoFilterType::BisqwitNtsc: _videoFilter.reset(new BisqwitNtscFilter(_console, 1, false)); break; + case VideoFilterType::BisqwitNtscHalfRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 2, false)); break; + case VideoFilterType::BisqwitNtscQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 4, false)); break; + case VideoFilterType::BisqwitNtscSMPTEC: _videoFilter.reset(new BisqwitNtscFilter(_console, 1, true)); break; + case VideoFilterType::BisqwitNtscSMPTECHalfRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 2, true)); break; + case VideoFilterType::BisqwitNtscSMPTECQuarterRes: _videoFilter.reset(new BisqwitNtscFilter(_console, 4, true)); break; case VideoFilterType::Raw: _videoFilter.reset(new RawVideoFilter(_console)); break; default: _scaleFilter = ScaleFilter::GetScaleFilter(_videoFilterType); break; } diff --git a/GUI.NET/Forms/Config/frmVideoConfig.cs b/GUI.NET/Forms/Config/frmVideoConfig.cs index f893e3b20..5ececd30d 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.cs @@ -165,7 +165,12 @@ protected override bool ValidateInput() tlpNtscFilter2.Visible = false; chkMergeFields.Visible = true; grpNtscFilter.Visible = true; - } else if(filter == VideoFilterType.BisqwitNtsc || filter == VideoFilterType.BisqwitNtscHalfRes || filter == VideoFilterType.BisqwitNtscQuarterRes) { + } else if(filter == VideoFilterType.BisqwitNtsc || + filter == VideoFilterType.BisqwitNtscHalfRes || + filter == VideoFilterType.BisqwitNtscQuarterRes || + filter == VideoFilterType.BisqwitNtscSMPTEC || + filter == VideoFilterType.BisqwitNtscSMPTECHalfRes || + filter == VideoFilterType.BisqwitNtscSMPTECQuarterRes) { tlpNtscFilter1.Visible = true; tlpNtscFilter2.Visible = true; chkMergeFields.Visible = false; diff --git a/GUI.NET/Forms/frmMain.Designer.cs b/GUI.NET/Forms/frmMain.Designer.cs index f810490f0..0651ddece 100644 --- a/GUI.NET/Forms/frmMain.Designer.cs +++ b/GUI.NET/Forms/frmMain.Designer.cs @@ -106,6 +106,9 @@ private void InitializeComponent() this.mnuNtscBisqwitQuarterFilter = new System.Windows.Forms.ToolStripMenuItem(); this.mnuNtscBisqwitHalfFilter = new System.Windows.Forms.ToolStripMenuItem(); this.mnuNtscBisqwitFullFilter = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuNtscSMPTECBisqwitQuarterFilter = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuNtscSMPTECBisqwitHalfFilter = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuNtscSMPTECBisqwitFullFilter = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripSeparator(); this.mnuXBRZ2xFilter = new System.Windows.Forms.ToolStripMenuItem(); this.mnuXBRZ3xFilter = new System.Windows.Forms.ToolStripMenuItem(); @@ -831,6 +834,9 @@ private void InitializeComponent() this.mnuNtscBisqwitQuarterFilter, this.mnuNtscBisqwitHalfFilter, this.mnuNtscBisqwitFullFilter, + this.mnuNtscSMPTECBisqwitQuarterFilter, + this.mnuNtscSMPTECBisqwitHalfFilter, + this.mnuNtscSMPTECBisqwitFullFilter, this.toolStripMenuItem15, this.mnuXBRZ2xFilter, this.mnuXBRZ3xFilter, @@ -903,6 +909,27 @@ private void InitializeComponent() this.mnuNtscBisqwitFullFilter.Text = "NTSC 8x (Bisqwit)"; this.mnuNtscBisqwitFullFilter.Click += new System.EventHandler(this.mnuNtscBisqwitFullFilter_Click); // + // mnuNtscSMPTECBisqwitQuarterFilter + // + this.mnuNtscSMPTECBisqwitQuarterFilter.Name = "mnuNtscSMPTECBisqwitQuarterFilter"; + this.mnuNtscSMPTECBisqwitQuarterFilter.Size = new System.Drawing.Size(206, 22); + this.mnuNtscSMPTECBisqwitQuarterFilter.Text = "NTSC SMPTE C 2x (Bisqwit)"; + this.mnuNtscSMPTECBisqwitQuarterFilter.Click += new System.EventHandler(this.mnuNtscSMPTECBisqwitQuarterFilter_Click); + // + // mnuNtscSMPTECBisqwitHalfFilter + // + this.mnuNtscSMPTECBisqwitHalfFilter.Name = "mnuNtscSMPTECBisqwitHalfFilter"; + this.mnuNtscSMPTECBisqwitHalfFilter.Size = new System.Drawing.Size(206, 22); + this.mnuNtscSMPTECBisqwitHalfFilter.Text = "NTSC SMPTE C 4x (Bisqwit)"; + this.mnuNtscSMPTECBisqwitHalfFilter.Click += new System.EventHandler(this.mnuNtscSMPTECBisqwitHalfFilter_Click); + // + // mnuNtscSMPTECBisqwitFullFilter + // + this.mnuNtscSMPTECBisqwitFullFilter.Name = "mnuNtscSMPTECBisqwitFullFilter"; + this.mnuNtscSMPTECBisqwitFullFilter.Size = new System.Drawing.Size(206, 22); + this.mnuNtscSMPTECBisqwitFullFilter.Text = "NTSC SMPTE C 8x (Bisqwit)"; + this.mnuNtscSMPTECBisqwitFullFilter.Click += new System.EventHandler(this.mnuNtscSMPTECBisqwitFullFilter_Click); + // // toolStripMenuItem15 // this.toolStripMenuItem15.Name = "toolStripMenuItem15"; @@ -1977,6 +2004,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem mnuNtscBisqwitHalfFilter; private System.Windows.Forms.ToolStripMenuItem mnuNtscBisqwitFullFilter; private System.Windows.Forms.ToolStripMenuItem mnuNtscBisqwitQuarterFilter; + private System.Windows.Forms.ToolStripMenuItem mnuNtscSMPTECBisqwitHalfFilter; + private System.Windows.Forms.ToolStripMenuItem mnuNtscSMPTECBisqwitFullFilter; + private System.Windows.Forms.ToolStripMenuItem mnuNtscSMPTECBisqwitQuarterFilter; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem22; private System.Windows.Forms.ToolStripMenuItem mnuVideoRecorder; private System.Windows.Forms.ToolStripMenuItem mnuAviRecord; diff --git a/GUI.NET/Forms/frmMain.Options.cs b/GUI.NET/Forms/frmMain.Options.cs index 54bac9194..d9e50843b 100644 --- a/GUI.NET/Forms/frmMain.Options.cs +++ b/GUI.NET/Forms/frmMain.Options.cs @@ -52,6 +52,9 @@ private void UpdateFilterMenu(VideoFilterType filterType) mnuNtscBisqwitFullFilter.Checked = (filterType == VideoFilterType.BisqwitNtsc); mnuNtscBisqwitHalfFilter.Checked = (filterType == VideoFilterType.BisqwitNtscHalfRes); mnuNtscBisqwitQuarterFilter.Checked = (filterType == VideoFilterType.BisqwitNtscQuarterRes); + mnuNtscSMPTECBisqwitFullFilter.Checked = (filterType == VideoFilterType.BisqwitNtscSMPTEC); + mnuNtscSMPTECBisqwitHalfFilter.Checked = (filterType == VideoFilterType.BisqwitNtscSMPTECHalfRes); + mnuNtscSMPTECBisqwitQuarterFilter.Checked = (filterType == VideoFilterType.BisqwitNtscSMPTECQuarterRes); mnuXBRZ2xFilter.Checked = (filterType == VideoFilterType.xBRZ2x); mnuXBRZ3xFilter.Checked = (filterType == VideoFilterType.xBRZ3x); @@ -370,5 +373,20 @@ private void mnuNtscBisqwitQuarterFilter_Click(object sender, EventArgs e) { SetVideoFilter(VideoFilterType.BisqwitNtscQuarterRes); } + + private void mnuNtscSMPTECBisqwitFullFilter_Click(object sender, EventArgs e) + { + SetVideoFilter(VideoFilterType.BisqwitNtscSMPTEC); + } + + private void mnuNtscSMPTECBisqwitHalfFilter_Click(object sender, EventArgs e) + { + SetVideoFilter(VideoFilterType.BisqwitNtscSMPTECHalfRes); + } + + private void mnuNtscSMPTECBisqwitQuarterFilter_Click(object sender, EventArgs e) + { + SetVideoFilter(VideoFilterType.BisqwitNtscSMPTECQuarterRes); + } } } diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index cd19dbf78..785651079 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -1363,6 +1363,9 @@ private void UpdateMenus() mnuNtscBisqwitQuarterFilter.Enabled = !isHdPackLoader; mnuNtscBisqwitHalfFilter.Enabled = !isHdPackLoader; mnuNtscBisqwitFullFilter.Enabled = !isHdPackLoader; + mnuNtscSMPTECBisqwitQuarterFilter.Enabled = !isHdPackLoader; + mnuNtscSMPTECBisqwitHalfFilter.Enabled = !isHdPackLoader; + mnuNtscSMPTECBisqwitFullFilter.Enabled = !isHdPackLoader; } } catch { } } diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 97ee7a012..7044583b9 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -2362,6 +2362,9 @@ public enum VideoFilterType Prescale6x = 22, Prescale8x = 23, Prescale10x = 24, + BisqwitNtscSMPTECQuarterRes = 26, + BisqwitNtscSMPTECHalfRes = 27, + BisqwitNtscSMPTEC = 28, } public enum HDPackOuputTileType