diff --git a/Core/Console.cpp b/Core/Console.cpp index f746373f..fa4f72f3 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -101,7 +101,7 @@ bool Console::Initialize(VirtualFile &romFile, VirtualFile &patchFile) if(mapper) { if(_mapper) { //Send notification only if a game was already running and we successfully loaded the new one - MessageManager::SendNotification(ConsoleNotificationType::GameStopped); + MessageManager::SendNotification(ConsoleNotificationType::GameStopped, (void*)1); } if(_romFilepath != (string)romFile || _patchFilename != (string)patchFile) { diff --git a/Core/IRenderingDevice.h b/Core/IRenderingDevice.h index 68ea2436..a8612eab 100644 --- a/Core/IRenderingDevice.h +++ b/Core/IRenderingDevice.h @@ -9,4 +9,5 @@ class IRenderingDevice virtual void UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height) = 0; virtual void Render() = 0; virtual void Reset() = 0; + virtual void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) = 0; }; \ No newline at end of file diff --git a/GUI.NET/Config/VideoInfo.cs b/GUI.NET/Config/VideoInfo.cs index d1951c6d..02682206 100644 --- a/GUI.NET/Config/VideoInfo.cs +++ b/GUI.NET/Config/VideoInfo.cs @@ -51,6 +51,7 @@ namespace Mesen.GUI.Config public bool ForceSpritesFirstColumn = false; public bool FullscreenForceIntegerScale = false; + public bool UseExclusiveFullscreen = false; public bool UseCustomVsPalette = false; public bool ShowColorIndexes = true; diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml index 5111a70c..09253f45 100644 --- a/GUI.NET/Dependencies/resources.ca.xml +++ b/GUI.NET/Dependencies/resources.ca.xml @@ -256,6 +256,7 @@ Fes servir valors enters d'escalat al mode de pantalla completa Mostra els FPS Fes servir els paquets d'alta resolució d'HDNes + Use exclusive fullscreen mode Sobreescaneig Retall de vídeo Esquerra diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index 82cdbb0f..e78d442f 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -256,6 +256,7 @@ Utilizar valores enteros de escalado en modo de pantalla completa Mostrar FPS Utilizar los paquetes de alta resolución de HDNes + Use exclusive fullscreen mode Overscan Recorte Izquierda diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index 3b9dd458..69b88da6 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -259,6 +259,7 @@ Utiliser une valeur entière pour l'échelle vidéo en mode plein écran Afficher le FPS Utiliser les packs haute-définition de HDNes + Utiliser le mode plein écran exclusif Overscan Overscan Gauche diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index 80c32b12..73ab27b8 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -260,6 +260,7 @@ 全画面表示モードに入る時、画面サイズの倍率を整数にする フレームレート表示 HDNesのHDパックを使う + 排他的なフルスクリーンモードを使う オーバースキャン オーバースキャン diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index 37ae53f9..225f26cb 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -256,6 +256,7 @@ Usar valores de escala inteira ao entrar no modo de tela cheia Mostrar FPS Usar os pacotes de alta definição do HDNes + Use exclusive fullscreen mode Overscan Recorte Esquerda diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index 97ac0312..01997852 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -258,6 +258,7 @@ Use integer scale values when entering fullscreen mode Показывать FPS Использовать HDNes HD packs + Use exclusive fullscreen mode Overscan Overscan Слева diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index 585b9474..82dec56e 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -258,6 +258,7 @@ Використовуйте цілі значення масштабу при введенні повноекранного режиму Показувати FPS Використовувати HDNes HD packs + Use exclusive fullscreen mode Overscan Overscan Злiва diff --git a/GUI.NET/Forms/BaseInputForm.cs b/GUI.NET/Forms/BaseInputForm.cs new file mode 100644 index 00000000..287be3fa --- /dev/null +++ b/GUI.NET/Forms/BaseInputForm.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Mesen.GUI.Forms +{ + public class BaseInputForm : BaseForm, IMessageFilter + { + private static Stack
_inputForms = new Stack(); + + private const int WM_KEYDOWN = 0x100; + private const int WM_KEYUP = 0x101; + private const int WM_SYSKEYDOWN = 0x104; + private const int WM_SYSKEYUP = 0x105; + private Timer _tmrUpdateBackground; + + public BaseInputForm() + { + if(!this.DesignMode) { + _inputForms.Push(this); + Application.AddMessageFilter(this); + this._tmrUpdateBackground = new Timer(); + this._tmrUpdateBackground.Start(); + this._tmrUpdateBackground.Tick += tmrUpdateBackground_Tick; + } + } + + bool IMessageFilter.PreFilterMessage(ref Message m) + { + if(this.ContainsFocus) { + if(m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP) { + int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); + InteropEmu.SetKeyState(scanCode, false); + } else if(m.Msg == WM_SYSKEYDOWN || m.Msg == WM_KEYDOWN) { + int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); + InteropEmu.SetKeyState(scanCode, true); + } + } + return false; + } + + protected override void OnFormClosed(FormClosedEventArgs e) + { + base.OnFormClosed(e); + Application.RemoveMessageFilter(this); + _tmrUpdateBackground.Stop(); + _tmrUpdateBackground.Dispose(); + _inputForms.Pop(); + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + if(Program.IsMono) { + //Mono does not trigger the activate/deactivate events when opening a modal popup, but it does set the form to disabled + //Use this to reset key states + this.EnabledChanged += (object s, EventArgs evt) => { + InteropEmu.ResetKeyState(); + }; + } + } + + protected override void OnDeactivate(EventArgs e) + { + base.OnDeactivate(e); + InteropEmu.ResetKeyState(); + } + + protected override void OnActivated(EventArgs e) + { + base.OnActivated(e); + InteropEmu.ResetKeyState(); + } + + private void tmrUpdateBackground_Tick(object sender, EventArgs e) + { + UpdateFocusFlag(); + } + + private void UpdateFocusFlag() + { + if(_inputForms.Peek() == this) { + InteropEmu.SetFlag(EmulationFlags.InBackground, !this.ContainsFocus); + } + } + } +} diff --git a/GUI.NET/Forms/BaseInputForm.resx b/GUI.NET/Forms/BaseInputForm.resx new file mode 100644 index 00000000..5f270f99 --- /dev/null +++ b/GUI.NET/Forms/BaseInputForm.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 107, 17 + + \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmGetKey.cs b/GUI.NET/Forms/Config/frmGetKey.cs index 3ec61611..0e55c8d7 100644 --- a/GUI.NET/Forms/Config/frmGetKey.cs +++ b/GUI.NET/Forms/Config/frmGetKey.cs @@ -10,14 +10,12 @@ using System.Windows.Forms; namespace Mesen.GUI.Forms.Config { - public partial class frmGetKey : BaseForm, IMessageFilter + public partial class frmGetKey : BaseInputForm { - const int WM_KEYDOWN = 0x100; - const int WM_KEYUP = 0x101; - const int WM_SYSKEYDOWN = 0x104; - const int WM_SYSKEYUP = 0x105; - private bool _singleKeyMode = false; + private List _prevScanCodes = new List(); + + public KeyCombination ShortcutKey { get; set; } public frmGetKey(bool singleKeyMode) { @@ -37,36 +35,14 @@ namespace Mesen.GUI.Forms.Config //Prevent other keybindings from interfering/activating InteropEmu.DisableAllKeys(true); - - Application.AddMessageFilter(this); - } - - bool IMessageFilter.PreFilterMessage(ref Message m) - { - if(m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP) { - int virtualKeyCode = (Int32)m.WParam; - int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); - InteropEmu.SetKeyState(scanCode, false); - } else if(m.Msg == WM_SYSKEYDOWN || m.Msg == WM_KEYDOWN) { - int virtualKeyCode = (Int32)((Int64)m.WParam & 0xFF); - int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); - InteropEmu.SetKeyState(scanCode, true); - } - - return false; } protected override void OnFormClosing(FormClosingEventArgs e) { - Application.RemoveMessageFilter(this); - InteropEmu.ResetKeyState(); InteropEmu.DisableAllKeys(false); base.OnFormClosing(e); } - - public KeyCombination ShortcutKey { get; set; } - private List _prevScanCodes = new List(); - + private void tmrCheckKey_Tick(object sender, EventArgs e) { List scanCodes = InteropEmu.GetPressedKeys(); diff --git a/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs b/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs index 18dcc87e..3867292c 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs @@ -44,6 +44,7 @@ namespace Mesen.GUI.Forms.Config this.nudCustomRatio = new Mesen.GUI.Controls.MesenNumericUpDown(); this.chkFullscreenForceIntegerScale = new System.Windows.Forms.CheckBox(); this.chkShowFps = new System.Windows.Forms.CheckBox(); + this.chkUseExclusiveFullscreen = new System.Windows.Forms.CheckBox(); this.chkIntegerFpsMode = new System.Windows.Forms.CheckBox(); this.tabMain = new System.Windows.Forms.TabControl(); this.tpgGeneral = new System.Windows.Forms.TabPage(); @@ -108,6 +109,8 @@ namespace Mesen.GUI.Forms.Config this.chkDisableSprites = new Mesen.GUI.Controls.ctrlRiskyOption(); this.chkForceBackgroundFirstColumn = new Mesen.GUI.Controls.ctrlRiskyOption(); this.chkForceSpritesFirstColumn = new Mesen.GUI.Controls.ctrlRiskyOption(); + this.lblScreenRotation = new System.Windows.Forms.Label(); + this.cboScreenRotation = new System.Windows.Forms.ComboBox(); this.contextPicturePresets = new System.Windows.Forms.ContextMenuStrip(this.components); this.mnuPresetComposite = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPresetSVideo = new System.Windows.Forms.ToolStripMenuItem(); @@ -125,8 +128,6 @@ namespace Mesen.GUI.Forms.Config this.mnuPaletteSonyCxa2025As = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPaletteUnsaturated = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPaletteYuv = new System.Windows.Forms.ToolStripMenuItem(); - this.lblScreenRotation = new System.Windows.Forms.Label(); - this.cboScreenRotation = new System.Windows.Forms.ComboBox(); this.tlpMain.SuspendLayout(); this.flowLayoutPanel7.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picHdNesTooltip)).BeginInit(); @@ -173,17 +174,18 @@ namespace Mesen.GUI.Forms.Config this.tlpMain.Controls.Add(this.lblVideoScale, 0, 0); this.tlpMain.Controls.Add(this.chkVerticalSync, 0, 3); this.tlpMain.Controls.Add(this.lblDisplayRatio, 0, 1); - this.tlpMain.Controls.Add(this.flowLayoutPanel7, 0, 4); + this.tlpMain.Controls.Add(this.flowLayoutPanel7, 0, 6); this.tlpMain.Controls.Add(this.nudScale, 1, 0); this.tlpMain.Controls.Add(this.flowLayoutPanel6, 1, 1); this.tlpMain.Controls.Add(this.chkFullscreenForceIntegerScale, 0, 5); - this.tlpMain.Controls.Add(this.chkShowFps, 0, 6); + this.tlpMain.Controls.Add(this.chkShowFps, 0, 7); + this.tlpMain.Controls.Add(this.chkUseExclusiveFullscreen, 0, 4); this.tlpMain.Controls.Add(this.chkIntegerFpsMode, 0, 2); this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill; this.tlpMain.Location = new System.Drawing.Point(3, 3); this.tlpMain.Margin = new System.Windows.Forms.Padding(0); this.tlpMain.Name = "tlpMain"; - this.tlpMain.RowCount = 8; + this.tlpMain.RowCount = 9; 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()); @@ -192,6 +194,7 @@ namespace Mesen.GUI.Forms.Config 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.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tlpMain.Size = new System.Drawing.Size(521, 370); this.tlpMain.TabIndex = 1; // @@ -233,7 +236,7 @@ namespace Mesen.GUI.Forms.Config this.flowLayoutPanel7.Controls.Add(this.chkUseHdPacks); this.flowLayoutPanel7.Controls.Add(this.picHdNesTooltip); this.flowLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill; - this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 92); + this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 138); this.flowLayoutPanel7.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel7.Name = "flowLayoutPanel7"; this.flowLayoutPanel7.Size = new System.Drawing.Size(521, 23); @@ -381,13 +384,25 @@ namespace Mesen.GUI.Forms.Config this.chkShowFps.Anchor = System.Windows.Forms.AnchorStyles.Left; this.chkShowFps.AutoSize = true; this.tlpMain.SetColumnSpan(this.chkShowFps, 2); - this.chkShowFps.Location = new System.Drawing.Point(3, 141); + this.chkShowFps.Location = new System.Drawing.Point(3, 164); this.chkShowFps.Name = "chkShowFps"; this.chkShowFps.Size = new System.Drawing.Size(76, 17); this.chkShowFps.TabIndex = 9; this.chkShowFps.Text = "Show FPS"; this.chkShowFps.UseVisualStyleBackColor = true; // + // chkUseExclusiveFullscreen + // + this.chkUseExclusiveFullscreen.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkUseExclusiveFullscreen.AutoSize = true; + this.tlpMain.SetColumnSpan(this.chkUseExclusiveFullscreen, 2); + this.chkUseExclusiveFullscreen.Location = new System.Drawing.Point(3, 95); + this.chkUseExclusiveFullscreen.Name = "chkUseExclusiveFullscreen"; + this.chkUseExclusiveFullscreen.Size = new System.Drawing.Size(169, 17); + this.chkUseExclusiveFullscreen.TabIndex = 24; + this.chkUseExclusiveFullscreen.Text = "Use exclusive fullscreen mode"; + this.chkUseExclusiveFullscreen.UseVisualStyleBackColor = true; + // // chkIntegerFpsMode // this.chkIntegerFpsMode.Anchor = System.Windows.Forms.AnchorStyles.Left; @@ -1358,6 +1373,25 @@ namespace Mesen.GUI.Forms.Config this.chkForceSpritesFirstColumn.TabIndex = 3; this.chkForceSpritesFirstColumn.Text = "Force sprite display in first column"; // + // lblScreenRotation + // + this.lblScreenRotation.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblScreenRotation.AutoSize = true; + this.lblScreenRotation.Location = new System.Drawing.Point(3, 7); + this.lblScreenRotation.Name = "lblScreenRotation"; + this.lblScreenRotation.Size = new System.Drawing.Size(87, 13); + this.lblScreenRotation.TabIndex = 4; + this.lblScreenRotation.Text = "Screen Rotation:"; + // + // cboScreenRotation + // + this.cboScreenRotation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboScreenRotation.FormattingEnabled = true; + this.cboScreenRotation.Location = new System.Drawing.Point(96, 3); + this.cboScreenRotation.Name = "cboScreenRotation"; + this.cboScreenRotation.Size = new System.Drawing.Size(77, 21); + this.cboScreenRotation.TabIndex = 5; + // // contextPicturePresets // this.contextPicturePresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1481,25 +1515,6 @@ namespace Mesen.GUI.Forms.Config this.mnuPaletteYuv.Text = "YUV v3 (by FirebrandX)"; this.mnuPaletteYuv.Click += new System.EventHandler(this.mnuPaletteYuv_Click); // - // lblScreenRotation - // - this.lblScreenRotation.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.lblScreenRotation.AutoSize = true; - this.lblScreenRotation.Location = new System.Drawing.Point(3, 7); - this.lblScreenRotation.Name = "lblScreenRotation"; - this.lblScreenRotation.Size = new System.Drawing.Size(87, 13); - this.lblScreenRotation.TabIndex = 4; - this.lblScreenRotation.Text = "Screen Rotation:"; - // - // cboScreenRotation - // - this.cboScreenRotation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboScreenRotation.FormattingEnabled = true; - this.cboScreenRotation.Location = new System.Drawing.Point(96, 3); - this.cboScreenRotation.Name = "cboScreenRotation"; - this.cboScreenRotation.Size = new System.Drawing.Size(77, 21); - this.cboScreenRotation.TabIndex = 5; - // // frmVideoConfig // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1663,5 +1678,6 @@ namespace Mesen.GUI.Forms.Config private System.Windows.Forms.CheckBox chkIntegerFpsMode; private System.Windows.Forms.Label lblScreenRotation; private System.Windows.Forms.ComboBox cboScreenRotation; + private System.Windows.Forms.CheckBox chkUseExclusiveFullscreen; } } \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmVideoConfig.cs b/GUI.NET/Forms/Config/frmVideoConfig.cs index ddbdadcb..9a614284 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.cs @@ -66,6 +66,7 @@ namespace Mesen.GUI.Forms.Config AddBinding("ForceBackgroundFirstColumn", chkForceBackgroundFirstColumn); AddBinding("ForceSpritesFirstColumn", chkForceSpritesFirstColumn); AddBinding("FullscreenForceIntegerScale", chkFullscreenForceIntegerScale); + AddBinding("UseExclusiveFullscreen", chkUseExclusiveFullscreen); AddBinding("UseCustomVsPalette", chkUseCustomVsPalette); @@ -83,6 +84,11 @@ namespace Mesen.GUI.Forms.Config ResourceHelper.ApplyResources(this, contextPaletteList); ResourceHelper.ApplyResources(this, contextPicturePresets); + + if(Program.IsMono) { + //Not available in the linux build (for now) + chkUseExclusiveFullscreen.Visible = false; + } } private void UpdatePalette() diff --git a/GUI.NET/Forms/MesenMsgBox.cs b/GUI.NET/Forms/MesenMsgBox.cs index add64cc5..082f74f0 100644 --- a/GUI.NET/Forms/MesenMsgBox.cs +++ b/GUI.NET/Forms/MesenMsgBox.cs @@ -20,7 +20,7 @@ namespace Mesen.GUI.Forms return MessageBox.Show(string.Format("Critical error (" + text + ")"), "Mesen", buttons, icon); } } else { - return MessageBox.Show(ResourceHelper.GetMessage(text, args), "Mesen", buttons, icon); + return MessageBox.Show(Application.OpenForms[0], ResourceHelper.GetMessage(text, args), "Mesen", buttons, icon); } } } diff --git a/GUI.NET/Forms/frmFullscreenRenderer.cs b/GUI.NET/Forms/frmFullscreenRenderer.cs new file mode 100644 index 00000000..48d507ac --- /dev/null +++ b/GUI.NET/Forms/frmFullscreenRenderer.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Mesen.GUI.Forms +{ + public class frmFullscreenRenderer : BaseInputForm + { + private const int LeftMouseButtonKeyCode = 0x200; + private const int RightMouseButtonKeyCode = 0x201; + private const int MiddleMouseButtonKeyCode = 0x202; + private bool _closing = false; + + public frmFullscreenRenderer() + { + this.BackColor = Color.Black; + this.Text = "Mesen Fullscreen Window"; + this.FormBorderStyle = FormBorderStyle.None; + this.WindowState = FormWindowState.Maximized; + } + + protected override void OnFormClosing(FormClosingEventArgs e) + { + _closing = true; + base.OnFormClosing(e); + } + + protected override void OnDeactivate(EventArgs e) + { + base.OnDeactivate(e); + + if(!_closing) { + //Close fullscreen mode if window loses focus + this.Close(); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + SetMouseButtonState(Control.MouseButtons); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + SetMouseButtonState(Control.MouseButtons); + } + + private void SetMouseButtonState(MouseButtons pressedButtons) + { + InteropEmu.SetKeyState(LeftMouseButtonKeyCode, pressedButtons.HasFlag(MouseButtons.Left)); + InteropEmu.SetKeyState(RightMouseButtonKeyCode, pressedButtons.HasFlag(MouseButtons.Right)); + InteropEmu.SetKeyState(MiddleMouseButtonKeyCode, pressedButtons.HasFlag(MouseButtons.Middle)); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + InteropEmu.ScreenSize size = InteropEmu.GetScreenSize(false); + int leftMargin = (this.Width - size.Width) / 2; + int topMargin = (this.Height - size.Height) / 2; + + CursorManager.OnMouseMove(this); + + if(CursorManager.NeedMouseIcon) { + this.Cursor = Cursors.Cross; + } + + double xPos = (double)(e.X - leftMargin) / size.Width; + double yPos = (double)(e.Y - topMargin) / size.Height; + + xPos = Math.Max(0.0, Math.Min(1.0, xPos)); + yPos = Math.Max(0.0, Math.Min(1.0, yPos)); + + InteropEmu.SetMousePosition(xPos, yPos); + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + CursorManager.OnMouseLeave(); + InteropEmu.SetMousePosition(-1, -1); + } + } +} diff --git a/GUI.NET/Forms/frmMain.File.cs b/GUI.NET/Forms/frmMain.File.cs index 8aacdd82..fa6c5095 100644 --- a/GUI.NET/Forms/frmMain.File.cs +++ b/GUI.NET/Forms/frmMain.File.cs @@ -95,7 +95,7 @@ namespace Mesen.GUI.Forms using(OpenFileDialog ofd = new OpenFileDialog()) { ofd.InitialDirectory = ConfigManager.SaveStateFolder; ofd.SetFilter(ResourceHelper.GetMessage("FilterSavestate")); - if(ofd.ShowDialog() == DialogResult.OK) { + if(ofd.ShowDialog(this) == DialogResult.OK) { InteropEmu.LoadStateFile(ofd.FileName); } } @@ -109,7 +109,7 @@ namespace Mesen.GUI.Forms sfd.InitialDirectory = ConfigManager.SaveStateFolder; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mst"; sfd.SetFilter(ResourceHelper.GetMessage("FilterSavestate")); - if(sfd.ShowDialog() == DialogResult.OK) { + if(sfd.ShowDialog(this) == DialogResult.OK) { InteropEmu.SaveStateFile(sfd.FileName); } } @@ -137,7 +137,7 @@ namespace Mesen.GUI.Forms ofd.InitialDirectory = ConfigManager.Config.RecentFiles[0].RomFile.Folder; } - if(ofd.ShowDialog() == DialogResult.OK) { + if(ofd.ShowDialog(this) == DialogResult.OK) { LoadFile(ofd.FileName); } } @@ -196,7 +196,7 @@ namespace Mesen.GUI.Forms ofd.InitialDirectory = ConfigManager.Config.RecentFiles[0].RomFile.Folder; } - if(ofd.ShowDialog() == DialogResult.OK) { + if(ofd.ShowDialog(this) == DialogResult.OK) { LoadROM(ofd.FileName, true, patchFile); } } diff --git a/GUI.NET/Forms/frmMain.Game.cs b/GUI.NET/Forms/frmMain.Game.cs index 18da396e..db213012 100644 --- a/GUI.NET/Forms/frmMain.Game.cs +++ b/GUI.NET/Forms/frmMain.Game.cs @@ -80,7 +80,7 @@ namespace Mesen.GUI.Forms ofd.SetFilter(ResourceHelper.GetMessage("FilterTapeFiles")); ofd.InitialDirectory = ConfigManager.SaveFolder; ofd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".fbt"; - if(ofd.ShowDialog() == DialogResult.OK) { + if(ofd.ShowDialog(this) == DialogResult.OK) { InteropEmu.LoadTapeFile(ofd.FileName); } } @@ -92,7 +92,7 @@ namespace Mesen.GUI.Forms sfd.SetFilter(ResourceHelper.GetMessage("FilterTapeFiles")); sfd.InitialDirectory = ConfigManager.SaveFolder; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".fbt"; - if(sfd.ShowDialog() == DialogResult.OK) { + if(sfd.ShowDialog(this) == DialogResult.OK) { InteropEmu.StartRecordingTapeFile(sfd.FileName); } } diff --git a/GUI.NET/Forms/frmMain.Help.cs b/GUI.NET/Forms/frmMain.Help.cs index 27f05c42..882532db 100644 --- a/GUI.NET/Forms/frmMain.Help.cs +++ b/GUI.NET/Forms/frmMain.Help.cs @@ -101,7 +101,7 @@ namespace Mesen.GUI.Forms private void mnuAbout_Click(object sender, EventArgs e) { using(frmAbout frm = new frmAbout()) { - frm.ShowDialog(); + frm.ShowDialog(this); } } diff --git a/GUI.NET/Forms/frmMain.Options.cs b/GUI.NET/Forms/frmMain.Options.cs index b4d52271..b35b2f44 100644 --- a/GUI.NET/Forms/frmMain.Options.cs +++ b/GUI.NET/Forms/frmMain.Options.cs @@ -85,7 +85,7 @@ namespace Mesen.GUI.Forms Configuration configBackup = ConfigManager.Config.Clone(); bool cancelled = false; using(frmVideoConfig frm = new frmVideoConfig()) { - cancelled = frm.ShowDialog(sender) == DialogResult.Cancel; + cancelled = frm.ShowDialog(sender, this) == DialogResult.Cancel; } if(cancelled) { ConfigManager.RevertToBackup(configBackup); @@ -96,19 +96,25 @@ namespace Mesen.GUI.Forms if((cancelled || (screenSize.Height == originalScreenSize.Height && screenSize.Width == originalScreenSize.Width)) && this.WindowState == FormWindowState.Normal) { this.Size = originalSize; } + if(_fullscreenMode && ConfigManager.Config.VideoInfo.UseExclusiveFullscreen && _frmFullscreenRenderer == null) { + StopFullscreenWindowMode(); + if(!this._isNsfPlayerMode) { + SetFullscreenState(true); + } + } } private void mnuInput_Click(object sender, EventArgs e) { using(frmInputConfig frm = new frmInputConfig()) { - frm.ShowDialog(sender); + frm.ShowDialog(sender, this); } } private void mnuAudioConfig_Click(object sender, EventArgs e) { using(frmAudioConfig frm = new frmAudioConfig()) { - frm.ShowDialog(sender); + frm.ShowDialog(sender, this); } this.ctrlNsfPlayer.UpdateVolume(); } @@ -116,7 +122,7 @@ namespace Mesen.GUI.Forms private void mnuPreferences_Click(object sender, EventArgs e) { using(frmPreferences frm = new frmPreferences()) { - if(frm.ShowDialog(sender) == DialogResult.OK) { + if(frm.ShowDialog(sender, this) == DialogResult.OK) { ResourceHelper.LoadResources(ConfigManager.Config.PreferenceInfo.DisplayLanguage); ResourceHelper.UpdateEmuLanguage(); ResourceHelper.ApplyResources(this); @@ -137,7 +143,7 @@ namespace Mesen.GUI.Forms private void mnuEmulationConfig_Click(object sender, EventArgs e) { using(frmEmulationConfig frm = new frmEmulationConfig()) { - frm.ShowDialog(sender); + frm.ShowDialog(sender, this); } } diff --git a/GUI.NET/Forms/frmMain.Tests.cs b/GUI.NET/Forms/frmMain.Tests.cs index 9427e300..a859273a 100644 --- a/GUI.NET/Forms/frmMain.Tests.cs +++ b/GUI.NET/Forms/frmMain.Tests.cs @@ -18,7 +18,7 @@ namespace Mesen.GUI.Forms ofd.SetFilter(ResourceHelper.GetMessage("FilterTest")); ofd.InitialDirectory = ConfigManager.TestFolder; ofd.Multiselect = true; - if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { List passedTests = new List(); List failedTests = new List(); List failedFrameCount = new List(); @@ -79,7 +79,7 @@ namespace Mesen.GUI.Forms sfd.SetFilter(ResourceHelper.GetMessage("FilterTest")); sfd.InitialDirectory = ConfigManager.TestFolder; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mtp"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.RomTestRecord(sfd.FileName, resetEmu); } } @@ -90,12 +90,12 @@ namespace Mesen.GUI.Forms using(OpenFileDialog ofd = new OpenFileDialog()) { ofd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); ofd.InitialDirectory = ConfigManager.MovieFolder; - if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { SaveFileDialog sfd = new SaveFileDialog(); sfd.SetFilter(ResourceHelper.GetMessage("FilterTest")); sfd.InitialDirectory = ConfigManager.TestFolder; sfd.FileName = Path.GetFileNameWithoutExtension(ofd.FileName) + ".mtp"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.RomTestRecordFromMovie(sfd.FileName, ofd.FileName); } } @@ -108,12 +108,12 @@ namespace Mesen.GUI.Forms ofd.SetFilter(ResourceHelper.GetMessage("FilterTest")); ofd.InitialDirectory = ConfigManager.TestFolder; - if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { SaveFileDialog sfd = new SaveFileDialog(); sfd.SetFilter(ResourceHelper.GetMessage("FilterTest")); sfd.InitialDirectory = ConfigManager.TestFolder; sfd.FileName = Path.GetFileNameWithoutExtension(ofd.FileName) + ".mtp"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.RomTestRecordFromTest(sfd.FileName, ofd.FileName); } } @@ -124,7 +124,7 @@ namespace Mesen.GUI.Forms { using(OpenFileDialog ofd = new OpenFileDialog()) { ofd.SetFilter("*.nes|*.nes"); - if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { string filename = ofd.FileName; Task.Run(() => { diff --git a/GUI.NET/Forms/frmMain.Tools.cs b/GUI.NET/Forms/frmMain.Tools.cs index 98e753c7..0c329cee 100644 --- a/GUI.NET/Forms/frmMain.Tools.cs +++ b/GUI.NET/Forms/frmMain.Tools.cs @@ -33,7 +33,7 @@ namespace Mesen.GUI.Forms sfd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); sfd.InitialDirectory = ConfigManager.MovieFolder; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.MovieRecord(sfd.FileName, resetEmu); } } @@ -44,7 +44,7 @@ namespace Mesen.GUI.Forms using(OpenFileDialog ofd = new OpenFileDialog()) { ofd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); ofd.InitialDirectory = ConfigManager.MovieFolder; - if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.MoviePlay(ofd.FileName); } } @@ -71,7 +71,7 @@ namespace Mesen.GUI.Forms sfd.SetFilter(ResourceHelper.GetMessage("FilterWave")); sfd.InitialDirectory = ConfigManager.WaveFolder; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".wav"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { + if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.WaveRecord(sfd.FileName); } } @@ -85,7 +85,7 @@ namespace Mesen.GUI.Forms private void mnuAviRecord_Click(object sender, EventArgs e) { using(frmRecordAvi frm = new frmRecordAvi()) { - if(frm.ShowDialog(mnuVideoRecorder) == DialogResult.OK) { + if(frm.ShowDialog(mnuVideoRecorder, this) == DialogResult.OK) { InteropEmu.AviRecord(frm.Filename, ConfigManager.Config.AviRecordInfo.Codec, ConfigManager.Config.AviRecordInfo.CompressionLevel); } } @@ -166,7 +166,7 @@ namespace Mesen.GUI.Forms Task.Run(() => InteropEmu.StopServer()); } else { using(frmServerConfig frm = new frmServerConfig()) { - if(frm.ShowDialog(sender) == System.Windows.Forms.DialogResult.OK) { + if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) { InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port, ConfigManager.Config.Profile.PlayerName); } } @@ -179,7 +179,7 @@ namespace Mesen.GUI.Forms Task.Run(() => InteropEmu.Disconnect()); } else { using(frmClientConfig frm = new frmClientConfig()) { - if(frm.ShowDialog(sender) == System.Windows.Forms.DialogResult.OK) { + if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) { Task.Run(() => { InteropEmu.Connect(ConfigManager.Config.ClientConnectionInfo.Host, ConfigManager.Config.ClientConnectionInfo.Port, ConfigManager.Config.Profile.PlayerName, ConfigManager.Config.ClientConnectionInfo.Spectator); }); @@ -191,7 +191,7 @@ namespace Mesen.GUI.Forms private void mnuProfile_Click(object sender, EventArgs e) { using(frmPlayerProfile frm = new frmPlayerProfile()) { - frm.ShowDialog(sender); + frm.ShowDialog(sender, this); } } diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index fce3175e..9033af4d 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -19,16 +19,12 @@ using Mesen.GUI.Forms.Config; using Mesen.GUI.Forms.HdPackEditor; using Mesen.GUI.Forms.NetPlay; using Mesen.GUI.GoogleDriveIntegration; +using Mesen.GUI.Properties; namespace Mesen.GUI.Forms { - public partial class frmMain : BaseForm, IMessageFilter + public partial class frmMain : BaseInputForm { - private const int WM_KEYDOWN = 0x100; - private const int WM_KEYUP = 0x101; - const int WM_SYSKEYDOWN = 0x104; - const int WM_SYSKEYUP = 0x105; - private InteropEmu.NotificationListener _notifListener; private Thread _emuThread; private frmLogWindow _logWindow; @@ -46,13 +42,14 @@ namespace Mesen.GUI.Forms private bool _isNsfPlayerMode = false; private object _loadRomLock = new object(); private int _romLoadCounter = 0; - private bool _removeFocus = false; private bool _showUpgradeMessage = false; private float _xFactor = 1; private float _yFactor = 1; private bool _enableResize = false; private bool _overrideWindowSize = false; + private frmFullscreenRenderer _frmFullscreenRenderer = null; + private Dictionary> _actionEnabledFuncs = new Dictionary>(); private string[] _commandLineArgs; @@ -186,29 +183,6 @@ namespace Mesen.GUI.Forms if(ConfigManager.Config.WindowSize.HasValue && !_overrideWindowSize) { this.ClientSize = ConfigManager.Config.WindowSize.Value; } - - if(Program.IsMono) { - //Mono does not trigger the activate/deactivate events when opening a modal popup, but it does set the form to disabled - //Use this to reset key states - this.EnabledChanged += (object s, EventArgs evt) => { - _removeFocus = !this.Enabled; - InteropEmu.ResetKeyState(); - }; - } - } - - protected override void OnDeactivate(EventArgs e) - { - base.OnDeactivate(e); - _removeFocus = true; - InteropEmu.ResetKeyState(); - } - - protected override void OnActivated(EventArgs e) - { - base.OnActivated(e); - _removeFocus = false; - InteropEmu.ResetKeyState(); } protected override void OnShown(EventArgs e) @@ -283,7 +257,7 @@ namespace Mesen.GUI.Forms void InitializeEmu() { - InteropEmu.InitializeEmu(ConfigManager.HomeFolder, this.Handle, this.ctrlRenderer.Handle, _noAudio, _noVideo, _noInput); + InteropEmu.InitializeEmu(ConfigManager.HomeFolder, this.Handle, ctrlRenderer.Handle, _noAudio, _noVideo, _noInput); if(ConfigManager.Config.PreferenceInfo.OverrideGameFolder && Directory.Exists(ConfigManager.Config.PreferenceInfo.GameFolder)) { InteropEmu.AddKnownGameFolder(ConfigManager.Config.PreferenceInfo.GameFolder); } @@ -349,47 +323,108 @@ namespace Mesen.GUI.Forms } } - private void SetScaleBasedOnWindowSize() + private void SetScaleBasedOnDimensions(Size dimensions) { _customSize = true; InteropEmu.ScreenSize size = InteropEmu.GetScreenSize(true); - double verticalScale = (double)panelRenderer.ClientSize.Height / size.Height; - double horizontalScale = (double)panelRenderer.ClientSize.Width / size.Width; + double verticalScale = (double)dimensions.Height / size.Height; + double horizontalScale = (double)dimensions.Width / size.Width; double scale = Math.Min(verticalScale, horizontalScale); - if(_fullscreenMode && ConfigManager.Config.VideoInfo.FullscreenForceIntegerScale) { + if(ConfigManager.Config.VideoInfo.FullscreenForceIntegerScale) { scale = Math.Floor(scale); } UpdateScaleMenu(scale); VideoInfo.ApplyConfig(); } + private void SetScaleBasedOnWindowSize() + { + SetScaleBasedOnDimensions(panelRenderer.ClientSize); + } + + private void SetScaleBasedOnScreenSize() + { + SetScaleBasedOnDimensions(Screen.FromControl(this).Bounds.Size); + } + + private void StopExclusiveFullscreenMode() + { + if(_frmFullscreenRenderer != null) { + _frmFullscreenRenderer.Close(); + } + } + + private void StartExclusiveFullscreenMode() + { + Size screenSize = Screen.FromControl(this).Bounds.Size; + _frmFullscreenRenderer = new frmFullscreenRenderer(); + _frmFullscreenRenderer.Shown += (object sender, EventArgs e) => { + ctrlRenderer.Visible = false; + SetScaleBasedOnScreenSize(); + InteropEmu.SetFullscreenMode(true, _frmFullscreenRenderer.Handle, (UInt32)screenSize.Width, (UInt32)screenSize.Height); + }; + _frmFullscreenRenderer.FormClosing += (object sender, FormClosingEventArgs e) => { + InteropEmu.SetFullscreenMode(false, ctrlRenderer.Handle, (UInt32)screenSize.Width, (UInt32)screenSize.Height); + _frmFullscreenRenderer = null; + ctrlRenderer.Visible = true; + _fullscreenMode = false; + frmMain_Resize(null, EventArgs.Empty); + }; + _frmFullscreenRenderer.Show(); + } + + private void StartFullscreenWindowMode() + { + this.menuStrip.Visible = false; + _originalWindowState = this.WindowState; + this.WindowState = FormWindowState.Normal; + this.FormBorderStyle = FormBorderStyle.None; + this.WindowState = FormWindowState.Maximized; + SetScaleBasedOnWindowSize(); + } + + private void StopFullscreenWindowMode() + { + this.menuStrip.Visible = true; + this.WindowState = _originalWindowState; + this.FormBorderStyle = FormBorderStyle.Sizable; + this.frmMain_Resize(null, EventArgs.Empty); + } + private void SetFullscreenState(bool enabled) { - this.Resize -= frmMain_Resize; - _fullscreenMode = enabled; - if(enabled) { - this.menuStrip.Visible = false; - _originalWindowState = this.WindowState; - this.WindowState = FormWindowState.Normal; - this.FormBorderStyle = FormBorderStyle.None; - this.WindowState = FormWindowState.Maximized; - SetScaleBasedOnWindowSize(); - } else { - this.menuStrip.Visible = true; - this.WindowState = _originalWindowState; - this.FormBorderStyle = FormBorderStyle.Sizable; - this.frmMain_Resize(null, EventArgs.Empty); + if(this._isNsfPlayerMode) { + enabled = false; } - this.Resize += frmMain_Resize; - UpdateViewerSize(); + + _fullscreenMode = enabled; mnuFullscreen.Checked = enabled; + + if(ConfigManager.Config.VideoInfo.UseExclusiveFullscreen) { + if(_emuThread != null) { + if(enabled) { + StartExclusiveFullscreenMode(); + } else { + StopExclusiveFullscreenMode(); + } + } + } else { + this.Resize -= frmMain_Resize; + if(enabled) { + StartFullscreenWindowMode(); + } else { + StopFullscreenWindowMode(); + } + this.Resize += frmMain_Resize; + UpdateViewerSize(); + } } private bool HideMenuStrip { get { - return _fullscreenMode || ConfigManager.Config.PreferenceInfo.AutoHideMenu; + return (_fullscreenMode && !ConfigManager.Config.VideoInfo.UseExclusiveFullscreen) || ConfigManager.Config.PreferenceInfo.AutoHideMenu; } } @@ -469,6 +504,10 @@ namespace Mesen.GUI.Forms _hdPackEditorWindow.Close(); } ctrlRecentGames.Initialize(); + if(e.Parameter == IntPtr.Zero) { + //We are completely stopping the emulation, close fullscreen mode + StopExclusiveFullscreenMode(); + } })); break; @@ -607,6 +646,8 @@ namespace Mesen.GUI.Forms } } + bool restoreFullscreen = _frmFullscreenRenderer != null; + switch(shortcut) { case EmulatorShortcut.Pause: PauseEmu(); break; case EmulatorShortcut.Reset: this.ResetEmu(); break; @@ -624,7 +665,7 @@ namespace Mesen.GUI.Forms case EmulatorShortcut.ToggleLagCounter: ToggleLagCounter(); break; case EmulatorShortcut.ToggleOsd: ToggleOsd(); break; case EmulatorShortcut.MaxSpeed: ToggleMaxSpeed(); break; - case EmulatorShortcut.ToggleFullscreen: ToggleFullscreen(); break; + case EmulatorShortcut.ToggleFullscreen: ToggleFullscreen(); restoreFullscreen = false; break; case EmulatorShortcut.OpenFile: OpenFile(); break; case EmulatorShortcut.IncreaseSpeed: InteropEmu.IncreaseEmulationSpeed(); break; @@ -644,7 +685,7 @@ namespace Mesen.GUI.Forms case EmulatorShortcut.InputBarcode: using(frmInputBarcode frm = new frmInputBarcode()) { - frm.ShowDialog(); + frm.ShowDialog(this, this); } break; @@ -677,6 +718,11 @@ namespace Mesen.GUI.Forms case EmulatorShortcut.LoadStateSlot7: LoadState(7); break; case EmulatorShortcut.LoadStateSlot8: LoadState(8); break; } + + if(restoreFullscreen && _frmFullscreenRenderer == null) { + //Need to restore fullscreen mode after showing a dialog + this.SetFullscreenState(true); + } } private void ToggleFullscreen() @@ -759,22 +805,6 @@ namespace Mesen.GUI.Forms ConfigManager.ApplyChanges(); } - private void UpdateFocusFlag() - { - bool hasFocus = false; - if(Application.OpenForms.Count > 0) { - if(Application.OpenForms[0].ContainsFocus) { - hasFocus = true; - } - } - - if(_removeFocus) { - hasFocus = false; - } - - InteropEmu.SetFlag(EmulationFlags.InBackground, !hasFocus); - } - private void UpdateMenus() { try { @@ -790,7 +820,6 @@ namespace Mesen.GUI.Forms ctrlLoading.Visible = (_romLoadCounter > 0); - UpdateFocusFlag(); UpdateWindowTitle(); bool isNetPlayClient = InteropEmu.IsConnected(); @@ -964,20 +993,6 @@ namespace Mesen.GUI.Forms } } - bool IMessageFilter.PreFilterMessage(ref Message m) - { - if(Application.OpenForms.Count > 0 && Application.OpenForms[0].ContainsFocus) { - if(m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP) { - int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); - InteropEmu.SetKeyState(scanCode, false); - } else if(m.Msg == WM_SYSKEYDOWN || m.Msg == WM_KEYDOWN) { - int scanCode = (Int32)(((Int64)m.LParam & 0x1FF0000) >> 16); - InteropEmu.SetKeyState(scanCode, true); - } - } - return false; - } - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if(!this.menuStrip.Enabled) { @@ -1016,7 +1031,7 @@ namespace Mesen.GUI.Forms if(MesenMsgBox.Show("FdsBiosNotFound", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { using(OpenFileDialog ofd = new OpenFileDialog()) { ofd.SetFilter(ResourceHelper.GetMessage("FilterAll")); - if(ofd.ShowDialog() == DialogResult.OK) { + if(ofd.ShowDialog(this) == DialogResult.OK) { string hash = MD5Helper.GetMD5Hash(ofd.FileName).ToLowerInvariant(); if(hash == "ca30b50f880eb660a320674ed365ef7a" || hash == "c1a9e9415a6adde3c8563c622d4c9fce") { File.Copy(ofd.FileName, Path.Combine(ConfigManager.HomeFolder, "FdsBios.bin")); @@ -1113,6 +1128,8 @@ namespace Mesen.GUI.Forms this.BeginInvoke((MethodInvoker)(() => this.InitializeNsfMode(updateTextOnly, gameLoaded))); } else { if(InteropEmu.IsNsf()) { + this.SetFullscreenState(false); + if(gameLoaded) { //Force emulation speed to 100 when loading a NSF SetEmulationSpeed(100); @@ -1132,7 +1149,6 @@ namespace Mesen.GUI.Forms this.ctrlNsfPlayer.Visible = true; this.ctrlNsfPlayer.Focus(); - NsfHeader header = InteropEmu.NsfGetHeader(); if(header.HasSongName) { _currentGame = header.GetSongName(); diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj index 916af245..b0fc1603 100644 --- a/GUI.NET/GUI.NET.csproj +++ b/GUI.NET/GUI.NET.csproj @@ -612,6 +612,9 @@ Form + + Form + UserControl @@ -678,9 +681,7 @@ frmCopyFiles.cs - - Form - + frmGetKey.cs @@ -757,6 +758,9 @@ frmDownloadProgress.cs + + Form + Form @@ -777,27 +781,21 @@ frmMain.cs - Form frmMain.cs - Form frmMain.cs - Form frmMain.cs - Form frmMain.cs - Form frmMain.cs - Form Form @@ -831,9 +829,7 @@ frmClientConfig.cs - - Form - + frmMain.cs @@ -1035,6 +1031,9 @@ BaseForm.cs + + BaseInputForm.cs + ctrlCheatFinder.cs diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 26775975..87c4196f 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -24,6 +24,8 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern void SetDisplayLanguage(Language lang); + [DllImport(DLLPath)] public static extern void SetFullscreenMode([MarshalAs(UnmanagedType.I1)]bool fullscreen, IntPtr windowHandle, UInt32 monitorWidth, UInt32 monitorHeight); + [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsRunning(); [DllImport(DLLPath)] public static extern void LoadROM([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string patchFile); diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index 49f96fe5..08baeac9 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -122,6 +122,14 @@ namespace InteropEmu { } } + DllExport void __stdcall SetFullscreenMode(bool fullscreen, void *windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) + { + if(_renderer) { + _renderer->SetFullscreenMode(fullscreen, windowHandle, monitorWidth, monitorHeight); + } + } + + DllExport bool __stdcall IsRunning() { return Console::IsRunning(); } DllExport void __stdcall LoadROM(char* filename, char* patchFile) { Console::LoadROM((string)filename, (string)patchFile); } diff --git a/Linux/SdlRenderer.cpp b/Linux/SdlRenderer.cpp index 6e9c7f84..67693520 100755 --- a/Linux/SdlRenderer.cpp +++ b/Linux/SdlRenderer.cpp @@ -17,6 +17,11 @@ SdlRenderer::~SdlRenderer() Cleanup(); } +void SdlRenderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) +{ + //TODO: Implement exclusive fullscreen for Linux +} + void SdlRenderer::Init() { SDL_InitSubSystem(SDL_INIT_VIDEO); diff --git a/Linux/SdlRenderer.h b/Linux/SdlRenderer.h index c300c9aa..ee7d02f4 100755 --- a/Linux/SdlRenderer.h +++ b/Linux/SdlRenderer.h @@ -64,4 +64,6 @@ public: void Reset(); void DrawString(std::wstring message, int x, int y, uint8_t r = 255, uint8_t g = 255, uint8_t b = 255, uint8_t opacity = 255); + + void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) override; }; \ No newline at end of file diff --git a/Windows/Renderer.cpp b/Windows/Renderer.cpp index 3d062845..6f09287d 100644 --- a/Windows/Renderer.cpp +++ b/Windows/Renderer.cpp @@ -29,24 +29,73 @@ namespace NES CleanupDevice(); } + void Renderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) + { + if(fullscreen != _fullscreen || _hWnd != (HWND)windowHandle) { + _hWnd = (HWND)windowHandle; + _monitorWidth = monitorWidth; + _monitorHeight = monitorHeight; + _newFullscreen = fullscreen; + } + } + void Renderer::SetScreenSize(uint32_t width, uint32_t height) { ScreenSize screenSize; VideoDecoder::GetInstance()->GetScreenSize(screenSize, false); - if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _resizeFilter != EmulationSettings::GetVideoResizeFilter()) { - _frameLock.Acquire(); - _nesFrameHeight = height; - _nesFrameWidth = width; - _newFrameBufferSize = width*height; + if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _resizeFilter != EmulationSettings::GetVideoResizeFilter() || _newFullscreen != _fullscreen) { + auto frameLock = _frameLock.AcquireSafe(); + auto textureLock = _textureLock.AcquireSafe(); + VideoDecoder::GetInstance()->GetScreenSize(screenSize, false); + if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _resizeFilter != EmulationSettings::GetVideoResizeFilter() || _newFullscreen != _fullscreen) { + _nesFrameHeight = height; + _nesFrameWidth = width; + _newFrameBufferSize = width*height; - _screenHeight = screenSize.Height; - _screenWidth = screenSize.Width; + bool needReset = _fullscreen != _newFullscreen; + bool fullscreenResizeMode = _fullscreen && _newFullscreen; - _screenBufferSize = _screenHeight*_screenWidth; + if(_pSwapChain && _fullscreen && !_newFullscreen) { + HRESULT hr = _pSwapChain->SetFullscreenState(FALSE, NULL); + if(FAILED(hr)) { + MessageManager::Log("SetFullscreenState(FALSE) failed - Error:" + std::to_string(hr)); + } + } - Reset(); - _frameLock.Release(); + _fullscreen = _newFullscreen; + + _screenHeight = screenSize.Height; + _screenWidth = screenSize.Width; + + if(_fullscreen) { + _realScreenHeight = _monitorHeight; + _realScreenWidth = _monitorWidth; + } else { + _realScreenHeight = screenSize.Height; + _realScreenWidth = screenSize.Width; + } + + _leftMargin = (_realScreenWidth - _screenWidth) / 2; + _topMargin = (_realScreenHeight - _screenHeight) / 2; + + _screenBufferSize = _realScreenHeight*_realScreenWidth; + + if(!_pSwapChain || needReset) { + Reset(); + } else { + if(fullscreenResizeMode) { + ResetNesBuffers(); + CreateNesBuffers(); + } else { + ResetNesBuffers(); + ReleaseRenderTargetView(); + _pSwapChain->ResizeBuffers(1, _realScreenWidth, _realScreenHeight, DXGI_FORMAT_B8G8R8A8_UNORM, 0); + CreateRenderTargetView(); + CreateNesBuffers(); + } + } + } } } @@ -62,6 +111,37 @@ namespace NES } void Renderer::CleanupDevice() + { + ResetNesBuffers(); + ReleaseRenderTargetView(); + if(_pAlphaEnableBlendingState) { + _pAlphaEnableBlendingState->Release(); + _pAlphaEnableBlendingState = nullptr; + } + if(_pDepthDisabledStencilState) { + _pDepthDisabledStencilState->Release(); + _pDepthDisabledStencilState = nullptr; + } + if(_samplerState) { + _samplerState->Release(); + _samplerState = nullptr; + } + if(_pSwapChain) { + _pSwapChain->SetFullscreenState(false, nullptr); + _pSwapChain->Release(); + _pSwapChain = nullptr; + } + if(_pDeviceContext) { + _pDeviceContext->Release(); + _pDeviceContext = nullptr; + } + if(_pd3dDevice) { + _pd3dDevice->Release(); + _pd3dDevice = nullptr; + } + } + + void Renderer::ResetNesBuffers() { if(_pTexture) { _pTexture->Release(); @@ -87,34 +167,69 @@ namespace NES delete[] _textureBuffer[1]; _textureBuffer[1] = nullptr; } - if(_samplerState) { - _samplerState->Release(); - _samplerState = nullptr; - } + } + + void Renderer::ReleaseRenderTargetView() + { if(_pRenderTargetView) { _pRenderTargetView->Release(); _pRenderTargetView = nullptr; } - if(_pSwapChain) { - _pSwapChain->Release(); - _pSwapChain = nullptr; + } + + HRESULT Renderer::CreateRenderTargetView() + { + // Create a render target view + ID3D11Texture2D* pBackBuffer = nullptr; + HRESULT hr = _pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); + if(FAILED(hr)) { + MessageManager::Log("SwapChain::GetBuffer() failed - Error:" + std::to_string(hr)); + return hr; } - if(_pDeviceContext) { - _pDeviceContext->Release(); - _pDeviceContext = nullptr; + + hr = _pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &_pRenderTargetView); + pBackBuffer->Release(); + if(FAILED(hr)) { + MessageManager::Log("D3DDevice::CreateRenderTargetView() failed - Error:" + std::to_string(hr)); + return hr; } - if(_pd3dDevice) { - _pd3dDevice->Release(); - _pd3dDevice = nullptr; + + _pDeviceContext->OMSetRenderTargets(1, &_pRenderTargetView, nullptr); + + return S_OK; + } + + HRESULT Renderer::CreateNesBuffers() + { + _textureBuffer[0] = new uint8_t[_nesFrameWidth*_nesFrameHeight * 4]; + _textureBuffer[1] = new uint8_t[_nesFrameWidth*_nesFrameHeight * 4]; + memset(_textureBuffer[0], 0, _nesFrameWidth*_nesFrameHeight * 4); + memset(_textureBuffer[1], 0, _nesFrameWidth*_nesFrameHeight * 4); + + _pTexture = CreateTexture(_nesFrameWidth, _nesFrameHeight); + if(!_pTexture) { + return S_FALSE; } - if(_pAlphaEnableBlendingState) { - _pAlphaEnableBlendingState->Release(); - _pAlphaEnableBlendingState = nullptr; + _overlayTexture = CreateTexture(8, 8); + if(!_overlayTexture) { + return S_FALSE; } - if(_pDepthDisabledStencilState) { - _pDepthDisabledStencilState->Release(); - _pDepthDisabledStencilState = nullptr; + _pTextureSrv = GetShaderResourceView(_pTexture); + if(!_pTextureSrv) { + return S_FALSE; } + _pOverlaySrv = GetShaderResourceView(_overlayTexture); + if(!_pOverlaySrv) { + return S_FALSE; + } + + //////////////////////////////////////////////////////////////////////////// + _spriteBatch.reset(new SpriteBatch(_pDeviceContext)); + + _largeFont.reset(new SpriteFont(_pd3dDevice, L"Resources\\Font.64.spritefont")); + _font.reset(new SpriteFont(_pd3dDevice, L"Resources\\Font.24.spritefont")); + + return S_OK; } //-------------------------------------------------------------------------------------- @@ -149,8 +264,8 @@ namespace NES DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; - sd.BufferDesc.Width = _screenWidth; - sd.BufferDesc.Height = _screenHeight; + sd.BufferDesc.Width = _realScreenWidth; + sd.BufferDesc.Height = _realScreenHeight; sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; @@ -167,6 +282,10 @@ namespace NES featureLevel = D3D_FEATURE_LEVEL_11_1; hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &featureLevel, &_pDeviceContext); + /*if(FAILED(hr)) { + MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr)); + }*/ + if(hr == E_INVALIDARG) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it featureLevel = D3D_FEATURE_LEVEL_11_0; @@ -177,23 +296,27 @@ namespace NES break; } } + if(FAILED(hr)) { MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr)); return hr; } - // Create a render target view - ID3D11Texture2D* pBackBuffer = nullptr; - hr = _pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); - if(FAILED(hr)) { - MessageManager::Log("SwapChain::GetBuffer() failed - Error:" + std::to_string(hr)); - return hr; + if(_fullscreen) { + hr = _pSwapChain->SetFullscreenState(TRUE, NULL); + if(FAILED(hr)) { + MessageManager::Log("SetFullscreenState(true) failed - Error:" + std::to_string(hr)); + MessageManager::Log("Switching back to windowed mode"); + hr = _pSwapChain->SetFullscreenState(FALSE, NULL); + if(FAILED(hr)) { + MessageManager::Log("SetFullscreenState(false) failed - Error:" + std::to_string(hr)); + return hr; + } + } } - hr = _pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &_pRenderTargetView); - pBackBuffer->Release(); + hr = CreateRenderTargetView(); if(FAILED(hr)) { - MessageManager::Log("D3DDevice::CreateRenderTargetView() failed - Error:" + std::to_string(hr)); return hr; } @@ -250,46 +373,32 @@ namespace NES _pDeviceContext->OMSetBlendState(_pAlphaEnableBlendingState, blendFactor, 0xffffffff); _pDeviceContext->OMSetDepthStencilState(_pDepthDisabledStencilState, 1); - _pDeviceContext->OMSetRenderTargets(1, &_pRenderTargetView, nullptr); // Setup the viewport D3D11_VIEWPORT vp; - vp.Width = (FLOAT)_screenWidth; - vp.Height = (FLOAT)_screenHeight; + vp.Width = (FLOAT)2560; + vp.Height = (FLOAT)1440; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; _pDeviceContext->RSSetViewports(1, &vp); - _textureBuffer[0] = new uint8_t[_nesFrameWidth*_nesFrameHeight*4]; - _textureBuffer[1] = new uint8_t[_nesFrameWidth*_nesFrameHeight*4]; - memset(_textureBuffer[0], 0, _nesFrameWidth*_nesFrameHeight*4); - memset(_textureBuffer[1], 0, _nesFrameWidth*_nesFrameHeight*4); - - _pTexture = CreateTexture(_nesFrameWidth, _nesFrameHeight); - if(!_pTexture) { - return S_FALSE; - } - _overlayTexture = CreateTexture(8, 8); - if(!_overlayTexture) { - return S_FALSE; - } - _pTextureSrv = GetShaderResourceView(_pTexture); - if(!_pTextureSrv) { - return S_FALSE; - } - _pOverlaySrv = GetShaderResourceView(_overlayTexture); - if(!_pOverlaySrv) { - return S_FALSE; + hr = CreateNesBuffers(); + if(FAILED(hr)) { + return hr; } - //////////////////////////////////////////////////////////////////////////// - _spriteBatch.reset(new SpriteBatch(_pDeviceContext)); + hr = CreateSamplerState(); + if(FAILED(hr)) { + return hr; + } - _largeFont.reset(new SpriteFont(_pd3dDevice, L"Resources\\Font.64.spritefont")); - _font.reset(new SpriteFont(_pd3dDevice, L"Resources\\Font.24.spritefont")); + return S_OK; + } + HRESULT Renderer::CreateSamplerState() + { _resizeFilter = EmulationSettings::GetVideoResizeFilter(); //Sample state @@ -305,14 +414,13 @@ namespace NES samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - - hr = _pd3dDevice->CreateSamplerState(&samplerDesc, &_samplerState); + + HRESULT hr = _pd3dDevice->CreateSamplerState(&samplerDesc, &_samplerState); if(FAILED(hr)) { MessageManager::Log("D3DDevice::CreateSamplerState() failed - Error:" + std::to_string(hr)); - return hr; } - return S_OK; + return hr; } ID3D11Texture2D* Renderer::CreateTexture(uint32_t width, uint32_t height) @@ -367,7 +475,7 @@ namespace NES font = _font.get(); } - font->DrawString(_spriteBatch.get(), text, XMFLOAT2(x, y), color, 0.0f, XMFLOAT2(0, 0), scale); + font->DrawString(_spriteBatch.get(), text, XMFLOAT2(x+_leftMargin, y+_topMargin), color, 0.0f, XMFLOAT2(0, 0), scale); } void Renderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height) @@ -376,9 +484,12 @@ namespace NES uint32_t bpp = 4; auto lock = _textureLock.AcquireSafe(); - memcpy(_textureBuffer[0], frameBuffer, width*height*bpp); - _needFlip = true; - _frameChanged = true; + if(_textureBuffer[0]) { + //_textureBuffer[0] may be null if directx failed to initialize properly + memcpy(_textureBuffer[0], frameBuffer, width*height*bpp); + _needFlip = true; + _frameChanged = true; + } } void Renderer::DrawNESScreen() @@ -416,10 +527,10 @@ namespace NES _pDeviceContext->Unmap(_pTexture, 0); RECT destRect; - destRect.left = 0; - destRect.top = 0; - destRect.right = _screenWidth; - destRect.bottom = _screenHeight; + destRect.left = _leftMargin; + destRect.top = _topMargin; + destRect.right = _screenWidth+_leftMargin; + destRect.bottom = _screenHeight+_topMargin; _spriteBatch->Draw(_pTextureSrv, destRect); } @@ -428,9 +539,9 @@ namespace NES { RECT destRect; destRect.left = 0; - destRect.right = _screenWidth; - destRect.bottom = _screenHeight; destRect.top = 0; + destRect.right = _realScreenWidth; + destRect.bottom = _realScreenHeight; D3D11_MAPPED_SUBRESOURCE dd; HRESULT hr = _pDeviceContext->Map(_overlayTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd); @@ -452,7 +563,9 @@ namespace NES _spriteBatch->Draw(_pOverlaySrv, destRect); XMVECTOR stringDimensions = _largeFont->MeasureString(L"PAUSE"); - DrawString("PAUSE", (float)_screenWidth / 2 - stringDimensions.m128_f32[0] / 2, (float)_screenHeight / 2 - stringDimensions.m128_f32[1] / 2 - 8, Colors::AntiqueWhite, 1.0f, _largeFont.get()); + float x = (float)_screenWidth / 2 - stringDimensions.m128_f32[0] / 2; + float y = (float)_screenHeight / 2 - stringDimensions.m128_f32[1] / 2 - 8; + DrawString("PAUSE", x, y, Colors::AntiqueWhite, 1.0f, _largeFont.get()); } void Renderer::Render() @@ -462,6 +575,18 @@ namespace NES _noUpdateCount = 0; auto lock = _frameLock.AcquireSafe(); + if(_newFullscreen != _fullscreen) { + SetScreenSize(_nesFrameWidth, _nesFrameHeight); + } + + if(_pDeviceContext == nullptr) { + //DirectX failed to initialize, try to init + Reset(); + if(_pDeviceContext == nullptr) { + //Can't init, prevent crash + return; + } + } // Clear the back buffer _pDeviceContext->ClearRenderTargetView(_pRenderTargetView, Colors::Black); @@ -499,7 +624,7 @@ namespace NES void Renderer::DrawString(std::wstring message, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t opacity) { XMVECTORF32 color = { (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)opacity / 255.0f }; - _font->DrawString(_spriteBatch.get(), message.c_str(), XMFLOAT2((float)x, (float)y), color); + _font->DrawString(_spriteBatch.get(), message.c_str(), XMFLOAT2((float)x+_leftMargin, (float)y+_topMargin), color); } float Renderer::MeasureString(std::wstring text) diff --git a/Windows/Renderer.h b/Windows/Renderer.h index 9dcbd11f..0d3f64f1 100644 --- a/Windows/Renderer.h +++ b/Windows/Renderer.h @@ -52,6 +52,16 @@ namespace NES { const uint32_t _bytesPerPixel = 4; uint32_t _screenBufferSize = 0; + bool _newFullscreen = false; + bool _fullscreen = false; + + uint32_t _realScreenHeight = 240; + uint32_t _realScreenWidth = 256; + uint32_t _leftMargin = 0; + uint32_t _topMargin = 0; + uint32_t _monitorWidth = 0; + uint32_t _monitorHeight = 0; + uint32_t _nesFrameHeight = 0; uint32_t _nesFrameWidth = 0; uint32_t _newFrameBufferSize = 0; @@ -76,10 +86,18 @@ namespace NES { float MeasureString(std::wstring text); bool ContainsCharacter(wchar_t character); + HRESULT CreateRenderTargetView(); + void ReleaseRenderTargetView(); + HRESULT CreateNesBuffers(); + void ResetNesBuffers(); + HRESULT CreateSamplerState(); + public: Renderer(HWND hWnd); ~Renderer(); + void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight); + void Reset(); void Render();