Video: Exclusive fullscreen mode (wip)
This commit is contained in:
parent
dc3202fbfc
commit
114d9d2313
31 changed files with 764 additions and 265 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Fes servir valors enters d'escalat al mode de pantalla completa</Control>
|
||||
<Control ID="chkShowFps">Mostra els FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Fes servir els paquets d'alta resolució d'HDNes</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Use exclusive fullscreen mode</Control>
|
||||
<Control ID="tpgOverscan">Sobreescaneig</Control>
|
||||
<Control ID="grpCropping">Retall de vídeo</Control>
|
||||
<Control ID="lblLeft">Esquerra</Control>
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Utilizar valores enteros de escalado en modo de pantalla completa</Control>
|
||||
<Control ID="chkShowFps">Mostrar FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Utilizar los paquetes de alta resolución de HDNes</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Use exclusive fullscreen mode</Control>
|
||||
<Control ID="tpgOverscan">Overscan</Control>
|
||||
<Control ID="grpCropping">Recorte</Control>
|
||||
<Control ID="lblLeft">Izquierda</Control>
|
||||
|
|
|
@ -259,6 +259,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Utiliser une valeur entière pour l'échelle vidéo en mode plein écran</Control>
|
||||
<Control ID="chkShowFps">Afficher le FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Utiliser les packs haute-définition de HDNes</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Utiliser le mode plein écran exclusif</Control>
|
||||
<Control ID="tpgOverscan">Overscan</Control>
|
||||
<Control ID="grpCropping">Overscan</Control>
|
||||
<Control ID="lblLeft">Gauche</Control>
|
||||
|
|
|
@ -260,6 +260,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">全画面表示モードに入る時、画面サイズの倍率を整数にする</Control>
|
||||
<Control ID="chkShowFps">フレームレート表示</Control>
|
||||
<Control ID="chkUseHdPacks">HDNesのHDパックを使う</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">排他的なフルスクリーンモードを使う</Control>
|
||||
<Control ID="tpgOverscan">オーバースキャン</Control>
|
||||
<Control ID="grpCropping">オーバースキャン</Control>
|
||||
<Control ID="lblLeft">左</Control>
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Usar valores de escala inteira ao entrar no modo de tela cheia</Control>
|
||||
<Control ID="chkShowFps">Mostrar FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Usar os pacotes de alta definição do HDNes</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Use exclusive fullscreen mode</Control>
|
||||
<Control ID="tpgOverscan">Overscan</Control>
|
||||
<Control ID="grpCropping">Recorte</Control>
|
||||
<Control ID="lblLeft">Esquerda</Control>
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Use integer scale values when entering fullscreen mode</Control>
|
||||
<Control ID="chkShowFps">Показывать FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Использовать HDNes HD packs</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Use exclusive fullscreen mode</Control>
|
||||
<Control ID="tpgOverscan">Overscan</Control>
|
||||
<Control ID="grpCropping">Overscan</Control>
|
||||
<Control ID="lblLeft">Слева</Control>
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
<Control ID="chkFullscreenForceIntegerScale">Використовуйте цілі значення масштабу при введенні повноекранного режиму</Control>
|
||||
<Control ID="chkShowFps">Показувати FPS</Control>
|
||||
<Control ID="chkUseHdPacks">Використовувати HDNes HD packs</Control>
|
||||
<Control ID="chkUseExclusiveFullscreen">Use exclusive fullscreen mode</Control>
|
||||
<Control ID="tpgOverscan">Overscan</Control>
|
||||
<Control ID="grpCropping">Overscan</Control>
|
||||
<Control ID="lblLeft">Злiва</Control>
|
||||
|
|
92
GUI.NET/Forms/BaseInputForm.cs
Normal file
92
GUI.NET/Forms/BaseInputForm.cs
Normal file
|
@ -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<Form> _inputForms = new Stack<Form>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
126
GUI.NET/Forms/BaseInputForm.resx
Normal file
126
GUI.NET/Forms/BaseInputForm.resx
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="tmrUpdateBackground.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>107, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -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<UInt32> _prevScanCodes = new List<UInt32>();
|
||||
|
||||
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<UInt32> _prevScanCodes = new List<UInt32>();
|
||||
|
||||
private void tmrCheckKey_Tick(object sender, EventArgs e)
|
||||
{
|
||||
List<UInt32> scanCodes = InteropEmu.GetPressedKeys();
|
||||
|
|
68
GUI.NET/Forms/Config/frmVideoConfig.Designer.cs
generated
68
GUI.NET/Forms/Config/frmVideoConfig.Designer.cs
generated
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
93
GUI.NET/Forms/frmFullscreenRenderer.cs
Normal file
93
GUI.NET/Forms/frmFullscreenRenderer.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<string> passedTests = new List<string>();
|
||||
List<string> failedTests = new List<string>();
|
||||
List<int> failedFrameCount = new List<int>();
|
||||
|
@ -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(() => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<EmulatorShortcut, Func<bool>> _actionEnabledFuncs = new Dictionary<EmulatorShortcut, Func<bool>>();
|
||||
|
||||
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();
|
||||
|
|
|
@ -612,6 +612,9 @@
|
|||
<Compile Include="Forms\BaseConfigForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\BaseInputForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Cheats\ctrlCheatFinder.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -678,9 +681,7 @@
|
|||
<Compile Include="Forms\Config\frmCopyFiles.Designer.cs">
|
||||
<DependentUpon>frmCopyFiles.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Config\frmGetKey.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Config\frmGetKey.cs" />
|
||||
<Compile Include="Forms\Config\frmGetKey.Designer.cs">
|
||||
<DependentUpon>frmGetKey.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -757,6 +758,9 @@
|
|||
<Compile Include="Forms\frmDownloadProgress.Designer.cs">
|
||||
<DependentUpon>frmDownloadProgress.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmFullscreenRenderer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmHelp.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -777,27 +781,21 @@
|
|||
</Compile>
|
||||
<Compile Include="Forms\frmMain.File.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.Game.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.Options.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.Tests.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.Tools.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.Help.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmRecordAvi.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
@ -831,9 +829,7 @@
|
|||
<Compile Include="Forms\NetPlay\frmClientConfig.Designer.cs">
|
||||
<DependentUpon>frmClientConfig.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmMain.cs" />
|
||||
<Compile Include="Forms\frmMain.Designer.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -1035,6 +1031,9 @@
|
|||
<EmbeddedResource Include="Forms\BaseForm.resx">
|
||||
<DependentUpon>BaseForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\BaseInputForm.resx">
|
||||
<DependentUpon>BaseInputForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Cheats\ctrlCheatFinder.resx">
|
||||
<DependentUpon>ctrlCheatFinder.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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
|
||||
|
@ -306,13 +415,12 @@ namespace NES
|
|||
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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue