Video Config: Brightness/Contrast/Hue/Saturation/Scanline configuration. + NTSC filter config

This commit is contained in:
Souryo 2016-05-26 22:32:20 -04:00
parent 0cfe0246cf
commit 7b9f3eb1b2
21 changed files with 1044 additions and 59 deletions

View file

@ -36,11 +36,16 @@ OverscanDimensions BaseVideoFilter::GetOverscan()
return _overscan;
}
void BaseVideoFilter::OnBeforeApplyFilter()
{
}
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer)
{
_frameLock.Acquire();
_overscan = EmulationSettings::GetOverscanDimensions();
UpdateBufferSize();
OnBeforeApplyFilter();
ApplyFilter(ppuOutputBuffer);
_frameLock.Release();
}

View file

@ -23,6 +23,7 @@ private:
protected:
OverscanDimensions GetOverscan();
virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0;
virtual void OnBeforeApplyFilter();
public:
BaseVideoFilter();

View file

@ -1,6 +1,37 @@
#include "stdafx.h"
#include "DefaultVideoFilter.h"
#include "EmulationSettings.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
DefaultVideoFilter::DefaultVideoFilter()
{
InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation);
}
void DefaultVideoFilter::InitConversionMatrix(double hueShift, double saturationShift)
{
_pictureSettings.Hue = hueShift;
_pictureSettings.Saturation = saturationShift;
double hue = hueShift * M_PI - 15 * M_PI / 180;
double sat = saturationShift + 1;
double baseValues[6] = { 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
double s = sin(hue) * sat;
double c = cos(hue) * sat;
double *output = _yiqToRgbMatrix;
double *input = baseValues;
for(int n = 0; n < 3; n++) {
double i = *input++;
double q = *input++;
*output++ = i * c - q * s;
*output++ = i * s + q * c;
}
}
FrameInfo DefaultVideoFilter::GetFrameInfo()
{
@ -8,20 +39,55 @@ FrameInfo DefaultVideoFilter::GetFrameInfo()
return { overscan.GetScreenWidth(), overscan.GetScreenHeight(), 4 };
}
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
void DefaultVideoFilter::OnBeforeApplyFilter()
{
PictureSettings currentSettings = EmulationSettings::GetPictureSettings();
if(_pictureSettings.Hue != currentSettings.Hue || _pictureSettings.Saturation != currentSettings.Saturation) {
InitConversionMatrix(currentSettings.Hue, currentSettings.Saturation);
}
_pictureSettings = currentSettings;
_needToProcess = _pictureSettings.Hue != 0 || _pictureSettings.Saturation != 0 || _pictureSettings.Brightness || _pictureSettings.Contrast;
}
void DefaultVideoFilter::DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, bool displayScanlines)
{
OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions();
uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer();
double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity;
for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) {
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
*outputBuffer = ProcessIntensifyBits(ppuOutputBuffer[i * 256 + j]);
outputBuffer++;
if(displayScanlines && (i + overscan.Top) % 2 == 0) {
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
*outputBuffer = ProcessIntensifyBits(ppuOutputBuffer[i * 256 + j], scanlineIntensity);
outputBuffer++;
}
} else {
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
*outputBuffer = ProcessIntensifyBits(ppuOutputBuffer[i * 256 + j]);
outputBuffer++;
}
}
}
}
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel)
void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{
DecodePpuBuffer(ppuOutputBuffer, (uint32_t*)GetOutputBuffer(), true);
}
void DefaultVideoFilter::RgbToYiq(double r, double g, double b, double &y, double &i, double &q)
{
y = r * 0.299f + g * 0.587f + b * 0.114f;
i = r * 0.596f - g * 0.275f - b * 0.321f;
q = r * 0.212f - g * 0.523f + b * 0.311f;
}
void DefaultVideoFilter::YiqToRgb(double y, double i, double q, double &r, double &g, double &b)
{
r = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[0] * i + _yiqToRgbMatrix[1] * q)));
g = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[2] * i + _yiqToRgbMatrix[3] * q)));
b = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[4] * i + _yiqToRgbMatrix[5] * q)));
}
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity)
{
uint32_t pixelOutput = EmulationSettings::GetRgbPalette()[ppuPixel & 0x3F];
@ -49,10 +115,28 @@ uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel)
greenChannel *= 0.9;
}
uint8_t r, g, b;
r = (uint8_t)(redChannel > 255 ? 255 : redChannel);
g = (uint8_t)(greenChannel > 255 ? 255 : greenChannel);
b = (uint8_t)(blueChannel > 255 ? 255 : blueChannel);
redChannel = (float)(redChannel > 255 ? 255 : redChannel) / 255.0;
greenChannel = (float)(greenChannel > 255 ? 255 : greenChannel) / 255.0;
blueChannel = (float)(blueChannel > 255 ? 255 : blueChannel) / 255.0;
//Apply brightness, contrast, hue & saturation
if(_needToProcess) {
double y, i, q;
RgbToYiq(redChannel, greenChannel, blueChannel, y, i, q);
y *= _pictureSettings.Contrast * 0.5f + 1;
y += _pictureSettings.Brightness * 0.5f;
YiqToRgb(y, i, q, redChannel, greenChannel, blueChannel);
}
if(scanlineIntensity < 1.0) {
redChannel *= scanlineIntensity;
greenChannel *= scanlineIntensity;
blueChannel *= scanlineIntensity;
}
int r = std::min(255, (int)(redChannel * 255));
int g = std::min(255, (int)(greenChannel * 255));
int b = std::min(255, (int)(blueChannel * 255));
return 0xFF000000 | (r << 16) | (g << 8) | b;
}

View file

@ -5,10 +5,23 @@
class DefaultVideoFilter : public BaseVideoFilter
{
private:
double _yiqToRgbMatrix[6];
PictureSettings _pictureSettings;
bool _needToProcess = false;
void InitConversionMatrix(double hueShift, double saturationShift);
void RgbToYiq(double r, double g, double b, double &y, double &i, double &q);
void YiqToRgb(double y, double i, double q, double &r, double &g, double &b);
protected:
uint32_t ProcessIntensifyBits(uint16_t ppuPixel);
void DecodePpuBuffer(uint16_t *ppuOutputBuffer, uint32_t* outputBuffer, bool displayScanlines);
uint32_t ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity = 1.0);
void OnBeforeApplyFilter();
public:
DefaultVideoFilter();
void ApplyFilter(uint16_t *ppuOutputBuffer);
FrameInfo GetFrameInfo();
};

View file

@ -31,6 +31,8 @@ VideoFilterType EmulationSettings::_videoFilterType = VideoFilterType::None;
VideoResizeFilter EmulationSettings::_resizeFilter = VideoResizeFilter::NearestNeighbor;
double EmulationSettings::_videoScale = 1;
VideoAspectRatio EmulationSettings::_aspectRatio = VideoAspectRatio::Auto;
PictureSettings EmulationSettings::_pictureSettings;
NtscFilterSettings EmulationSettings::_ntscFilterSettings;
ConsoleType EmulationSettings::_consoleType = ConsoleType::Nes;
ExpansionPortDevice EmulationSettings::_expansionDevice = ExpansionPortDevice::None;

View file

@ -111,6 +111,26 @@ struct OverscanDimensions
}
};
struct PictureSettings
{
double Brightness = 0;
double Contrast = 0;
double Saturation = 0;
double Hue = 0;
double ScanlineIntensity = 0;
};
struct NtscFilterSettings
{
double Sharpness = 0;
double Gamma = 0;
double Resolution = 0;
double Artifacts = 0;
double Fringing = 0;
double Bleed = 0;
bool MergeFields = false;
};
enum class ConsoleType
{
Nes = 0,
@ -226,6 +246,8 @@ private:
static double _videoScale;
static VideoAspectRatio _aspectRatio;
static VideoResizeFilter _resizeFilter;
static PictureSettings _pictureSettings;
static NtscFilterSettings _ntscFilterSettings;
static ConsoleType _consoleType;
static ExpansionPortDevice _expansionDevice;
@ -441,6 +463,37 @@ public:
return _aspectRatio;
}
static void SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity)
{
_pictureSettings.Brightness = brightness;
_pictureSettings.Contrast = contrast;
_pictureSettings.Saturation = saturation;
_pictureSettings.Hue = hue;
_pictureSettings.ScanlineIntensity = scanlineIntensity;
}
static PictureSettings GetPictureSettings()
{
return _pictureSettings;
}
static void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields)
{
_ntscFilterSettings.Artifacts = artifacts;
_ntscFilterSettings.Bleed = bleed;
_ntscFilterSettings.Fringing = fringing;
_ntscFilterSettings.Gamma = gamma;
_ntscFilterSettings.Resolution = resolution;
_ntscFilterSettings.Sharpness = sharpness;
_ntscFilterSettings.MergeFields = mergeFields;
}
static NtscFilterSettings GetNtscFilterSettings()
{
return _ntscFilterSettings;
}
static double GetAspectRatio()
{
switch(_aspectRatio) {

View file

@ -18,6 +18,32 @@ FrameInfo NtscFilter::GetFrameInfo()
return { NES_NTSC_OUT_WIDTH(PPU::ScreenWidth) - overscanLeft - overscanRight, (PPU::ScreenHeight - overscan.Top - overscan.Bottom) * 2, 4 };
}
void NtscFilter::OnBeforeApplyFilter()
{
PictureSettings pictureSettings = EmulationSettings::GetPictureSettings();
NtscFilterSettings ntscSettings = EmulationSettings::GetNtscFilterSettings();
if(_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) {
_ntscData = new nes_ntsc_t();
_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 = (int)ntscSettings.MergeFields;
_ntscSetup.resolution = ntscSettings.Resolution;
_ntscSetup.sharpness = ntscSettings.Sharpness;
nes_ntsc_init(_ntscData, &_ntscSetup);
}
}
void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{
static bool oddFrame = false;
@ -38,6 +64,8 @@ void NtscFilter::DoubleOutputHeight(uint32_t *ntscBuffer)
int rowWidth = NES_NTSC_OUT_WIDTH(PPU::ScreenWidth);
int rowWidthOverscan = rowWidth - overscanLeft - overscanRight;
double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity;
for(int y = PPU::ScreenHeight - 1 - overscan.Bottom; y >= (int)overscan.Top; y--) {
uint32_t const* in = ntscBuffer + y * rowWidth;
uint32_t* out = outputBuffer + (y - overscan.Top) * 2 * rowWidthOverscan;
@ -46,11 +74,20 @@ void NtscFilter::DoubleOutputHeight(uint32_t *ntscBuffer)
uint32_t prev = in[overscanLeft];
uint32_t next = y < 239 ? in[overscanLeft + rowWidth] : 0;
/* mix 24-bit rgb without losing low bits */
uint64_t mixed = prev + next + ((prev ^ next) & 0x030303);
/* darken color */
*out = prev;
*(out + rowWidthOverscan) = (uint32_t)((mixed >> 1) - (mixed >> 4 & 0x0F0F0F));
/* mix 24-bit rgb without losing low bits */
uint32_t mixed = (prev + next + ((prev ^ next) & 0x030303)) >> 1;
if(scanlineIntensity < 1.0) {
uint8_t r = (mixed >> 16) & 0xFF, g = (mixed >> 8) & 0xFF, b = mixed & 0xFF;
r = (uint8_t)(r * scanlineIntensity);
g = (uint8_t)(g * scanlineIntensity);
b = (uint8_t)(b * scanlineIntensity);
*(out + rowWidthOverscan) = (r << 16) | (g << 8) | b;
} else {
*(out + rowWidthOverscan) = mixed;
}
in++;
out++;
}

View file

@ -11,6 +11,9 @@ private:
void DoubleOutputHeight(uint32_t *outputBuffer);
protected:
void OnBeforeApplyFilter();
public:
NtscFilter();
virtual ~NtscFilter();

View file

@ -33,34 +33,42 @@ FrameInfo ScaleFilter::GetFrameInfo()
void ScaleFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{
DecodePpuBuffer(ppuOutputBuffer, _decodedPpuBuffer, false);
OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions();
uint32_t* outputBuffer = _decodedPpuBuffer;
for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) {
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
*outputBuffer = ProcessIntensifyBits(ppuOutputBuffer[i * 256 + j]);
outputBuffer++;
}
}
uint32_t height = overscan.GetScreenHeight();
uint32_t width = overscan.GetScreenWidth();
uint32_t* outputBuffer = (uint32_t*)GetOutputBuffer();
if(_scaleFilterType == ScaleFilterType::xBRZ) {
xbrz::scale(_filterScale, _decodedPpuBuffer, (uint32_t*)GetOutputBuffer(), width, height, xbrz::ColorFormat::ARGB);
xbrz::scale(_filterScale, _decodedPpuBuffer, outputBuffer, width, height, xbrz::ColorFormat::ARGB);
} else if(_scaleFilterType == ScaleFilterType::HQX) {
switch(_filterScale) {
case 2: hq2x_32(_decodedPpuBuffer, (uint32_t*)GetOutputBuffer(), width, height); break;
case 3: hq3x_32(_decodedPpuBuffer, (uint32_t*)GetOutputBuffer(), width, height); break;
case 4: hq4x_32(_decodedPpuBuffer, (uint32_t*)GetOutputBuffer(), width, height); break;
case 2: hq2x_32(_decodedPpuBuffer, outputBuffer, width, height); break;
case 3: hq3x_32(_decodedPpuBuffer, outputBuffer, width, height); break;
case 4: hq4x_32(_decodedPpuBuffer, outputBuffer, width, height); break;
}
} else if(_scaleFilterType == ScaleFilterType::Scale2x) {
scale(_filterScale, GetOutputBuffer(), width*sizeof(uint32_t)*_filterScale, _decodedPpuBuffer, width*sizeof(uint32_t), 4, width, height);
scale(_filterScale, outputBuffer, width*sizeof(uint32_t)*_filterScale, _decodedPpuBuffer, width*sizeof(uint32_t), 4, width, height);
} else if(_scaleFilterType == ScaleFilterType::_2xSai) {
twoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, (uint32_t*)GetOutputBuffer(), width * _filterScale);
twoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::Super2xSai) {
supertwoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, (uint32_t*)GetOutputBuffer(), width * _filterScale);
supertwoxsai_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale);
} else if(_scaleFilterType == ScaleFilterType::SuperEagle) {
supereagle_generic_xrgb8888(width, height, _decodedPpuBuffer, width, (uint32_t*)GetOutputBuffer(), width * _filterScale);
supereagle_generic_xrgb8888(width, height, _decodedPpuBuffer, width, outputBuffer, width * _filterScale);
}
double scanlineIntensity = 1.0 - EmulationSettings::GetPictureSettings().ScanlineIntensity;
if(scanlineIntensity < 1.0) {
for(int y = 1, yMax = height * _filterScale; y < yMax; y += 2) {
for(int x = 0, xMax = width * _filterScale; x < xMax; x++) {
uint32_t &color = outputBuffer[y*xMax + x];
uint8_t r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF;
r = (uint8_t)(r * scanlineIntensity);
g = (uint8_t)(g * scanlineIntensity);
b = (uint8_t)(b * scanlineIntensity);
color = (r << 16) | (g << 8) | b;
}
}
}
}

View file

@ -25,6 +25,20 @@ namespace Mesen.GUI.Config
public bool UseHdPacks = false;
public Int32[] Palette = new Int32[0];
public Int32 Brightness = 0;
public Int32 Contrast = 0;
public Int32 Hue = 0;
public Int32 Saturation = 0;
public Int32 ScanlineIntensity = 0;
public Int32 NtscArtifacts = 0;
public Int32 NtscBleed = 0;
public Int32 NtscFringing = 0;
public Int32 NtscGamma = 0;
public Int32 NtscResolution = 0;
public Int32 NtscSharpness = 0;
public bool NtscMergeFields = false;
public VideoInfo()
{
}
@ -46,6 +60,9 @@ namespace Mesen.GUI.Config
InteropEmu.SetVideoScale(videoInfo.VideoScale);
InteropEmu.SetVideoAspectRatio(videoInfo.AspectRatio);
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);
if(videoInfo.Palette.Length == 64) {
InteropEmu.SetRgbPalette(videoInfo.Palette);
}

View file

@ -0,0 +1,121 @@
namespace Mesen.GUI.Controls
{
partial class ctrlHorizontalTrackbar
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.trackBar = new System.Windows.Forms.TrackBar();
this.txtValue = new System.Windows.Forms.TextBox();
this.lblText = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.trackBar, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.txtValue, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.lblText, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(206, 55);
this.tableLayoutPanel1.TabIndex = 0;
//
// trackBar
//
this.trackBar.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.trackBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.trackBar.Location = new System.Drawing.Point(0, 20);
this.trackBar.Margin = new System.Windows.Forms.Padding(0);
this.trackBar.Maximum = 100;
this.trackBar.Minimum = -100;
this.trackBar.Name = "trackBar";
this.trackBar.Size = new System.Drawing.Size(172, 35);
this.trackBar.TabIndex = 13;
this.trackBar.TickFrequency = 10;
this.trackBar.Value = 50;
this.trackBar.ValueChanged += new System.EventHandler(this.trackBar_ValueChanged);
//
// txtValue
//
this.txtValue.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.txtValue.BackColor = System.Drawing.Color.White;
this.txtValue.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtValue.Location = new System.Drawing.Point(175, 23);
this.txtValue.Multiline = true;
this.txtValue.Name = "txtValue";
this.txtValue.ReadOnly = true;
this.txtValue.Size = new System.Drawing.Size(28, 17);
this.txtValue.TabIndex = 17;
this.txtValue.TabStop = false;
this.txtValue.Text = "100";
this.txtValue.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// lblText
//
this.lblText.AutoSize = true;
this.lblText.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblText.Location = new System.Drawing.Point(3, 0);
this.lblText.Name = "lblText";
this.lblText.Size = new System.Drawing.Size(166, 20);
this.lblText.TabIndex = 18;
this.lblText.Text = "Text";
this.lblText.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// ctrlHorizontalTrackbar
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Margin = new System.Windows.Forms.Padding(0);
this.MaximumSize = new System.Drawing.Size(400, 55);
this.MinimumSize = new System.Drawing.Size(206, 55);
this.Name = "ctrlHorizontalTrackbar";
this.Size = new System.Drawing.Size(206, 55);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.TrackBar trackBar;
private System.Windows.Forms.TextBox txtValue;
private System.Windows.Forms.Label lblText;
}
}

View file

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Controls
{
public partial class ctrlHorizontalTrackbar : UserControl
{
public event EventHandler ValueChanged
{
add { trackBar.ValueChanged += value; }
remove { trackBar.ValueChanged -= value; }
}
public ctrlHorizontalTrackbar()
{
InitializeComponent();
}
public int Maximum
{
get { return trackBar.Maximum; }
set { trackBar.Maximum = value; }
}
public int Minimum
{
get { return trackBar.Minimum; }
set { trackBar.Minimum = value; }
}
[Bindable(true)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[EditorBrowsable(EditorBrowsableState.Always)]
public override string Text
{
get { return lblText.Text; }
set { lblText.Text = value; }
}
public int Value
{
get { return trackBar.Value; }
set
{
trackBar.Value = value;
txtValue.Text = trackBar.Value.ToString();
}
}
private void trackBar_ValueChanged(object sender, EventArgs e)
{
txtValue.Text = trackBar.Value.ToString();
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -173,6 +173,23 @@
<Control ID="tpgPalette">Palette</Control>
<Control ID="btnResetPalette">Réinitialiser</Control>
<Control ID="btnLoadPalFile">Charger fichier .pal</Control>
<Control ID="tpgPicture">Image</Control>
<Control ID="grpCommon">Paramètres communs</Control>
<Control ID="trkBrightness">Luminosité</Control>
<Control ID="trkContrast">Contraste</Control>
<Control ID="trkHue">Teinte</Control>
<Control ID="trkSaturation">Saturation</Control>
<Control ID="grpNtscFilter">Paramètres du filtre NTSC</Control>
<Control ID="trkArtifacts">Artefact</Control>
<Control ID="trkBleed">Dispersion des couleurs</Control>
<Control ID="trkFringing">Franges de distorsion</Control>
<Control ID="trkGamma">Gamma</Control>
<Control ID="trkResolution">Résolution</Control>
<Control ID="trkSharpness">Piqué</Control>
<Control ID="chkMergeFields">Combiner les images alternées</Control>
<Control ID="grpScanlines">Lignes de balayage</Control>
<Control ID="trkScanlines">Lignes de balayage</Control>
<Control ID="btnResetPictureSettings">Réinitialiser</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Annuler</Control>
</Form>

View file

@ -173,6 +173,23 @@
<Control ID="tpgPalette">パレット</Control>
<Control ID="btnResetPalette">リセット</Control>
<Control ID="btnLoadPalFile">.palファイルをロードする</Control>
<Control ID="tpgPicture">画像</Control>
<Control ID="grpCommon">共通設定</Control>
<Control ID="trkBrightness">明るさ</Control>
<Control ID="trkContrast">コントラスト</Control>
<Control ID="trkHue">色相</Control>
<Control ID="trkSaturation">彩度</Control>
<Control ID="grpNtscFilter">NTSCエフェクトの設定</Control>
<Control ID="trkArtifacts">アーティファクト</Control>
<Control ID="trkBleed">色にじみ</Control>
<Control ID="trkFringing">フリンジ</Control>
<Control ID="trkGamma">ガンマ</Control>
<Control ID="trkResolution">解像度</Control>
<Control ID="trkSharpness">シャープネス</Control>
<Control ID="chkMergeFields">画像をマージする</Control>
<Control ID="grpScanlines">走査線</Control>
<Control ID="trkScanlines">走査線</Control>
<Control ID="btnResetPictureSettings">リセット</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">キャンセル</Control>
</Form>

View file

@ -175,8 +175,14 @@ namespace Mesen.GUI.Forms
}
} else if(kvp.Value is ctrlTrackbar) {
((ctrlTrackbar)kvp.Value).Value = (int)(uint)value;
} else if(kvp.Value is ctrlHorizontalTrackbar) {
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)value;
} else if(kvp.Value is TrackBar) {
((TrackBar)kvp.Value).Value = (int)(uint)value;
if(field.FieldType == typeof(Int32)) {
((TrackBar)kvp.Value).Value = (int)value;
} else {
((TrackBar)kvp.Value).Value = (int)(uint)value;
}
} else if(kvp.Value is NumericUpDown) {
NumericUpDown nud = kvp.Value as NumericUpDown;
decimal val;
@ -248,8 +254,14 @@ namespace Mesen.GUI.Forms
field.SetValue(Entity, kvp.Value.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
} else if(kvp.Value is ctrlTrackbar) {
field.SetValue(Entity, (UInt32)((ctrlTrackbar)kvp.Value).Value);
} else if(kvp.Value is ctrlHorizontalTrackbar) {
field.SetValue(Entity, (Int32)((ctrlHorizontalTrackbar)kvp.Value).Value);
} else if(kvp.Value is TrackBar) {
field.SetValue(Entity, (UInt32)((TrackBar)kvp.Value).Value);
if(field.FieldType == typeof(Int32)) {
field.SetValue(Entity, ((TrackBar)kvp.Value).Value);
} else {
field.SetValue(Entity, (UInt32)((TrackBar)kvp.Value).Value);
}
} else if(kvp.Value is NumericUpDown) {
if(field.FieldType == typeof(UInt32)) {
field.SetValue(Entity, (UInt32)((NumericUpDown)kvp.Value).Value);

View file

@ -43,6 +43,7 @@
this.picHdNesTooltip = new System.Windows.Forms.PictureBox();
this.nudScale = new System.Windows.Forms.NumericUpDown();
this.cboFilter = new System.Windows.Forms.ComboBox();
this.chkBilinearInterpolation = new System.Windows.Forms.CheckBox();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tpgOverscan = new System.Windows.Forms.TabPage();
@ -61,6 +62,26 @@
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.lblRight = new System.Windows.Forms.Label();
this.nudOverscanRight = new System.Windows.Forms.NumericUpDown();
this.tpgPicture = new System.Windows.Forms.TabPage();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.btnResetPictureSettings = new System.Windows.Forms.Button();
this.grpNtscFilter = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
this.trkArtifacts = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkBleed = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkFringing = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkGamma = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkResolution = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkSharpness = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.chkMergeFields = new System.Windows.Forms.CheckBox();
this.grpCommon = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.trkBrightness = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkContrast = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkHue = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkSaturation = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.grpScanlines = new System.Windows.Forms.GroupBox();
this.trkScanlines = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.tpgPalette = new System.Windows.Forms.TabPage();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.picPalette = new System.Windows.Forms.PictureBox();
@ -68,7 +89,6 @@
this.btnResetPalette = new System.Windows.Forms.Button();
this.btnLoadPalFile = new System.Windows.Forms.Button();
this.colorDialog = new System.Windows.Forms.ColorDialog();
this.chkBilinearInterpolation = new System.Windows.Forms.CheckBox();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel6.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).BeginInit();
@ -89,6 +109,13 @@
((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).BeginInit();
this.flowLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).BeginInit();
this.tpgPicture.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
this.grpNtscFilter.SuspendLayout();
this.tableLayoutPanel6.SuspendLayout();
this.grpCommon.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.grpScanlines.SuspendLayout();
this.tpgPalette.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picPalette)).BeginInit();
@ -97,7 +124,7 @@
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 368);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 376);
this.baseConfigPanel.Size = new System.Drawing.Size(515, 29);
//
// tlpMain
@ -131,7 +158,7 @@
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.Size = new System.Drawing.Size(501, 336);
this.tlpMain.Size = new System.Drawing.Size(501, 344);
this.tlpMain.TabIndex = 1;
//
// lblVideoScale
@ -304,16 +331,29 @@
this.cboFilter.Size = new System.Drawing.Size(76, 21);
this.cboFilter.TabIndex = 14;
//
// chkBilinearInterpolation
//
this.chkBilinearInterpolation.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkBilinearInterpolation.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkBilinearInterpolation, 2);
this.chkBilinearInterpolation.Location = new System.Drawing.Point(3, 83);
this.chkBilinearInterpolation.Name = "chkBilinearInterpolation";
this.chkBilinearInterpolation.Size = new System.Drawing.Size(206, 17);
this.chkBilinearInterpolation.TabIndex = 22;
this.chkBilinearInterpolation.Text = "Use bilinear interpolation when scaling";
this.chkBilinearInterpolation.UseVisualStyleBackColor = true;
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgGeneral);
this.tabMain.Controls.Add(this.tpgOverscan);
this.tabMain.Controls.Add(this.tpgPicture);
this.tabMain.Controls.Add(this.tpgPalette);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(515, 368);
this.tabMain.Size = new System.Drawing.Size(515, 376);
this.tabMain.TabIndex = 2;
//
// tpgGeneral
@ -322,7 +362,7 @@
this.tpgGeneral.Location = new System.Drawing.Point(4, 22);
this.tpgGeneral.Name = "tpgGeneral";
this.tpgGeneral.Padding = new System.Windows.Forms.Padding(3);
this.tpgGeneral.Size = new System.Drawing.Size(507, 342);
this.tpgGeneral.Size = new System.Drawing.Size(507, 350);
this.tpgGeneral.TabIndex = 0;
this.tpgGeneral.Text = "General";
this.tpgGeneral.UseVisualStyleBackColor = true;
@ -333,7 +373,7 @@
this.tpgOverscan.Location = new System.Drawing.Point(4, 22);
this.tpgOverscan.Name = "tpgOverscan";
this.tpgOverscan.Padding = new System.Windows.Forms.Padding(3);
this.tpgOverscan.Size = new System.Drawing.Size(507, 342);
this.tpgOverscan.Size = new System.Drawing.Size(507, 350);
this.tpgOverscan.TabIndex = 1;
this.tpgOverscan.Text = "Overscan";
this.tpgOverscan.UseVisualStyleBackColor = true;
@ -344,7 +384,7 @@
this.grpCropping.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCropping.Location = new System.Drawing.Point(3, 3);
this.grpCropping.Name = "grpCropping";
this.grpCropping.Size = new System.Drawing.Size(501, 336);
this.grpCropping.Size = new System.Drawing.Size(501, 344);
this.grpCropping.TabIndex = 8;
this.grpCropping.TabStop = false;
this.grpCropping.Text = "Video Cropping";
@ -361,7 +401,7 @@
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel4, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel5, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 2, 1);
this.tableLayoutPanel1.Location = new System.Drawing.Point(65, 8);
this.tableLayoutPanel1.Location = new System.Drawing.Point(65, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
@ -504,13 +544,315 @@
this.nudOverscanRight.TabIndex = 1;
this.nudOverscanRight.ValueChanged += new System.EventHandler(this.nudOverscan_ValueChanged);
//
// tpgPicture
//
this.tpgPicture.Controls.Add(this.tableLayoutPanel5);
this.tpgPicture.Location = new System.Drawing.Point(4, 22);
this.tpgPicture.Name = "tpgPicture";
this.tpgPicture.Padding = new System.Windows.Forms.Padding(3);
this.tpgPicture.Size = new System.Drawing.Size(507, 350);
this.tpgPicture.TabIndex = 3;
this.tpgPicture.Text = "Picture";
this.tpgPicture.UseVisualStyleBackColor = true;
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 2;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.Controls.Add(this.btnResetPictureSettings, 0, 2);
this.tableLayoutPanel5.Controls.Add(this.grpNtscFilter, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.grpCommon, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.grpScanlines, 0, 1);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 3;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(501, 344);
this.tableLayoutPanel5.TabIndex = 5;
//
// btnResetPictureSettings
//
this.btnResetPictureSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnResetPictureSettings.AutoSize = true;
this.btnResetPictureSettings.Location = new System.Drawing.Point(3, 318);
this.btnResetPictureSettings.Name = "btnResetPictureSettings";
this.btnResetPictureSettings.Size = new System.Drawing.Size(75, 23);
this.btnResetPictureSettings.TabIndex = 3;
this.btnResetPictureSettings.Text = "Reset";
this.btnResetPictureSettings.UseVisualStyleBackColor = true;
this.btnResetPictureSettings.Click += new System.EventHandler(this.btnResetPictureSettings_Click);
//
// grpNtscFilter
//
this.grpNtscFilter.Controls.Add(this.tableLayoutPanel6);
this.grpNtscFilter.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpNtscFilter.Location = new System.Drawing.Point(252, 0);
this.grpNtscFilter.Margin = new System.Windows.Forms.Padding(2, 0, 0, 0);
this.grpNtscFilter.Name = "grpNtscFilter";
this.tableLayoutPanel5.SetRowSpan(this.grpNtscFilter, 3);
this.grpNtscFilter.Size = new System.Drawing.Size(249, 344);
this.grpNtscFilter.TabIndex = 4;
this.grpNtscFilter.TabStop = false;
this.grpNtscFilter.Text = "NTSC Filter";
//
// tableLayoutPanel6
//
this.tableLayoutPanel6.ColumnCount = 1;
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel6.Controls.Add(this.trkArtifacts, 0, 0);
this.tableLayoutPanel6.Controls.Add(this.trkBleed, 0, 1);
this.tableLayoutPanel6.Controls.Add(this.trkFringing, 0, 2);
this.tableLayoutPanel6.Controls.Add(this.trkGamma, 0, 3);
this.tableLayoutPanel6.Controls.Add(this.trkResolution, 0, 4);
this.tableLayoutPanel6.Controls.Add(this.trkSharpness, 0, 5);
this.tableLayoutPanel6.Controls.Add(this.chkMergeFields, 0, 6);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel6.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 7;
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel6.Size = new System.Drawing.Size(243, 325);
this.tableLayoutPanel6.TabIndex = 5;
//
// trkArtifacts
//
this.trkArtifacts.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkArtifacts.Location = new System.Drawing.Point(0, 0);
this.trkArtifacts.Margin = new System.Windows.Forms.Padding(0);
this.trkArtifacts.Maximum = 100;
this.trkArtifacts.MaximumSize = new System.Drawing.Size(0, 60);
this.trkArtifacts.Minimum = -100;
this.trkArtifacts.MinimumSize = new System.Drawing.Size(206, 50);
this.trkArtifacts.Name = "trkArtifacts";
this.trkArtifacts.Size = new System.Drawing.Size(243, 50);
this.trkArtifacts.TabIndex = 24;
this.trkArtifacts.Text = "Artifacts";
this.trkArtifacts.Value = 0;
//
// trkBleed
//
this.trkBleed.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBleed.Location = new System.Drawing.Point(0, 50);
this.trkBleed.Margin = new System.Windows.Forms.Padding(0);
this.trkBleed.Maximum = 100;
this.trkBleed.MaximumSize = new System.Drawing.Size(400, 55);
this.trkBleed.Minimum = -100;
this.trkBleed.MinimumSize = new System.Drawing.Size(206, 50);
this.trkBleed.Name = "trkBleed";
this.trkBleed.Size = new System.Drawing.Size(243, 50);
this.trkBleed.TabIndex = 25;
this.trkBleed.Text = "Bleed";
this.trkBleed.Value = 0;
//
// trkFringing
//
this.trkFringing.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkFringing.Location = new System.Drawing.Point(0, 100);
this.trkFringing.Margin = new System.Windows.Forms.Padding(0);
this.trkFringing.Maximum = 100;
this.trkFringing.MaximumSize = new System.Drawing.Size(0, 41);
this.trkFringing.Minimum = -100;
this.trkFringing.MinimumSize = new System.Drawing.Size(206, 50);
this.trkFringing.Name = "trkFringing";
this.trkFringing.Size = new System.Drawing.Size(243, 50);
this.trkFringing.TabIndex = 26;
this.trkFringing.Text = "Fringing";
this.trkFringing.Value = 0;
//
// trkGamma
//
this.trkGamma.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkGamma.Location = new System.Drawing.Point(0, 150);
this.trkGamma.Margin = new System.Windows.Forms.Padding(0);
this.trkGamma.Maximum = 100;
this.trkGamma.MaximumSize = new System.Drawing.Size(0, 41);
this.trkGamma.Minimum = -100;
this.trkGamma.MinimumSize = new System.Drawing.Size(206, 50);
this.trkGamma.Name = "trkGamma";
this.trkGamma.Size = new System.Drawing.Size(243, 50);
this.trkGamma.TabIndex = 27;
this.trkGamma.Text = "Gamma";
this.trkGamma.Value = 0;
//
// trkResolution
//
this.trkResolution.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkResolution.Location = new System.Drawing.Point(0, 200);
this.trkResolution.Margin = new System.Windows.Forms.Padding(0);
this.trkResolution.Maximum = 100;
this.trkResolution.MaximumSize = new System.Drawing.Size(0, 41);
this.trkResolution.Minimum = -100;
this.trkResolution.MinimumSize = new System.Drawing.Size(206, 50);
this.trkResolution.Name = "trkResolution";
this.trkResolution.Size = new System.Drawing.Size(243, 50);
this.trkResolution.TabIndex = 28;
this.trkResolution.Text = "Resolution";
this.trkResolution.Value = 0;
//
// trkSharpness
//
this.trkSharpness.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkSharpness.Location = new System.Drawing.Point(0, 250);
this.trkSharpness.Margin = new System.Windows.Forms.Padding(0);
this.trkSharpness.Maximum = 100;
this.trkSharpness.MaximumSize = new System.Drawing.Size(0, 41);
this.trkSharpness.Minimum = -100;
this.trkSharpness.MinimumSize = new System.Drawing.Size(206, 50);
this.trkSharpness.Name = "trkSharpness";
this.trkSharpness.Size = new System.Drawing.Size(243, 50);
this.trkSharpness.TabIndex = 29;
this.trkSharpness.Text = "Sharpness";
this.trkSharpness.Value = 0;
//
// chkMergeFields
//
this.chkMergeFields.AutoSize = true;
this.chkMergeFields.Location = new System.Drawing.Point(3, 303);
this.chkMergeFields.Name = "chkMergeFields";
this.chkMergeFields.Size = new System.Drawing.Size(86, 17);
this.chkMergeFields.TabIndex = 30;
this.chkMergeFields.Text = "Merge Fields";
this.chkMergeFields.UseVisualStyleBackColor = true;
//
// grpCommon
//
this.grpCommon.Controls.Add(this.tableLayoutPanel4);
this.grpCommon.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCommon.Location = new System.Drawing.Point(0, 0);
this.grpCommon.Margin = new System.Windows.Forms.Padding(0, 0, 2, 0);
this.grpCommon.Name = "grpCommon";
this.grpCommon.Size = new System.Drawing.Size(248, 217);
this.grpCommon.TabIndex = 3;
this.grpCommon.TabStop = false;
this.grpCommon.Text = "Common Settings";
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 1;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel4.Controls.Add(this.trkBrightness, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.trkContrast, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.trkHue, 0, 2);
this.tableLayoutPanel4.Controls.Add(this.trkSaturation, 0, 3);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 5;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(242, 198);
this.tableLayoutPanel4.TabIndex = 4;
//
// trkBrightness
//
this.trkBrightness.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBrightness.Location = new System.Drawing.Point(0, 0);
this.trkBrightness.Margin = new System.Windows.Forms.Padding(0);
this.trkBrightness.Maximum = 100;
this.trkBrightness.MaximumSize = new System.Drawing.Size(0, 60);
this.trkBrightness.Minimum = -100;
this.trkBrightness.MinimumSize = new System.Drawing.Size(206, 50);
this.trkBrightness.Name = "trkBrightness";
this.trkBrightness.Size = new System.Drawing.Size(242, 50);
this.trkBrightness.TabIndex = 24;
this.trkBrightness.Text = "Brightness";
this.trkBrightness.Value = 0;
//
// trkContrast
//
this.trkContrast.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkContrast.Location = new System.Drawing.Point(0, 50);
this.trkContrast.Margin = new System.Windows.Forms.Padding(0);
this.trkContrast.Maximum = 100;
this.trkContrast.MaximumSize = new System.Drawing.Size(400, 55);
this.trkContrast.Minimum = -100;
this.trkContrast.MinimumSize = new System.Drawing.Size(206, 50);
this.trkContrast.Name = "trkContrast";
this.trkContrast.Size = new System.Drawing.Size(242, 50);
this.trkContrast.TabIndex = 25;
this.trkContrast.Text = "Contrast";
this.trkContrast.Value = 0;
//
// trkHue
//
this.trkHue.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkHue.Location = new System.Drawing.Point(0, 100);
this.trkHue.Margin = new System.Windows.Forms.Padding(0);
this.trkHue.Maximum = 100;
this.trkHue.MaximumSize = new System.Drawing.Size(0, 41);
this.trkHue.Minimum = -100;
this.trkHue.MinimumSize = new System.Drawing.Size(206, 50);
this.trkHue.Name = "trkHue";
this.trkHue.Size = new System.Drawing.Size(242, 50);
this.trkHue.TabIndex = 26;
this.trkHue.Text = "Hue";
this.trkHue.Value = 0;
//
// trkSaturation
//
this.trkSaturation.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkSaturation.Location = new System.Drawing.Point(0, 150);
this.trkSaturation.Margin = new System.Windows.Forms.Padding(0);
this.trkSaturation.Maximum = 100;
this.trkSaturation.MaximumSize = new System.Drawing.Size(0, 41);
this.trkSaturation.Minimum = -100;
this.trkSaturation.MinimumSize = new System.Drawing.Size(206, 50);
this.trkSaturation.Name = "trkSaturation";
this.trkSaturation.Size = new System.Drawing.Size(242, 50);
this.trkSaturation.TabIndex = 27;
this.trkSaturation.Text = "Saturation";
this.trkSaturation.Value = 0;
//
// grpScanlines
//
this.grpScanlines.Controls.Add(this.trkScanlines);
this.grpScanlines.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpScanlines.Location = new System.Drawing.Point(3, 220);
this.grpScanlines.Name = "grpScanlines";
this.grpScanlines.Size = new System.Drawing.Size(244, 72);
this.grpScanlines.TabIndex = 5;
this.grpScanlines.TabStop = false;
this.grpScanlines.Text = "Scanlines";
//
// trkScanlines
//
this.trkScanlines.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkScanlines.Location = new System.Drawing.Point(3, 16);
this.trkScanlines.Margin = new System.Windows.Forms.Padding(0);
this.trkScanlines.Maximum = 100;
this.trkScanlines.MaximumSize = new System.Drawing.Size(0, 41);
this.trkScanlines.Minimum = 0;
this.trkScanlines.MinimumSize = new System.Drawing.Size(206, 50);
this.trkScanlines.Name = "trkScanlines";
this.trkScanlines.Size = new System.Drawing.Size(238, 50);
this.trkScanlines.TabIndex = 28;
this.trkScanlines.Text = "Scanlines";
this.trkScanlines.Value = 0;
//
// tpgPalette
//
this.tpgPalette.Controls.Add(this.tableLayoutPanel3);
this.tpgPalette.Location = new System.Drawing.Point(4, 22);
this.tpgPalette.Name = "tpgPalette";
this.tpgPalette.Padding = new System.Windows.Forms.Padding(3);
this.tpgPalette.Size = new System.Drawing.Size(507, 342);
this.tpgPalette.Size = new System.Drawing.Size(507, 350);
this.tpgPalette.TabIndex = 2;
this.tpgPalette.Text = "Palette";
this.tpgPalette.UseVisualStyleBackColor = true;
@ -529,7 +871,7 @@
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.Size = new System.Drawing.Size(501, 336);
this.tableLayoutPanel3.Size = new System.Drawing.Size(501, 344);
this.tableLayoutPanel3.TabIndex = 4;
//
// picPalette
@ -584,23 +926,11 @@
this.btnLoadPalFile.UseVisualStyleBackColor = true;
this.btnLoadPalFile.Click += new System.EventHandler(this.btnLoadPalFile_Click);
//
// chkBilinearInterpolation
//
this.chkBilinearInterpolation.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkBilinearInterpolation.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkBilinearInterpolation, 2);
this.chkBilinearInterpolation.Location = new System.Drawing.Point(3, 83);
this.chkBilinearInterpolation.Name = "chkBilinearInterpolation";
this.chkBilinearInterpolation.Size = new System.Drawing.Size(206, 17);
this.chkBilinearInterpolation.TabIndex = 22;
this.chkBilinearInterpolation.Text = "Use bilinear interpolation when scaling";
this.chkBilinearInterpolation.UseVisualStyleBackColor = true;
//
// frmVideoConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(515, 397);
this.ClientSize = new System.Drawing.Size(515, 405);
this.Controls.Add(this.tabMain);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -637,6 +967,15 @@
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).EndInit();
this.tpgPicture.ResumeLayout(false);
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel5.PerformLayout();
this.grpNtscFilter.ResumeLayout(false);
this.tableLayoutPanel6.ResumeLayout(false);
this.tableLayoutPanel6.PerformLayout();
this.grpCommon.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.grpScanlines.ResumeLayout(false);
this.tpgPalette.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picPalette)).EndInit();
@ -690,5 +1029,25 @@
private System.Windows.Forms.ColorDialog colorDialog;
private System.Windows.Forms.NumericUpDown nudScale;
private System.Windows.Forms.CheckBox chkBilinearInterpolation;
private System.Windows.Forms.TabPage tpgPicture;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private Controls.ctrlHorizontalTrackbar trkBrightness;
private Controls.ctrlHorizontalTrackbar trkContrast;
private Controls.ctrlHorizontalTrackbar trkHue;
private Controls.ctrlHorizontalTrackbar trkSaturation;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.GroupBox grpNtscFilter;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
private Controls.ctrlHorizontalTrackbar trkArtifacts;
private Controls.ctrlHorizontalTrackbar trkBleed;
private Controls.ctrlHorizontalTrackbar trkFringing;
private Controls.ctrlHorizontalTrackbar trkGamma;
private Controls.ctrlHorizontalTrackbar trkResolution;
private Controls.ctrlHorizontalTrackbar trkSharpness;
private System.Windows.Forms.GroupBox grpCommon;
private System.Windows.Forms.CheckBox chkMergeFields;
private System.Windows.Forms.Button btnResetPictureSettings;
private System.Windows.Forms.GroupBox grpScanlines;
private Controls.ctrlHorizontalTrackbar trkScanlines;
}
}

View file

@ -38,6 +38,20 @@ namespace Mesen.GUI.Forms.Config
AddBinding("OverscanTop", nudOverscanTop);
AddBinding("OverscanBottom", nudOverscanBottom);
AddBinding("Brightness", trkBrightness);
AddBinding("Contrast", trkContrast);
AddBinding("Hue", trkHue);
AddBinding("Saturation", trkSaturation);
AddBinding("ScanlineIntensity", trkScanlines);
AddBinding("NtscArtifacts", trkArtifacts);
AddBinding("NtscBleed", trkBleed);
AddBinding("NtscFringing", trkFringing);
AddBinding("NtscGamma", trkGamma);
AddBinding("NtscResolution", trkResolution);
AddBinding("NtscSharpness", trkSharpness);
AddBinding("NtscMergeFields", chkMergeFields);
_paletteData = InteropEmu.GetRgbPalette();
RefreshPalette();
@ -45,7 +59,14 @@ namespace Mesen.GUI.Forms.Config
UpdateOverscanImage();
}
protected override bool ValidateInput()
{
UpdateObject();
VideoInfo.ApplyConfig();
return true;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
if(DialogResult == System.Windows.Forms.DialogResult.OK) {
@ -147,5 +168,23 @@ namespace Mesen.GUI.Forms.Config
{
UpdateOverscanImage();
}
private void btnResetPictureSettings_Click(object sender, EventArgs e)
{
trkBrightness.Value = 0;
trkContrast.Value = 0;
trkHue.Value = 0;
trkSaturation.Value = 0;
trkScanlines.Value = 0;
trkArtifacts.Value = 0;
trkBleed.Value = 0;
trkFringing.Value = 0;
trkGamma.Value = 0;
trkResolution.Value = 0;
trkSharpness.Value = 0;
chkMergeFields.Checked = false;
}
}
}

View file

@ -219,6 +219,12 @@
<Compile Include="Config\ConfigManager.cs" />
<Compile Include="Config\ServerInfo.cs" />
<Compile Include="Config\VsConfigInfo.cs" />
<Compile Include="Controls\ctrlHorizontalTrackbar.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Controls\ctrlHorizontalTrackbar.Designer.cs">
<DependentUpon>ctrlHorizontalTrackbar.cs</DependentUpon>
</Compile>
<Compile Include="Controls\ctrlTrackbar.cs">
<SubType>UserControl</SubType>
</Compile>
@ -479,6 +485,9 @@
<Compile Include="ResourceManager.cs" />
<Compile Include="RuntimeChecker.cs" />
<Compile Include="SingleInstance.cs" />
<EmbeddedResource Include="Controls\ctrlHorizontalTrackbar.resx">
<DependentUpon>ctrlHorizontalTrackbar.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\ctrlTrackbar.resx">
<DependentUpon>ctrlTrackbar.cs</DependentUpon>
</EmbeddedResource>

View file

@ -118,6 +118,9 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetVideoFilter(VideoFilterType filter);
[DllImport(DLLPath)] public static extern void SetVideoResizeFilter(VideoResizeFilter filter);
[DllImport(DLLPath)] public static extern void SetRgbPalette(Int32[] palette);
[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);
[DllImport(DLLPath, EntryPoint="GetRgbPalette")] private static extern void GetRgbPaletteWrapper(IntPtr paletteBuffer);
[DllImport(DLLPath, EntryPoint="GetScreenSize")] private static extern void GetScreenSizeWrapper(out ScreenSize size, [MarshalAs(UnmanagedType.I1)]bool ignoreScale);

View file

@ -269,6 +269,8 @@ namespace InteropEmu {
DllExport void __stdcall SetVideoResizeFilter(VideoResizeFilter filter) { EmulationSettings::SetVideoResizeFilter(filter); }
DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::GetRgbPalette(paletteBuffer); }
DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::SetRgbPalette(paletteBuffer); }
DllExport void __stdcall SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity) { EmulationSettings::SetPictureSettings(brightness, contrast, saturation, hue, scanlineIntensity); }
DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields) { EmulationSettings::SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields); }
DllExport const char* __stdcall GetAudioDevices()
{