Video: Overscan settings
This commit is contained in:
parent
61c1b58051
commit
84d1439780
14 changed files with 446 additions and 33 deletions
|
@ -10,7 +10,7 @@
|
|||
BaseVideoFilter::BaseVideoFilter(shared_ptr<Console> console)
|
||||
{
|
||||
_console = console;
|
||||
_overscan = {}; //TODO _console->GetSettings()->GetOverscanDimensions();
|
||||
_overscan = _console->GetSettings()->GetOverscan();
|
||||
}
|
||||
|
||||
BaseVideoFilter::~BaseVideoFilter()
|
||||
|
@ -29,7 +29,11 @@ void BaseVideoFilter::SetBaseFrameInfo(FrameInfo frameInfo)
|
|||
|
||||
FrameInfo BaseVideoFilter::GetFrameInfo()
|
||||
{
|
||||
return _baseFrameInfo;
|
||||
FrameInfo frameInfo = _baseFrameInfo;
|
||||
OverscanDimensions overscan = GetOverscan();
|
||||
frameInfo.Width -= overscan.Left * 2 + overscan.Right * 2;
|
||||
frameInfo.Height -= overscan.Top * 2 + overscan.Bottom * 2;
|
||||
return frameInfo;
|
||||
}
|
||||
|
||||
void BaseVideoFilter::UpdateBufferSize()
|
||||
|
@ -64,7 +68,7 @@ bool BaseVideoFilter::IsOddFrame()
|
|||
void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber)
|
||||
{
|
||||
_frameLock.Acquire();
|
||||
_overscan = {}; //TODO _console->GetSettings()->GetOverscanDimensions();
|
||||
_overscan = _console->GetSettings()->GetOverscan();
|
||||
_isOddFrame = frameNumber % 2;
|
||||
UpdateBufferSize();
|
||||
OnBeforeApplyFilter();
|
||||
|
|
|
@ -13,12 +13,12 @@ private:
|
|||
SimpleLock _frameLock;
|
||||
OverscanDimensions _overscan;
|
||||
bool _isOddFrame;
|
||||
FrameInfo _baseFrameInfo;
|
||||
|
||||
void UpdateBufferSize();
|
||||
|
||||
protected:
|
||||
shared_ptr<Console> _console;
|
||||
FrameInfo _baseFrameInfo;
|
||||
|
||||
virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0;
|
||||
virtual void OnBeforeApplyFilter();
|
||||
|
|
|
@ -87,26 +87,31 @@ void DefaultVideoFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
|||
{
|
||||
uint32_t *out = GetOutputBuffer();
|
||||
FrameInfo frameInfo = GetFrameInfo();
|
||||
OverscanDimensions overscan = GetOverscan();
|
||||
|
||||
uint32_t xOffset = overscan.Left * 2;
|
||||
uint32_t yOffset = overscan.Top * 2 * 512;
|
||||
|
||||
uint8_t scanlineIntensity = (uint8_t)((1.0 - _console->GetSettings()->GetVideoConfig().ScanlineIntensity) * 255);
|
||||
if(scanlineIntensity < 255) {
|
||||
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||
if(i & 0x01) {
|
||||
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||
*out = ApplyScanlineEffect(_calculatedPalette[ppuOutputBuffer[i * 512 + j]], scanlineIntensity);
|
||||
*out = ApplyScanlineEffect(_calculatedPalette[ppuOutputBuffer[i * 512 + j + yOffset + xOffset]], scanlineIntensity);
|
||||
out++;
|
||||
}
|
||||
} else {
|
||||
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||
*out = _calculatedPalette[ppuOutputBuffer[i * 512 + j]];
|
||||
*out = _calculatedPalette[ppuOutputBuffer[i * 512 + j + yOffset + xOffset]];
|
||||
out++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t pixelCount = frameInfo.Width * frameInfo.Height;
|
||||
for(uint32_t i = 0; i < pixelCount; i++) {
|
||||
out[i] = _calculatedPalette[ppuOutputBuffer[i]];
|
||||
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||
out[i*frameInfo.Width+j] = _calculatedPalette[ppuOutputBuffer[i * 512 + j + yOffset + xOffset]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,16 @@ vector<KeyCombination> EmuSettings::GetShortcutSupersets(EmulatorShortcut shortc
|
|||
return _shortcutSupersets[keySetIndex][(uint32_t)shortcut];
|
||||
}
|
||||
|
||||
OverscanDimensions EmuSettings::GetOverscan()
|
||||
{
|
||||
OverscanDimensions overscan;
|
||||
overscan.Left = _video.OverscanLeft;
|
||||
overscan.Right = _video.OverscanRight;
|
||||
overscan.Top = _video.OverscanTop;
|
||||
overscan.Bottom = _video.OverscanBottom;
|
||||
return overscan;
|
||||
}
|
||||
|
||||
uint32_t EmuSettings::GetRewindBufferSize()
|
||||
{
|
||||
return _preferences.RewindBufferSize;
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
KeyCombination GetShortcutKey(EmulatorShortcut shortcut, int keySetIndex);
|
||||
vector<KeyCombination> GetShortcutSupersets(EmulatorShortcut shortcut, int keySetIndex);
|
||||
|
||||
OverscanDimensions GetOverscan();
|
||||
uint32_t GetRewindBufferSize();
|
||||
uint32_t GetEmulationSpeed();
|
||||
double GetAspectRatio();
|
||||
|
|
|
@ -15,7 +15,8 @@ NtscFilter::NtscFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
|
|||
FrameInfo NtscFilter::GetFrameInfo()
|
||||
{
|
||||
FrameInfo frameInfo = BaseVideoFilter::GetFrameInfo();
|
||||
frameInfo.Width = SNES_NTSC_OUT_WIDTH(frameInfo.Width / 2);
|
||||
OverscanDimensions overscan = GetOverscan();
|
||||
frameInfo.Width = SNES_NTSC_OUT_WIDTH(_baseFrameInfo.Width / 2) - overscan.Left * 2 - overscan.Right * 2;
|
||||
return frameInfo;
|
||||
}
|
||||
|
||||
|
@ -45,22 +46,29 @@ void NtscFilter::OnBeforeApplyFilter()
|
|||
void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
|
||||
{
|
||||
FrameInfo frameInfo = GetFrameInfo();
|
||||
OverscanDimensions overscan = GetOverscan();
|
||||
uint32_t baseWidth = SNES_NTSC_OUT_WIDTH(256);
|
||||
uint32_t xOffset = overscan.Left * 2;
|
||||
uint32_t yOffset = overscan.Top * 2 * baseWidth;
|
||||
|
||||
snes_ntsc_blit_hires(&_ntscData, ppuOutputBuffer, 512, IsOddFrame() ? 0 : 1, 512, frameInfo.Height, _ntscBuffer, SNES_NTSC_OUT_WIDTH(256)*4);
|
||||
VideoConfig cfg = _console->GetSettings()->GetVideoConfig();
|
||||
|
||||
if(cfg.ScanlineIntensity == 0) {
|
||||
memcpy(GetOutputBuffer(), _ntscBuffer, frameInfo.Width * frameInfo.Height * sizeof(uint32_t));
|
||||
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||
memcpy(GetOutputBuffer()+i*frameInfo.Width, _ntscBuffer + yOffset + xOffset + i*baseWidth, frameInfo.Width * sizeof(uint32_t));
|
||||
}
|
||||
} else {
|
||||
uint8_t intensity = (uint8_t)((1.0 - cfg.ScanlineIntensity) * 255);
|
||||
for(uint32_t i = 0; i < frameInfo.Height; i++) {
|
||||
if(i & 0x01) {
|
||||
uint32_t *in = _ntscBuffer + i * frameInfo.Width;
|
||||
uint32_t *in = _ntscBuffer + yOffset + xOffset + i * baseWidth;
|
||||
uint32_t *out = GetOutputBuffer() + i * frameInfo.Width;
|
||||
for(uint32_t j = 0; j < frameInfo.Width; j++) {
|
||||
out[j] = ApplyScanlineEffect(in[j], intensity);
|
||||
}
|
||||
} else {
|
||||
memcpy(GetOutputBuffer()+i*frameInfo.Width, _ntscBuffer+i*frameInfo.Width, frameInfo.Width * sizeof(uint32_t));
|
||||
memcpy(GetOutputBuffer()+i*frameInfo.Width, _ntscBuffer + yOffset + xOffset + i*baseWidth, frameInfo.Width * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,11 @@ struct VideoConfig
|
|||
double NtscSharpness = 0;
|
||||
bool NtscMergeFields = false;
|
||||
|
||||
uint32_t OverscanLeft = 0;
|
||||
uint32_t OverscanRight = 0;
|
||||
uint32_t OverscanTop = 0;
|
||||
uint32_t OverscanBottom = 0;
|
||||
|
||||
bool FullscreenForceIntegerScale = false;
|
||||
bool UseExclusiveFullscreen = false;
|
||||
int32_t ExclusiveFullscreenRefreshRate = 60;
|
||||
|
|
|
@ -18,7 +18,10 @@ VideoDecoder::VideoDecoder(shared_ptr<Console> console)
|
|||
_console = console;
|
||||
_frameChanged = false;
|
||||
_stopFlag = false;
|
||||
_baseFrameInfo = { 512, 478 };
|
||||
_lastFrameInfo = _baseFrameInfo;
|
||||
UpdateVideoFilter();
|
||||
_videoFilter->SetBaseFrameInfo(_baseFrameInfo);
|
||||
}
|
||||
|
||||
VideoDecoder::~VideoDecoder()
|
||||
|
@ -33,22 +36,25 @@ FrameInfo VideoDecoder::GetFrameInfo()
|
|||
|
||||
ScreenSize VideoDecoder::GetScreenSize(bool ignoreScale)
|
||||
{
|
||||
ScreenSize size = {};
|
||||
if(_videoFilter) {
|
||||
VideoConfig config = _console->GetSettings()->GetVideoConfig();
|
||||
double aspectRatio = _console->GetSettings()->GetAspectRatio();
|
||||
double scale = (ignoreScale ? 1 : config.VideoScale);
|
||||
size.Width = (int32_t)(_baseFrameInfo.Width * scale / 2);
|
||||
size.Height = (int32_t)(_baseFrameInfo.Height * scale / 2);
|
||||
size.Scale = scale;
|
||||
if(aspectRatio != 0.0) {
|
||||
size.Width = (uint32_t)(_baseFrameInfo.Height * scale * aspectRatio / 2);
|
||||
}
|
||||
|
||||
/*if(_console->GetSettings()->GetScreenRotation() % 180) {
|
||||
std::swap(size.Width, size.Height);
|
||||
}*/
|
||||
ScreenSize size;
|
||||
OverscanDimensions overscan = ignoreScale ? _videoFilter->GetOverscan() : _console->GetSettings()->GetOverscan();
|
||||
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
|
||||
double aspectRatio = _console->GetSettings()->GetAspectRatio();
|
||||
double scale = (ignoreScale ? 1 : _console->GetSettings()->GetVideoConfig().VideoScale);
|
||||
size.Width = (int32_t)(frameInfo.Width * scale / 2);
|
||||
size.Height = (int32_t)(frameInfo.Height * scale / 2);
|
||||
if(aspectRatio != 0.0) {
|
||||
uint32_t originalHeight = frameInfo.Height + (overscan.Top + overscan.Bottom) * 2;
|
||||
uint32_t originalWidth = frameInfo.Width + (overscan.Left + overscan.Right) * 2;
|
||||
size.Width = (uint32_t)(originalHeight * scale * aspectRatio * ((double)frameInfo.Width / originalWidth)) / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
if(_console->GetSettings()->GetScreenRotation() % 180) {
|
||||
std::swap(size.Width, size.Height);
|
||||
}*/
|
||||
|
||||
size.Scale = scale;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ private:
|
|||
atomic<bool> _stopFlag;
|
||||
uint32_t _frameCount = 0;
|
||||
|
||||
FrameInfo _baseFrameInfo = { 512, 478 };
|
||||
ScreenSize _previousScreenSize = {};
|
||||
double _previousScale = 0;
|
||||
FrameInfo _baseFrameInfo;
|
||||
FrameInfo _lastFrameInfo;
|
||||
|
||||
VideoFilterType _videoFilterType = VideoFilterType::None;
|
||||
|
|
|
@ -33,6 +33,11 @@ namespace Mesen.GUI.Config
|
|||
[MinMax(-1, 1.0)] public double NtscSharpness = 0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool NtscMergeFields = false;
|
||||
|
||||
[MinMax(0, 100)] public UInt32 OverscanLeft = 0;
|
||||
[MinMax(0, 100)] public UInt32 OverscanRight = 0;
|
||||
[MinMax(0, 100)] public UInt32 OverscanTop = 0;
|
||||
[MinMax(0, 100)] public UInt32 OverscanBottom = 0;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool FullscreenForceIntegerScale = false;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool UseExclusiveFullscreen = false;
|
||||
public Int32 ExclusiveFullscreenRefreshRate = 60;
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace Mesen.GUI.Emulation
|
|||
private frmMain _frm;
|
||||
private ctrlRenderer _renderer;
|
||||
private Panel _panel;
|
||||
private bool _resizeForm;
|
||||
|
||||
public DisplayManager(frmMain frm, ctrlRenderer renderer, Panel panel)
|
||||
{
|
||||
|
@ -30,11 +31,11 @@ namespace Mesen.GUI.Emulation
|
|||
SetScaleBasedOnWindowSize();
|
||||
}
|
||||
|
||||
public void UpdateViewerSize(bool resizeForm)
|
||||
public void UpdateViewerSize()
|
||||
{
|
||||
ScreenSize screenSize = EmuApi.GetScreenSize(false);
|
||||
|
||||
if(resizeForm && _frm.WindowState != FormWindowState.Maximized) {
|
||||
if(_resizeForm && _frm.WindowState != FormWindowState.Maximized) {
|
||||
_frm.Resize -= frmMain_Resize;
|
||||
Size newSize = new Size(screenSize.Width, screenSize.Height);
|
||||
_frm.ClientSize = new Size(newSize.Width, newSize.Height + _panel.Top);
|
||||
|
@ -72,11 +73,12 @@ namespace Mesen.GUI.Emulation
|
|||
|
||||
public void SetScale(double scale, bool resizeForm)
|
||||
{
|
||||
_resizeForm = resizeForm;
|
||||
ConfigManager.Config.Video.VideoScale = scale;
|
||||
ConfigManager.Config.Video.ApplyConfig();
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
UpdateViewerSize(resizeForm);
|
||||
UpdateViewerSize();
|
||||
}
|
||||
|
||||
public void ToggleFullscreen()
|
||||
|
|
337
UI/Forms/Config/frmVideoConfig.Designer.cs
generated
337
UI/Forms/Config/frmVideoConfig.Designer.cs
generated
|
@ -76,6 +76,21 @@
|
|||
this.mnuPresetSVideo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPresetRgb = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPresetMonochrome = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tpgOverscan = new System.Windows.Forms.TabPage();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picOverscan = new System.Windows.Forms.PictureBox();
|
||||
this.tableLayoutPanel11 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.nudOverscanTop = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblTop = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel12 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.nudOverscanBottom = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblBottom = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel13 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.nudOverscanRight = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblRight = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel14 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.nudOverscanLeft = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblLeft = new System.Windows.Forms.Label();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.tpgGeneral.SuspendLayout();
|
||||
this.tlpMain.SuspendLayout();
|
||||
|
@ -91,6 +106,13 @@
|
|||
this.grpScanlines.SuspendLayout();
|
||||
this.tableLayoutPanel8.SuspendLayout();
|
||||
this.ctxPicturePresets.SuspendLayout();
|
||||
this.tpgOverscan.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picOverscan)).BeginInit();
|
||||
this.tableLayoutPanel11.SuspendLayout();
|
||||
this.tableLayoutPanel12.SuspendLayout();
|
||||
this.tableLayoutPanel13.SuspendLayout();
|
||||
this.tableLayoutPanel14.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
|
@ -102,6 +124,7 @@
|
|||
//
|
||||
this.tabMain.Controls.Add(this.tpgGeneral);
|
||||
this.tabMain.Controls.Add(this.tpgPicture);
|
||||
this.tabMain.Controls.Add(this.tpgOverscan);
|
||||
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tabMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.tabMain.Name = "tabMain";
|
||||
|
@ -791,6 +814,294 @@
|
|||
this.mnuPresetMonochrome.Text = "Monochrome";
|
||||
this.mnuPresetMonochrome.Click += new System.EventHandler(this.mnuPresetMonochrome_Click);
|
||||
//
|
||||
// tpgOverscan
|
||||
//
|
||||
this.tpgOverscan.Controls.Add(this.tableLayoutPanel1);
|
||||
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(566, 382);
|
||||
this.tpgOverscan.TabIndex = 6;
|
||||
this.tpgOverscan.Text = "Overscan";
|
||||
this.tpgOverscan.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 3;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 262F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.picOverscan, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel11, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel12, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel13, 2, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel14, 0, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 246F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(560, 376);
|
||||
this.tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// picOverscan
|
||||
//
|
||||
this.picOverscan.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picOverscan.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.picOverscan.Location = new System.Drawing.Point(152, 68);
|
||||
this.picOverscan.Name = "picOverscan";
|
||||
this.picOverscan.Size = new System.Drawing.Size(256, 240);
|
||||
this.picOverscan.TabIndex = 1;
|
||||
this.picOverscan.TabStop = false;
|
||||
//
|
||||
// tableLayoutPanel11
|
||||
//
|
||||
this.tableLayoutPanel11.ColumnCount = 1;
|
||||
this.tableLayoutPanel11.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel11.Controls.Add(this.nudOverscanTop, 0, 1);
|
||||
this.tableLayoutPanel11.Controls.Add(this.lblTop, 0, 0);
|
||||
this.tableLayoutPanel11.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel11.Location = new System.Drawing.Point(149, 0);
|
||||
this.tableLayoutPanel11.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel11.Name = "tableLayoutPanel11";
|
||||
this.tableLayoutPanel11.RowCount = 2;
|
||||
this.tableLayoutPanel11.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel11.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel11.Size = new System.Drawing.Size(262, 65);
|
||||
this.tableLayoutPanel11.TabIndex = 4;
|
||||
//
|
||||
// nudOverscanTop
|
||||
//
|
||||
this.nudOverscanTop.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||
this.nudOverscanTop.DecimalPlaces = 0;
|
||||
this.nudOverscanTop.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanTop.Location = new System.Drawing.Point(110, 44);
|
||||
this.nudOverscanTop.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.nudOverscanTop.Maximum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanTop.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||
this.nudOverscanTop.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanTop.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudOverscanTop.Name = "nudOverscanTop";
|
||||
this.nudOverscanTop.Size = new System.Drawing.Size(41, 21);
|
||||
this.nudOverscanTop.TabIndex = 2;
|
||||
this.nudOverscanTop.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanTop.ValueChanged += new System.EventHandler(this.nudOverscan_ValueChanged);
|
||||
//
|
||||
// lblTop
|
||||
//
|
||||
this.lblTop.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||
this.lblTop.AutoSize = true;
|
||||
this.lblTop.Location = new System.Drawing.Point(118, 31);
|
||||
this.lblTop.Name = "lblTop";
|
||||
this.lblTop.Size = new System.Drawing.Size(26, 13);
|
||||
this.lblTop.TabIndex = 0;
|
||||
this.lblTop.Text = "Top";
|
||||
this.lblTop.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// tableLayoutPanel12
|
||||
//
|
||||
this.tableLayoutPanel12.ColumnCount = 1;
|
||||
this.tableLayoutPanel12.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel12.Controls.Add(this.nudOverscanBottom, 0, 1);
|
||||
this.tableLayoutPanel12.Controls.Add(this.lblBottom, 0, 0);
|
||||
this.tableLayoutPanel12.Location = new System.Drawing.Point(149, 311);
|
||||
this.tableLayoutPanel12.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel12.Name = "tableLayoutPanel12";
|
||||
this.tableLayoutPanel12.RowCount = 2;
|
||||
this.tableLayoutPanel12.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel12.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel12.Size = new System.Drawing.Size(262, 58);
|
||||
this.tableLayoutPanel12.TabIndex = 5;
|
||||
//
|
||||
// nudOverscanBottom
|
||||
//
|
||||
this.nudOverscanBottom.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.nudOverscanBottom.DecimalPlaces = 0;
|
||||
this.nudOverscanBottom.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanBottom.Location = new System.Drawing.Point(110, 13);
|
||||
this.nudOverscanBottom.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.nudOverscanBottom.Maximum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanBottom.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||
this.nudOverscanBottom.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanBottom.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudOverscanBottom.Name = "nudOverscanBottom";
|
||||
this.nudOverscanBottom.Size = new System.Drawing.Size(41, 21);
|
||||
this.nudOverscanBottom.TabIndex = 2;
|
||||
this.nudOverscanBottom.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanBottom.ValueChanged += new System.EventHandler(this.nudOverscan_ValueChanged);
|
||||
//
|
||||
// lblBottom
|
||||
//
|
||||
this.lblBottom.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.lblBottom.AutoSize = true;
|
||||
this.lblBottom.Location = new System.Drawing.Point(111, 0);
|
||||
this.lblBottom.Name = "lblBottom";
|
||||
this.lblBottom.Size = new System.Drawing.Size(40, 13);
|
||||
this.lblBottom.TabIndex = 0;
|
||||
this.lblBottom.Text = "Bottom";
|
||||
this.lblBottom.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// tableLayoutPanel13
|
||||
//
|
||||
this.tableLayoutPanel13.ColumnCount = 2;
|
||||
this.tableLayoutPanel13.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel13.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel13.Controls.Add(this.nudOverscanRight, 0, 2);
|
||||
this.tableLayoutPanel13.Controls.Add(this.lblRight, 0, 1);
|
||||
this.tableLayoutPanel13.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel13.Location = new System.Drawing.Point(411, 65);
|
||||
this.tableLayoutPanel13.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel13.Name = "tableLayoutPanel13";
|
||||
this.tableLayoutPanel13.RowCount = 4;
|
||||
this.tableLayoutPanel13.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel13.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel13.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel13.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel13.Size = new System.Drawing.Size(149, 246);
|
||||
this.tableLayoutPanel13.TabIndex = 6;
|
||||
//
|
||||
// nudOverscanRight
|
||||
//
|
||||
this.nudOverscanRight.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.nudOverscanRight.DecimalPlaces = 0;
|
||||
this.nudOverscanRight.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanRight.Location = new System.Drawing.Point(0, 119);
|
||||
this.nudOverscanRight.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.nudOverscanRight.Maximum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanRight.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||
this.nudOverscanRight.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanRight.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudOverscanRight.Name = "nudOverscanRight";
|
||||
this.nudOverscanRight.Size = new System.Drawing.Size(41, 21);
|
||||
this.nudOverscanRight.TabIndex = 1;
|
||||
this.nudOverscanRight.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanRight.ValueChanged += new System.EventHandler(this.nudOverscan_ValueChanged);
|
||||
//
|
||||
// lblRight
|
||||
//
|
||||
this.lblRight.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.lblRight.AutoSize = true;
|
||||
this.lblRight.Location = new System.Drawing.Point(4, 106);
|
||||
this.lblRight.Name = "lblRight";
|
||||
this.lblRight.Size = new System.Drawing.Size(32, 13);
|
||||
this.lblRight.TabIndex = 0;
|
||||
this.lblRight.Text = "Right";
|
||||
this.lblRight.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// tableLayoutPanel14
|
||||
//
|
||||
this.tableLayoutPanel14.ColumnCount = 2;
|
||||
this.tableLayoutPanel14.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel14.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel14.Controls.Add(this.nudOverscanLeft, 1, 2);
|
||||
this.tableLayoutPanel14.Controls.Add(this.lblLeft, 1, 1);
|
||||
this.tableLayoutPanel14.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel14.Location = new System.Drawing.Point(0, 65);
|
||||
this.tableLayoutPanel14.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel14.Name = "tableLayoutPanel14";
|
||||
this.tableLayoutPanel14.RowCount = 4;
|
||||
this.tableLayoutPanel14.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel14.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel14.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel14.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel14.Size = new System.Drawing.Size(149, 246);
|
||||
this.tableLayoutPanel14.TabIndex = 7;
|
||||
//
|
||||
// nudOverscanLeft
|
||||
//
|
||||
this.nudOverscanLeft.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.nudOverscanLeft.DecimalPlaces = 0;
|
||||
this.nudOverscanLeft.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanLeft.Location = new System.Drawing.Point(108, 119);
|
||||
this.nudOverscanLeft.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.nudOverscanLeft.Maximum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanLeft.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||
this.nudOverscanLeft.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanLeft.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudOverscanLeft.Name = "nudOverscanLeft";
|
||||
this.nudOverscanLeft.Size = new System.Drawing.Size(41, 21);
|
||||
this.nudOverscanLeft.TabIndex = 2;
|
||||
this.nudOverscanLeft.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOverscanLeft.ValueChanged += new System.EventHandler(this.nudOverscan_ValueChanged);
|
||||
//
|
||||
// lblLeft
|
||||
//
|
||||
this.lblLeft.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.lblLeft.AutoSize = true;
|
||||
this.lblLeft.Location = new System.Drawing.Point(116, 106);
|
||||
this.lblLeft.Name = "lblLeft";
|
||||
this.lblLeft.Size = new System.Drawing.Size(25, 13);
|
||||
this.lblLeft.TabIndex = 0;
|
||||
this.lblLeft.Text = "Left";
|
||||
this.lblLeft.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// frmVideoConfig
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -827,6 +1138,17 @@
|
|||
this.tableLayoutPanel8.ResumeLayout(false);
|
||||
this.tableLayoutPanel8.PerformLayout();
|
||||
this.ctxPicturePresets.ResumeLayout(false);
|
||||
this.tpgOverscan.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.picOverscan)).EndInit();
|
||||
this.tableLayoutPanel11.ResumeLayout(false);
|
||||
this.tableLayoutPanel11.PerformLayout();
|
||||
this.tableLayoutPanel12.ResumeLayout(false);
|
||||
this.tableLayoutPanel12.PerformLayout();
|
||||
this.tableLayoutPanel13.ResumeLayout(false);
|
||||
this.tableLayoutPanel13.PerformLayout();
|
||||
this.tableLayoutPanel14.ResumeLayout(false);
|
||||
this.tableLayoutPanel14.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
@ -881,5 +1203,20 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuPresetSVideo;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPresetRgb;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPresetMonochrome;
|
||||
private System.Windows.Forms.TabPage tpgOverscan;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.PictureBox picOverscan;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel11;
|
||||
private Controls.MesenNumericUpDown nudOverscanTop;
|
||||
private System.Windows.Forms.Label lblTop;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel12;
|
||||
private Controls.MesenNumericUpDown nudOverscanBottom;
|
||||
private System.Windows.Forms.Label lblBottom;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel13;
|
||||
private Controls.MesenNumericUpDown nudOverscanRight;
|
||||
private System.Windows.Forms.Label lblRight;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel14;
|
||||
private Controls.MesenNumericUpDown nudOverscanLeft;
|
||||
private System.Windows.Forms.Label lblLeft;
|
||||
}
|
||||
}
|
|
@ -47,6 +47,11 @@ namespace Mesen.GUI.Forms.Config
|
|||
AddBinding(nameof(VideoConfig.NtscResolution), trkResolution);
|
||||
AddBinding(nameof(VideoConfig.NtscSharpness), trkSharpness);
|
||||
AddBinding(nameof(VideoConfig.NtscMergeFields), chkMergeFields);
|
||||
|
||||
AddBinding(nameof(VideoConfig.OverscanLeft), nudOverscanLeft);
|
||||
AddBinding(nameof(VideoConfig.OverscanRight), nudOverscanRight);
|
||||
AddBinding(nameof(VideoConfig.OverscanTop), nudOverscanTop);
|
||||
AddBinding(nameof(VideoConfig.OverscanBottom), nudOverscanBottom);
|
||||
}
|
||||
|
||||
protected override bool ValidateInput()
|
||||
|
@ -123,5 +128,24 @@ namespace Mesen.GUI.Forms.Config
|
|||
{
|
||||
SetNtscPreset(0, -100, 0, 0, 20, 0, 70, -20, -20, -10, 15, false);
|
||||
}
|
||||
|
||||
private void UpdateOverscanImage(PictureBox picture, int top, int bottom, int left, int right)
|
||||
{
|
||||
Bitmap overscan = new Bitmap(picture.Width - 2, picture.Height - 2);
|
||||
|
||||
using(Graphics g = Graphics.FromImage(overscan)) {
|
||||
g.Clear(Color.DarkGray);
|
||||
|
||||
Rectangle fg = new Rectangle(left, top, 256 - left - right, 240 - top - bottom);
|
||||
g.ScaleTransform((float)overscan.Width / 256, (float)overscan.Height / 240);
|
||||
g.FillRectangle(Brushes.LightCyan, fg);
|
||||
}
|
||||
picture.Image = overscan;
|
||||
}
|
||||
|
||||
private void nudOverscan_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateOverscanImage(picOverscan, (int)nudOverscanTop.Value, (int)nudOverscanBottom.Value, (int)nudOverscanLeft.Value, (int)nudOverscanRight.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Mesen.GUI.Forms
|
|||
ConfigManager.Config.ApplyConfig();
|
||||
|
||||
_displayManager = new DisplayManager(this, ctrlRenderer, pnlRenderer);
|
||||
_displayManager.UpdateViewerSize(false);
|
||||
_displayManager.UpdateViewerSize();
|
||||
_shortcuts = new ShortcutHandler(_displayManager);
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
|
@ -112,6 +112,12 @@ namespace Mesen.GUI.Forms
|
|||
}));
|
||||
break;
|
||||
|
||||
case ConsoleNotificationType.ResolutionChanged:
|
||||
this.BeginInvoke((Action)(() => {
|
||||
_displayManager.UpdateViewerSize();
|
||||
}));
|
||||
break;
|
||||
|
||||
case ConsoleNotificationType.ExecuteShortcut:
|
||||
this.BeginInvoke((Action)(() => {
|
||||
_shortcuts.ExecuteShortcut((EmulatorShortcut)e.Parameter);
|
||||
|
|
Loading…
Add table
Reference in a new issue