diff --git a/Core/Ppu.cpp b/Core/Ppu.cpp index bde095e..a432149 100644 --- a/Core/Ppu.cpp +++ b/Core/Ppu.cpp @@ -22,8 +22,8 @@ Ppu::Ppu(shared_ptr console) _outputBuffers[0] = new uint16_t[512 * 478]; _outputBuffers[1] = new uint16_t[512 * 478]; - memset(_outputBuffers[0], 0, 512 * 478); - memset(_outputBuffers[1], 0, 512 * 478); + memset(_outputBuffers[0], 0, 512 * 478 * sizeof(uint16_t)); + memset(_outputBuffers[1], 0, 512 * 478 * sizeof(uint16_t)); _currentBuffer = _outputBuffers[0]; @@ -1016,7 +1016,8 @@ void Ppu::ApplyBrightness() void Ppu::ApplyHiResMode() { - uint16_t scanline = _scanline - 1; + //When overscan mode is off, center the 224-line picture in the center of the 239-line output buffer + uint16_t scanline = _overscanMode ? (_scanline - 1) : (_scanline + 7); uint32_t screenY = IsDoubleHeight() ? ((_frameCount & 0x01) ? ((scanline << 1) + 1) : (scanline << 1)) : (scanline << 1); uint32_t baseAddr = (screenY << 9); @@ -1073,10 +1074,16 @@ void Ppu::ProcessWindowMaskSettings(uint8_t value, uint8_t offset) void Ppu::SendFrame() { + constexpr uint16_t width = 512; + constexpr uint16_t height = 478; + _console->GetNotificationManager()->SendNotification(ConsoleNotificationType::PpuFrameDone); - uint16_t width = 512; - uint16_t height = _overscanMode ? 478 : 448; + if(!_overscanMode) { + //Clear the top 7 and bottom 8 rows + memset(_currentBuffer, 0, width * 14 * sizeof(uint16_t)); + memset(_currentBuffer + width * 462, 0, width * 16 * sizeof(uint16_t)); + } bool isRewinding = _console->GetRewindManager()->IsRewinding(); if(isRewinding || _screenInterlace) { diff --git a/Core/VideoDecoder.h b/Core/VideoDecoder.h index 0d1c24e..ea7f043 100644 --- a/Core/VideoDecoder.h +++ b/Core/VideoDecoder.h @@ -28,7 +28,7 @@ private: atomic _stopFlag; uint32_t _frameCount = 0; - FrameInfo _baseFrameInfo = { 256, 224 }; + FrameInfo _baseFrameInfo = { 512, 478 }; ScreenSize _previousScreenSize = {}; double _previousScale = 0; FrameInfo _lastFrameInfo; diff --git a/UI/Emulation/DisplayManager.cs b/UI/Emulation/DisplayManager.cs new file mode 100644 index 0000000..ab7c6e7 --- /dev/null +++ b/UI/Emulation/DisplayManager.cs @@ -0,0 +1,87 @@ +using Mesen.GUI.Config; +using Mesen.GUI.Controls; +using Mesen.GUI.Forms; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Mesen.GUI.Emulation +{ + public class DisplayManager + { + private frmMain _frm; + private ctrlRenderer _renderer; + private Panel _panel; + + public DisplayManager(frmMain frm, ctrlRenderer renderer, Panel panel) + { + _frm = frm; + _renderer = renderer; + _panel = panel; + _frm.Resize += frmMain_Resize; + } + + private void frmMain_Resize(object sender, EventArgs e) + { + SetScaleBasedOnWindowSize(); + } + + public void UpdateViewerSize(bool resizeForm) + { + ScreenSize screenSize = EmuApi.GetScreenSize(false); + + 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); + _frm.Resize += frmMain_Resize; + } + + _renderer.Size = new Size(screenSize.Width, screenSize.Height); + _renderer.Top = (_panel.Height - _renderer.Height) / 2; + _renderer.Left = (_panel.Width - _renderer.Width) / 2; + } + + public void SetScaleBasedOnDimensions(Size dimensions) + { + ScreenSize size = EmuApi.GetScreenSize(true); + + double verticalScale = (double)dimensions.Height / size.Height; + double horizontalScale = (double)dimensions.Width / size.Width; + double scale = Math.Min(verticalScale, horizontalScale); + /*if(_fullscreenMode && ConfigManager.Config.Video.FullscreenForceIntegerScale) { + scale = Math.Floor(scale); + }*/ + + SetScale(scale, false); + } + + private void SetScaleBasedOnWindowSize() + { + SetScaleBasedOnDimensions(_panel.ClientSize); + } + + private void SetScaleBasedOnScreenSize() + { + SetScaleBasedOnDimensions(Screen.FromControl(_frm).Bounds.Size); + } + + public void SetScale(double scale, bool resizeForm) + { + ConfigManager.Config.Video.VideoScale = scale; + ConfigManager.Config.Video.ApplyConfig(); + ConfigManager.ApplyChanges(); + + UpdateViewerSize(resizeForm); + } + + public void ToggleFullscreen() + { + + } + } +} diff --git a/UI/Emulation/ShortcutHandler.cs b/UI/Emulation/ShortcutHandler.cs index c9e0f39..52ca3c2 100644 --- a/UI/Emulation/ShortcutHandler.cs +++ b/UI/Emulation/ShortcutHandler.cs @@ -13,10 +13,14 @@ namespace Mesen.GUI.Emulation { public class ShortcutHandler { + private DisplayManager _displayManager; private Dictionary> _actionEnabledFuncs = new Dictionary>(); private List _speedValues = new List { 1, 3, 6, 12, 25, 50, 75, 100, 150, 200, 250, 300, 350, 400, 450, 500, 750, 1000, 2000, 4000 }; - public bool AutoResizeForm { get; internal set; } + public ShortcutHandler(DisplayManager displayManager) + { + _displayManager = displayManager; + } public void BindShortcut(ToolStripMenuItem item, EmulatorShortcut shortcut, Func isActionEnabled = null) { @@ -80,18 +84,18 @@ namespace Mesen.GUI.Emulation case EmulatorShortcut.ToggleAlwaysOnTop: ToggleAlwaysOnTop(); break; case EmulatorShortcut.ToggleDebugInfo: ToggleDebugInfo(); break; case EmulatorShortcut.MaxSpeed: ToggleMaxSpeed(); break; - //case EmulatorShortcut.ToggleFullscreen: ToggleFullscreen(); restoreFullscreen = false; break; + case EmulatorShortcut.ToggleFullscreen: _displayManager.ToggleFullscreen(); break; case EmulatorShortcut.OpenFile: OpenFile(); break; case EmulatorShortcut.IncreaseSpeed: IncreaseEmulationSpeed(); break; case EmulatorShortcut.DecreaseSpeed: DecreaseEmulationSpeed(); break; - case EmulatorShortcut.SetScale1x: SetScale(1); break; - case EmulatorShortcut.SetScale2x: SetScale(2); break; - case EmulatorShortcut.SetScale3x: SetScale(3); break; - case EmulatorShortcut.SetScale4x: SetScale(4); break; - case EmulatorShortcut.SetScale5x: SetScale(5); break; - case EmulatorShortcut.SetScale6x: SetScale(6); break; + case EmulatorShortcut.SetScale1x: _displayManager.SetScale(1, true); break; + case EmulatorShortcut.SetScale2x: _displayManager.SetScale(2, true); break; + case EmulatorShortcut.SetScale3x: _displayManager.SetScale(3, true); break; + case EmulatorShortcut.SetScale4x: _displayManager.SetScale(4, true); break; + case EmulatorShortcut.SetScale5x: _displayManager.SetScale(5, true); break; + case EmulatorShortcut.SetScale6x: _displayManager.SetScale(6, true); break; case EmulatorShortcut.TakeScreenshot: EmuApi.TakeScreenshot(); break; @@ -145,7 +149,7 @@ namespace Mesen.GUI.Emulation } } } - + public void SetRegion(ConsoleRegion region) { ConfigManager.Config.Emulation.Region = region; @@ -160,14 +164,6 @@ namespace Mesen.GUI.Emulation ConfigManager.ApplyChanges(); } - public void SetScale(double scale, bool autoResize = true) - { - this.AutoResizeForm = autoResize; - ConfigManager.Config.Video.VideoScale = scale; - ConfigManager.Config.Video.ApplyConfig(); - ConfigManager.ApplyChanges(); - } - public void ToggleBilinearInterpolation() { ConfigManager.Config.Video.UseBilinearInterpolation = !ConfigManager.Config.Video.UseBilinearInterpolation; @@ -229,7 +225,9 @@ namespace Mesen.GUI.Emulation private void ToggleOsd() { - //TODO + ConfigManager.Config.Preferences.DisableOsd = !ConfigManager.Config.Preferences.DisableOsd; + ConfigManager.Config.Preferences.ApplyConfig(); + ConfigManager.ApplyChanges(); } private void ToggleFps() diff --git a/UI/Forms/frmMain.cs b/UI/Forms/frmMain.cs index 5232d51..e59caa9 100644 --- a/UI/Forms/frmMain.cs +++ b/UI/Forms/frmMain.cs @@ -22,10 +22,15 @@ namespace Mesen.GUI.Forms { private NotificationListener _notifListener; private ShortcutHandler _shortcuts; + private DisplayManager _displayManager; public frmMain(string[] args) { InitializeComponent(); + if(DesignMode) { + return; + } + ResourceHelper.LoadResources(Language.English); } @@ -44,8 +49,6 @@ namespace Mesen.GUI.Forms { base.OnShown(e); - _shortcuts = new ShortcutHandler(); - EmuApi.InitDll(); ConfigManager.Config.Video.ApplyConfig(); EmuApi.InitializeEmu(ConfigManager.HomeFolder, Handle, ctrlRenderer.Handle, false, false, false); @@ -53,9 +56,13 @@ namespace Mesen.GUI.Forms ConfigManager.Config.InitializeDefaults(); ConfigManager.Config.ApplyConfig(); + _displayManager = new DisplayManager(this, ctrlRenderer, pnlRenderer); + _displayManager.UpdateViewerSize(false); + _shortcuts = new ShortcutHandler(_displayManager); + _notifListener = new NotificationListener(); _notifListener.OnNotification += OnNotificationReceived; - + SaveStateManager.InitializeStateMenu(mnuSaveState, true, _shortcuts); SaveStateManager.InitializeStateMenu(mnuLoadState, false, _shortcuts); @@ -63,9 +70,9 @@ namespace Mesen.GUI.Forms ctrlRecentGames.Initialize(); ctrlRecentGames.Visible = true; + ResizeRecentGames(); this.Resize += frmMain_Resize; - ResizeRecentGames(); } protected override void OnFormClosing(FormClosingEventArgs e) @@ -105,13 +112,6 @@ namespace Mesen.GUI.Forms })); break; - case ConsoleNotificationType.ResolutionChanged: - ScreenSize size = EmuApi.GetScreenSize(false); - this.BeginInvoke((Action)(() => { - UpdateViewerSize(size); - })); - break; - case ConsoleNotificationType.ExecuteShortcut: this.BeginInvoke((Action)(() => { _shortcuts.ExecuteShortcut((EmulatorShortcut)e.Parameter); @@ -191,58 +191,14 @@ namespace Mesen.GUI.Forms mnuRegionPal.Click += (s, e) => { _shortcuts.SetRegion(ConsoleRegion.Pal); }; } - private void UpdateViewerSize(ScreenSize screenSize) - { - if(_shortcuts.AutoResizeForm && this.WindowState != FormWindowState.Maximized) { - this.Resize -= frmMain_Resize; - Size newSize = new Size(screenSize.Width, screenSize.Height); - this.ClientSize = new Size(newSize.Width, newSize.Height + pnlRenderer.Top); - this.Resize += frmMain_Resize; - } - - ctrlRenderer.Size = new Size(screenSize.Width, screenSize.Height); - ctrlRenderer.Top = (pnlRenderer.Height - ctrlRenderer.Height) / 2; - ctrlRenderer.Left = (pnlRenderer.Width - ctrlRenderer.Width) / 2; - } - - private void SetScaleBasedOnDimensions(Size dimensions) - { - ScreenSize size = EmuApi.GetScreenSize(true); - - double verticalScale = (double)dimensions.Height / size.Height; - double horizontalScale = (double)dimensions.Width / size.Width; - double scale = Math.Min(verticalScale, horizontalScale); - /*if(_fullscreenMode && ConfigManager.Config.Video.FullscreenForceIntegerScale) { - scale = Math.Floor(scale); - }*/ - - _shortcuts.SetScale(scale, false); - } - - private void SetScaleBasedOnWindowSize() - { - SetScaleBasedOnDimensions(pnlRenderer.ClientSize); - } - - private void SetScaleBasedOnScreenSize() - { - SetScaleBasedOnDimensions(Screen.FromControl(this).Bounds.Size); - } - private void ResizeRecentGames() { ctrlRecentGames.Height = this.ClientSize.Height - ctrlRecentGames.Top - 80; } - private void ProcessResize() - { - ResizeRecentGames(); - SetScaleBasedOnWindowSize(); - } - private void frmMain_Resize(object sender, EventArgs e) { - ProcessResize(); + ResizeRecentGames(); } private void mnuVideoConfig_Click(object sender, EventArgs e) diff --git a/UI/UI.csproj b/UI/UI.csproj index 1b8cfe2..68eec07 100644 --- a/UI/UI.csproj +++ b/UI/UI.csproj @@ -467,6 +467,7 @@ Form + BaseConfigForm.cs