diff --git a/src/BizHawk.Client.Common/Api/Classes/EmuClientApi.cs b/src/BizHawk.Client.Common/Api/Classes/EmuClientApi.cs index 47320ea4b7..9cc6a2246c 100644 --- a/src/BizHawk.Client.Common/Api/Classes/EmuClientApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/EmuClientApi.cs @@ -197,7 +197,7 @@ namespace BizHawk.Client.Common if (size == 1 || size == 2 || size == 3 || size == 4 || size == 5 || size == 10) { _config.SetWindowScaleFor(Emulator.SystemId, size); - _mainForm.FrameBufferResized(); + _mainForm.FrameBufferResized(forceWindowResize: true); _displayManager.OSD.AddMessage($"Window size set to {size}x"); } else diff --git a/src/BizHawk.Client.Common/IMainFormForApi.cs b/src/BizHawk.Client.Common/IMainFormForApi.cs index e3354b3a7f..790179a330 100644 --- a/src/BizHawk.Client.Common/IMainFormForApi.cs +++ b/src/BizHawk.Client.Common/IMainFormForApi.cs @@ -53,7 +53,8 @@ namespace BizHawk.Client.Common /// only referenced from EmuClientApi void FrameAdvance(bool discardApiHawkSurfaces = true); - void FrameBufferResized(); + /// Override + void FrameBufferResized(bool forceWindowResize = false); void FrameSkipMessage(); diff --git a/src/BizHawk.Client.Common/config/Config.cs b/src/BizHawk.Client.Common/config/Config.cs index 66577fc48a..15316b74a2 100644 --- a/src/BizHawk.Client.Common/config/Config.cs +++ b/src/BizHawk.Client.Common/config/Config.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Drawing; using System.IO; using BizHawk.Bizware.Graphics; @@ -139,8 +140,8 @@ namespace BizHawk.Client.Common public bool MainFormStayOnTop { get; set; } public bool StartPaused { get; set; } public bool StartFullscreen { get; set; } - public int MainWndx { get; set; } = -1; // Negative numbers will be ignored - public int MainWndy { get; set; } = -1; + public Point? MainWindowPosition { get; set; } + public Size? MainWindowSize { get; set; } public bool RunInBackground { get; set; } = true; public bool AcceptBackgroundInput { get; set; } public bool AcceptBackgroundInputControllerOnly { get; set; } @@ -277,6 +278,11 @@ namespace BizHawk.Client.Common public int DispCropRight { get; set; } = 0; public int DispCropBottom { get; set; } = 0; + /// + /// Automatically resize main window when framebuffer size changes (default behavior) + /// + public bool ResizeWithFramebuffer { get; set; } = true; + // Sound options public ESoundOutputMethod SoundOutputMethod { get; set; } = HostCapabilityDetector.HasXAudio2 ? ESoundOutputMethod.XAudio2 : ESoundOutputMethod.OpenAL; diff --git a/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs b/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs index fec81f1e89..fd547c82e6 100644 --- a/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs +++ b/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs @@ -58,7 +58,8 @@ namespace BizHawk.Client.EmuHawk void FrameAdvance(bool discardApiHawkSurfaces = true); /// only referenced from - void FrameBufferResized(); + /// Override + void FrameBufferResized(bool forceWindowResize = false); /// only referenced from bool LoadQuickSave(int slot, bool suppressOSD = false); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.Designer.cs b/src/BizHawk.Client.EmuHawk/MainForm.Designer.cs index 94a10c2699..8bfd8b16b6 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.Designer.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.Designer.cs @@ -123,6 +123,8 @@ namespace BizHawk.Client.EmuHawk this.LoadedCoreNameMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); this.ViewSubMenu = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); this.WindowSizeSubMenu = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); + this.toolStripSeparator26 = new BizHawk.WinForms.Controls.ToolStripSeparatorEx(); + this.DisableResizeWithFramebufferMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); this.SwitchToFullscreenMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); this.toolStripSeparator2 = new BizHawk.WinForms.Controls.ToolStripSeparatorEx(); this.DisplayFPSMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx(); @@ -978,9 +980,18 @@ namespace BizHawk.Client.EmuHawk // // WindowSizeSubMenu // + this.WindowSizeSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripSeparator26, + this.DisableResizeWithFramebufferMenuItem}); this.WindowSizeSubMenu.Text = "&Window Size"; this.WindowSizeSubMenu.DropDownOpened += new System.EventHandler(this.WindowSizeSubMenu_DropDownOpened); // + // ResizeWithFramebufferMenuItem + // + this.DisableResizeWithFramebufferMenuItem.CheckOnClick = true; + this.DisableResizeWithFramebufferMenuItem.Text = "&Static Size"; + this.DisableResizeWithFramebufferMenuItem.Click += new System.EventHandler(this.DisableResizeWithFramebufferMenuItem_Click); + // // SwitchToFullscreenMenuItem // this.SwitchToFullscreenMenuItem.Text = "Switch to Fullscreen"; @@ -2767,5 +2778,7 @@ namespace BizHawk.Client.EmuHawk private ToolStripSeparatorEx toolStripSeparator24; private ToolStripMenuItemEx AutosaveLastSlotMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator25; + private ToolStripMenuItemEx DisableResizeWithFramebufferMenuItem; + private ToolStripSeparatorEx toolStripSeparator26; } } diff --git a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs index 5bea05ba63..ccc454e3f9 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -611,16 +611,27 @@ namespace BizHawk.Client.EmuHawk private void WindowSizeSubMenu_DropDownOpened(object sender, EventArgs e) { var windowScale = Config.GetWindowScaleFor(Emulator.SystemId); - foreach (ToolStripMenuItem item in WindowSizeSubMenu.DropDownItems) + foreach (var item in WindowSizeSubMenu.DropDownItems) { - item.Checked = (int) item.Tag == windowScale; + // filter out separators + if (item is ToolStripMenuItem menuItem && menuItem.Tag is int itemScale) + { + menuItem.Checked = itemScale == windowScale && Config.ResizeWithFramebuffer; + } } + DisableResizeWithFramebufferMenuItem.Checked = !Config.ResizeWithFramebuffer; + } + + private void DisableResizeWithFramebufferMenuItem_Click(object sender, EventArgs e) + { + Config.ResizeWithFramebuffer = !DisableResizeWithFramebufferMenuItem.Checked; + FrameBufferResized(); } private void WindowSize_Click(object sender, EventArgs e) { Config.SetWindowScaleFor(Emulator.SystemId, (int) ((ToolStripMenuItem) sender).Tag); - FrameBufferResized(); + FrameBufferResized(forceWindowResize: true); } private void SwitchToFullscreenMenuItem_Click(object sender, EventArgs e) diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 69de974475..17073ba1e7 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -61,9 +61,7 @@ namespace BizHawk.Client.EmuHawk { UpdateWindowTitle(); - ToolStripItem[] CreateWindowSizeFactorSubmenus() { - var items = new ToolStripItem[WINDOW_SCALE_MAX]; for (int i = 1; i <= WINDOW_SCALE_MAX; i++) { long quotient = Math.DivRem(i, 10, out long remainder); @@ -73,11 +71,9 @@ namespace BizHawk.Client.EmuHawk Text = $"{(quotient > 0 ? quotient : "")}&{remainder}x" }; temp.Click += this.WindowSize_Click; - items[i - 1] = temp; + WindowSizeSubMenu.DropDownItems.Insert(i - 1, temp); } - return items; } - WindowSizeSubMenu.DropDownItems.AddRange(CreateWindowSizeFactorSubmenus()); foreach (var (appliesTo, coreNames) in Config.CorePickerUIData) { @@ -603,20 +599,17 @@ namespace BizHawk.Client.EmuHawk CheatList.Changed += Tools.UpdateCheatRelatedTools; RewireSound(); - // Workaround for windows, location is -32000 when minimized, if they close it during this time, that's what gets saved - if (Config.MainWndx == -32000) + if (Config.SaveWindowPosition) { - Config.MainWndx = 0; - } + if (Config.MainWindowPosition is Point position) + { + Location = position; + } - if (Config.MainWndy == -32000) - { - Config.MainWndy = 0; - } - - if (Config.MainWndx != -1 && Config.MainWndy != -1 && Config.SaveWindowPosition) - { - Location = new Point(Config.MainWndx, Config.MainWndy); + if (Config.MainWindowSize is Size size && !Config.ResizeWithFramebuffer) + { + Size = size; + } } if (Config.MainFormStayOnTop) TopMost = true; @@ -1395,8 +1388,12 @@ namespace BizHawk.Client.EmuHawk AddOnScreenMessage($"{fi.Name} saved."); } - public void FrameBufferResized() + public void FrameBufferResized(bool forceWindowResize = false) { + if (!Config.ResizeWithFramebuffer && !forceWindowResize) + { + return; + } // run this entire thing exactly twice, since the first resize may adjust the menu stacking for (int i = 0; i < 2; i++) { @@ -2422,20 +2419,16 @@ namespace BizHawk.Client.EmuHawk { if (Config.SaveWindowPosition) { - if (Config.MainWndx != -32000) // When minimized location is -32000, don't save this into the config file! + if (WindowState is FormWindowState.Normal) { - Config.MainWndx = Location.X; - } - - if (Config.MainWndy != -32000) - { - Config.MainWndy = Location.Y; + Config.MainWindowPosition = Location; + Config.MainWindowSize = Size; } } else { - Config.MainWndx = -1; - Config.MainWndy = -1; + Config.MainWindowPosition = null; + Config.MainWindowSize = null; } Config.LastWrittenFrom = VersionInfo.MainVersion; @@ -2591,7 +2584,7 @@ namespace BizHawk.Client.EmuHawk Config.SetWindowScaleFor(Emulator.SystemId, windowScale); } AddOnScreenMessage($"Screensize set to {windowScale}x"); - FrameBufferResized(); + FrameBufferResized(forceWindowResize: true); } private void DecreaseWindowSize() @@ -2603,7 +2596,7 @@ namespace BizHawk.Client.EmuHawk Config.SetWindowScaleFor(Emulator.SystemId, windowScale); } AddOnScreenMessage($"Screensize set to {windowScale}x"); - FrameBufferResized(); + FrameBufferResized(forceWindowResize: true); } private static readonly int[] SpeedPercents = { 1, 3, 6, 12, 25, 50, 75, 100, 150, 200, 300, 400, 800, 1600, 3200, 6400 }; diff --git a/src/BizHawk.Tests/Client.Common/config/SerializationStabilityTests.cs b/src/BizHawk.Tests/Client.Common/config/SerializationStabilityTests.cs index 3e14ad78d1..2e41605caa 100644 --- a/src/BizHawk.Tests/Client.Common/config/SerializationStabilityTests.cs +++ b/src/BizHawk.Tests/Client.Common/config/SerializationStabilityTests.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Drawing; using System.Reflection; using BizHawk.Client.Common; @@ -32,8 +33,10 @@ namespace BizHawk.Tests.Client.Common.config typeof(List<>), typeof(Nullable<>), typeof(object), + typeof(Point), typeof(Queue<>), typeof(float), + typeof(Size), typeof(string), };