From 078535436ea9a735955f6848f3ca2d2eda9c0245 Mon Sep 17 00:00:00 2001 From: Souryo Date: Sat, 12 Aug 2017 11:54:05 -0400 Subject: [PATCH] Input: Added basic support for famicom microphone --- Core/ControlManager.cpp | 8 + Core/EmulationSettings.h | 3 +- Core/StandardController.cpp | 15 +- Core/StandardController.h | 2 + GUI.NET/Config/InputInfo.cs | 3 + .../Config/ctrlInputPortConfig.Designer.cs | 107 ------------ GUI.NET/Forms/Config/ctrlInputPortConfig.cs | 43 ----- GUI.NET/Forms/Config/ctrlInputPortConfig.resx | 120 ------------- .../Config/ctrlStandardController.Designer.cs | 122 +++++++++++-- .../Forms/Config/ctrlStandardController.cs | 32 ++++ .../Forms/Config/ctrlStandardController.resx | 165 ------------------ GUI.NET/Forms/Config/frmControllerConfig.cs | 9 +- .../Forms/Config/frmInputConfig.Designer.cs | 27 +-- GUI.NET/Forms/Config/frmInputConfig.cs | 3 +- GUI.NET/GUI.NET.csproj | 9 - GUI.NET/InteropEmu.cs | 1 + 16 files changed, 193 insertions(+), 476 deletions(-) delete mode 100644 GUI.NET/Forms/Config/ctrlInputPortConfig.Designer.cs delete mode 100644 GUI.NET/Forms/Config/ctrlInputPortConfig.cs delete mode 100644 GUI.NET/Forms/Config/ctrlInputPortConfig.resx diff --git a/Core/ControlManager.cpp b/Core/ControlManager.cpp index 27cfc4c1..0804499d 100644 --- a/Core/ControlManager.cpp +++ b/Core/ControlManager.cpp @@ -217,6 +217,14 @@ uint8_t ControlManager::GetPortValue(uint8_t port) uint8_t value = MemoryManager::GetOpenBus(GetOpenBusMask(port)); if(device) { value |= device->GetPortOutput(); + + if(port == 0 && EmulationSettings::GetConsoleType() == ConsoleType::Famicom) { + //Connect $4016.2 to the 2nd controller's microphone on Famicoms + shared_ptr controller = std::dynamic_pointer_cast(GetControlDevice(1)); + if(controller && controller->IsMicrophoneActive()) { + value |= 0x04; + } + } } return value; diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h index de632ca7..2f3dc8bf 100644 --- a/Core/EmulationSettings.h +++ b/Core/EmulationSettings.h @@ -249,10 +249,11 @@ struct KeyMapping uint32_t TurboB = 0; uint32_t TurboStart = 0; uint32_t TurboSelect = 0; + uint32_t Microphone = 0; bool HasKeySet() { - return A || B || Up || Down || Left || Right || Start || Select || TurboA || TurboB || TurboStart || TurboSelect; + return A || B || Up || Down || Left || Right || Start || Select || TurboA || TurboB || TurboStart || TurboSelect || Microphone; } }; diff --git a/Core/StandardController.cpp b/Core/StandardController.cpp index 4c59fbed..147cb9a3 100644 --- a/Core/StandardController.cpp +++ b/Core/StandardController.cpp @@ -19,6 +19,19 @@ void StandardController::StreamState(bool saving) Stream(_stateBuffer, _stateBufferFamicom, additionalController); } +bool StandardController::IsMicrophoneActive() +{ + if(!EmulationSettings::CheckFlag(EmulationFlags::InBackground) || EmulationSettings::CheckFlag(EmulationFlags::AllowBackgroundInput)) { + for(size_t i = 0, len = _keyMappings.size(); i < len; i++) { + KeyMapping keyMapping = _keyMappings[i]; + if((PPU::GetFrameCount() % 3) == 0 && ControlManager::IsKeyPressed(keyMapping.Microphone)) { + return true; + } + } + } + return false; +} + uint8_t StandardController::GetButtonState() { ButtonState state; @@ -84,7 +97,7 @@ uint8_t StandardController::GetPortOutput() //"All subsequent reads will return D=1 on an authentic controller but may return D=0 on third party controllers." _stateBuffer |= _isEmptyPort ? 0 : 0x800000; - + return returnValue; } diff --git a/Core/StandardController.h b/Core/StandardController.h index dc510696..a9741d46 100644 --- a/Core/StandardController.h +++ b/Core/StandardController.h @@ -30,6 +30,8 @@ public: uint32_t GetInternalState(); void SetInternalState(uint32_t state); + bool IsMicrophoneActive(); + void AddAdditionalController(shared_ptr controller); shared_ptr GetAdditionalController(); diff --git a/GUI.NET/Config/InputInfo.cs b/GUI.NET/Config/InputInfo.cs index 648129c6..99389465 100644 --- a/GUI.NET/Config/InputInfo.cs +++ b/GUI.NET/Config/InputInfo.cs @@ -23,6 +23,8 @@ namespace Mesen.GUI.Config public UInt32 TurboStart; public UInt32 TurboSelect; + public UInt32 Microphone; + public KeyMappings() { } @@ -48,6 +50,7 @@ namespace Mesen.GUI.Config mapping.TurboB = TurboB; mapping.TurboStart = TurboStart; mapping.TurboSelect = TurboSelect; + mapping.Microphone = Microphone; return mapping; } diff --git a/GUI.NET/Forms/Config/ctrlInputPortConfig.Designer.cs b/GUI.NET/Forms/Config/ctrlInputPortConfig.Designer.cs deleted file mode 100644 index 5f1960ff..00000000 --- a/GUI.NET/Forms/Config/ctrlInputPortConfig.Designer.cs +++ /dev/null @@ -1,107 +0,0 @@ -namespace Mesen.GUI.Forms.Config -{ - partial class ctrlInputPortConfig - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if(disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.ctrlStandardController = new Mesen.GUI.Forms.Config.ctrlStandardController(); - this.cboControllerType = new System.Windows.Forms.ComboBox(); - this.lblControllerType = new System.Windows.Forms.Label(); - this.tableLayoutPanel1.SuspendLayout(); - this.SuspendLayout(); - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Controls.Add(this.lblControllerType, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.ctrlStandardController, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.cboControllerType, 1, 0); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(618, 353); - this.tableLayoutPanel1.TabIndex = 1; - // - // ctrlStandardController - // - this.tableLayoutPanel1.SetColumnSpan(this.ctrlStandardController, 2); - this.ctrlStandardController.Location = new System.Drawing.Point(3, 30); - this.ctrlStandardController.Name = "ctrlStandardController"; - this.ctrlStandardController.Size = new System.Drawing.Size(611, 320); - this.ctrlStandardController.TabIndex = 3; - // - // cboControllerType - // - this.cboControllerType.Dock = System.Windows.Forms.DockStyle.Top; - this.cboControllerType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboControllerType.FormattingEnabled = true; - this.cboControllerType.Items.AddRange(new object[] { - "None", - "Standard NES Controller", - "Zapper"}); - this.cboControllerType.Location = new System.Drawing.Point(90, 3); - this.cboControllerType.Name = "cboControllerType"; - this.cboControllerType.Size = new System.Drawing.Size(525, 21); - this.cboControllerType.TabIndex = 2; - this.cboControllerType.SelectedIndexChanged += new System.EventHandler(this.cboControllerType_SelectedIndexChanged); - // - // lblControllerType - // - this.lblControllerType.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.lblControllerType.AutoSize = true; - this.lblControllerType.Location = new System.Drawing.Point(3, 7); - this.lblControllerType.Name = "lblControllerType"; - this.lblControllerType.Size = new System.Drawing.Size(81, 13); - this.lblControllerType.TabIndex = 1; - this.lblControllerType.Text = "Controller Type:"; - // - // ctrlInputPortConfig - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.tableLayoutPanel1); - this.Name = "ctrlInputPortConfig"; - this.Size = new System.Drawing.Size(618, 353); - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private ctrlStandardController ctrlStandardController; - private System.Windows.Forms.Label lblControllerType; - private System.Windows.Forms.ComboBox cboControllerType; - } -} diff --git a/GUI.NET/Forms/Config/ctrlInputPortConfig.cs b/GUI.NET/Forms/Config/ctrlInputPortConfig.cs deleted file mode 100644 index a75da0cc..00000000 --- a/GUI.NET/Forms/Config/ctrlInputPortConfig.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using Mesen.GUI.Config; -using Mesen.GUI.Controls; - -namespace Mesen.GUI.Forms.Config -{ - public partial class ctrlInputPortConfig : BaseControl - { - private ControllerInfo _controllerInfo; - - public ctrlInputPortConfig() - { - InitializeComponent(); - } - - public void Initialize(ControllerInfo controllerInfo) - { - _controllerInfo = controllerInfo; - //ctrlStandardController.Initialize(controllerInfo.Keys); - - cboControllerType.SelectedIndex = (int)_controllerInfo.ControllerType; - } - - public void UpdateConfig() - { - //_controllerInfo.Keys = ctrlStandardController.GetKeyMappings(); - _controllerInfo.ControllerType = (InteropEmu.ControllerType)cboControllerType.SelectedIndex; - } - - private void cboControllerType_SelectedIndexChanged(object sender, EventArgs e) - { - ctrlStandardController.Visible = ((InteropEmu.ControllerType)cboControllerType.SelectedIndex == InteropEmu.ControllerType.StandardController); - } - } -} diff --git a/GUI.NET/Forms/Config/ctrlInputPortConfig.resx b/GUI.NET/Forms/Config/ctrlInputPortConfig.resx deleted file mode 100644 index 1af7de15..00000000 --- a/GUI.NET/Forms/Config/ctrlInputPortConfig.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - \ No newline at end of file diff --git a/GUI.NET/Forms/Config/ctrlStandardController.Designer.cs b/GUI.NET/Forms/Config/ctrlStandardController.Designer.cs index bba9d526..e1d54b4d 100644 --- a/GUI.NET/Forms/Config/ctrlStandardController.Designer.cs +++ b/GUI.NET/Forms/Config/ctrlStandardController.Designer.cs @@ -27,8 +27,15 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ctrlStandardController)); this.panel2 = new System.Windows.Forms.Panel(); + this.lblB = new System.Windows.Forms.Label(); + this.lblA = new System.Windows.Forms.Label(); + this.lblTurboA = new System.Windows.Forms.Label(); + this.lblTurboB = new System.Windows.Forms.Label(); + this.lblStart = new System.Windows.Forms.Label(); + this.lblSelect = new System.Windows.Forms.Label(); + this.lblMicrophone = new System.Windows.Forms.Label(); + this.btnMicrophone = new System.Windows.Forms.Button(); this.btnTurboB = new System.Windows.Forms.Button(); this.btnRight = new System.Windows.Forms.Button(); this.btnSelect = new System.Windows.Forms.Button(); @@ -39,13 +46,19 @@ this.btnUp = new System.Windows.Forms.Button(); this.btnDown = new System.Windows.Forms.Button(); this.btnA = new System.Windows.Forms.Button(); - this.picControllerLayout = new System.Windows.Forms.PictureBox(); this.panel2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).BeginInit(); this.SuspendLayout(); // // panel2 // + this.panel2.Controls.Add(this.lblB); + this.panel2.Controls.Add(this.lblA); + this.panel2.Controls.Add(this.lblTurboA); + this.panel2.Controls.Add(this.lblTurboB); + this.panel2.Controls.Add(this.lblStart); + this.panel2.Controls.Add(this.lblSelect); + this.panel2.Controls.Add(this.lblMicrophone); + this.panel2.Controls.Add(this.btnMicrophone); this.panel2.Controls.Add(this.btnTurboB); this.panel2.Controls.Add(this.btnRight); this.panel2.Controls.Add(this.btnSelect); @@ -56,7 +69,6 @@ this.panel2.Controls.Add(this.btnUp); this.panel2.Controls.Add(this.btnDown); this.panel2.Controls.Add(this.btnA); - this.panel2.Controls.Add(this.picControllerLayout); this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; this.panel2.Location = new System.Drawing.Point(0, 0); this.panel2.Margin = new System.Windows.Forms.Padding(0); @@ -64,6 +76,88 @@ this.panel2.Size = new System.Drawing.Size(585, 210); this.panel2.TabIndex = 3; // + // lblB + // + this.lblB.AutoSize = true; + this.lblB.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblB.Location = new System.Drawing.Point(460, 165); + this.lblB.Name = "lblB"; + this.lblB.Size = new System.Drawing.Size(19, 18); + this.lblB.TabIndex = 29; + this.lblB.Text = "B"; + // + // lblA + // + this.lblA.AutoSize = true; + this.lblA.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblA.Location = new System.Drawing.Point(543, 165); + this.lblA.Name = "lblA"; + this.lblA.Size = new System.Drawing.Size(17, 18); + this.lblA.TabIndex = 28; + this.lblA.Text = "A"; + // + // lblTurboA + // + this.lblTurboA.AutoSize = true; + this.lblTurboA.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblTurboA.Location = new System.Drawing.Point(498, 78); + this.lblTurboA.Name = "lblTurboA"; + this.lblTurboA.Size = new System.Drawing.Size(62, 18); + this.lblTurboA.TabIndex = 27; + this.lblTurboA.Text = "Turbo A"; + // + // lblTurboB + // + this.lblTurboB.AutoSize = true; + this.lblTurboB.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblTurboB.Location = new System.Drawing.Point(414, 78); + this.lblTurboB.Name = "lblTurboB"; + this.lblTurboB.Size = new System.Drawing.Size(65, 18); + this.lblTurboB.TabIndex = 26; + this.lblTurboB.Text = "Turbo B"; + // + // lblStart + // + this.lblStart.AutoSize = true; + this.lblStart.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblStart.Location = new System.Drawing.Point(324, 107); + this.lblStart.Name = "lblStart"; + this.lblStart.Size = new System.Drawing.Size(42, 18); + this.lblStart.TabIndex = 25; + this.lblStart.Text = "Start"; + // + // lblSelect + // + this.lblSelect.AutoSize = true; + this.lblSelect.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblSelect.Location = new System.Drawing.Point(237, 106); + this.lblSelect.Name = "lblSelect"; + this.lblSelect.Size = new System.Drawing.Size(53, 18); + this.lblSelect.TabIndex = 24; + this.lblSelect.Text = "Select"; + // + // lblMicrophone + // + this.lblMicrophone.AutoSize = true; + this.lblMicrophone.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblMicrophone.Location = new System.Drawing.Point(260, 18); + this.lblMicrophone.Name = "lblMicrophone"; + this.lblMicrophone.Size = new System.Drawing.Size(93, 18); + this.lblMicrophone.TabIndex = 23; + this.lblMicrophone.Text = "Microphone"; + this.lblMicrophone.Visible = false; + // + // btnMicrophone + // + this.btnMicrophone.Location = new System.Drawing.Point(267, 39); + this.btnMicrophone.Name = "btnMicrophone"; + this.btnMicrophone.Size = new System.Drawing.Size(77, 37); + this.btnMicrophone.TabIndex = 22; + this.btnMicrophone.Text = "D"; + this.btnMicrophone.UseVisualStyleBackColor = true; + this.btnMicrophone.Visible = false; + this.btnMicrophone.Click += new System.EventHandler(this.btnMapping_Click); + // // btnTurboB // this.btnTurboB.Location = new System.Drawing.Point(417, 17); @@ -164,15 +258,6 @@ this.btnA.UseVisualStyleBackColor = true; this.btnA.Click += new System.EventHandler(this.btnMapping_Click); // - // picControllerLayout - // - this.picControllerLayout.Image = ((System.Drawing.Image)(resources.GetObject("picControllerLayout.Image"))); - this.picControllerLayout.Location = new System.Drawing.Point(0, 0); - this.picControllerLayout.Name = "picControllerLayout"; - this.picControllerLayout.Size = new System.Drawing.Size(615, 211); - this.picControllerLayout.TabIndex = 11; - this.picControllerLayout.TabStop = false; - // // ctrlStandardController // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -181,7 +266,7 @@ this.Name = "ctrlStandardController"; this.Size = new System.Drawing.Size(585, 210); this.panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).EndInit(); + this.panel2.PerformLayout(); this.ResumeLayout(false); } @@ -198,7 +283,14 @@ private System.Windows.Forms.Button btnUp; private System.Windows.Forms.Button btnDown; private System.Windows.Forms.Button btnA; - private System.Windows.Forms.PictureBox picControllerLayout; private System.Windows.Forms.Button btnLeft; + private System.Windows.Forms.Label lblB; + private System.Windows.Forms.Label lblA; + private System.Windows.Forms.Label lblTurboA; + private System.Windows.Forms.Label lblTurboB; + private System.Windows.Forms.Label lblStart; + private System.Windows.Forms.Label lblSelect; + private System.Windows.Forms.Label lblMicrophone; + private System.Windows.Forms.Button btnMicrophone; } } diff --git a/GUI.NET/Forms/Config/ctrlStandardController.cs b/GUI.NET/Forms/Config/ctrlStandardController.cs index 8d5ddb45..05cd7e23 100644 --- a/GUI.NET/Forms/Config/ctrlStandardController.cs +++ b/GUI.NET/Forms/Config/ctrlStandardController.cs @@ -31,6 +31,35 @@ namespace Mesen.GUI.Forms.Config } } + public bool ShowMicrophone + { + set + { + btnMicrophone.Visible = value; + lblMicrophone.Visible = value; + } + } + + private Point[] _drawPoints = new Point[13] { + new Point(56, 29), new Point(56, 85), new Point(22, 85), + new Point(22, 130), new Point(56, 130), new Point(56, 181), + new Point(145, 181), new Point(145, 130), new Point(179, 130), + new Point(179, 85), new Point(145, 85), new Point(145, 28), + new Point(56, 29) + }; + + protected override void OnPaint(PaintEventArgs e) + { + Rectangle rect = this.ClientRectangle; + rect.Inflate(-2, -2); + using(Pen pen = new Pen(Color.Black, 2f)) { + e.Graphics.DrawRectangle(pen, rect); + e.Graphics.DrawRectangle(pen, 226, 128, 159, 43); + e.Graphics.DrawPolygon(pen, _drawPoints); + } + base.OnPaint(e); + } + private void InitButton(Button btn, UInt32 scanCode) { btn.Text = InteropEmu.GetKeyName(scanCode); @@ -49,6 +78,7 @@ namespace Mesen.GUI.Forms.Config InitButton(btnRight, mappings.Right); InitButton(btnTurboA, mappings.TurboA); InitButton(btnTurboB, mappings.TurboB); + InitButton(btnMicrophone, mappings.Microphone); this.OnChange?.Invoke(this, null); } @@ -79,6 +109,7 @@ namespace Mesen.GUI.Forms.Config InitButton(btnRight, 0); InitButton(btnTurboA, 0); InitButton(btnTurboB, 0); + InitButton(btnMicrophone, 0); this.OnChange?.Invoke(this, null); } @@ -108,6 +139,7 @@ namespace Mesen.GUI.Forms.Config TurboB = (UInt32)btnTurboB.Tag, TurboSelect = 0, TurboStart = 0, + Microphone = (UInt32)btnMicrophone.Tag, }; return mappings; } diff --git a/GUI.NET/Forms/Config/ctrlStandardController.resx b/GUI.NET/Forms/Config/ctrlStandardController.resx index 3987fb71..1af7de15 100644 --- a/GUI.NET/Forms/Config/ctrlStandardController.resx +++ b/GUI.NET/Forms/Config/ctrlStandardController.resx @@ -117,169 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 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 - w9JudSxN4uTegdtxMDGTJx9jTjD8v3jG6a1XrR1S21eOSVIrkh4ReXj2a1WX/FBwsjZLlqN3x8trr+8t - 4UselnarY2kSJ/cO3I6Difmj4M23WbWMOcxMHqe1feWYJBRJT4/xgpIsFXFj6xP9GPucJW+JxwVLlqNx - 3rlN7T09lZ+Th6Xd6liaxMm9A7fjYGL+MHjzl61axhxmJo/T2r5yTJIfYzOs4QgIE/7FtdfrbMkdgwdn - nX+UsORG8fTo9ef3IeFLHpZ2q2NpEif3DtyOg4n5g+DNt121TM98enxGfGZ8Vnx2fE5cFFeMK8XFceW4 - SnChv6vG1eLqcY24ZlwrrhPXjevFDeKGcaPgyAA3feXee9xahtt2cMFFrnvFZR34yDznU3DOGUuqLFdR - aPD3/vK4XXxFfGXw0fA7xFcHE8PXxNfGneLOcZe4a3xdfH18Q9w97hH3jHvFveMb4z5x3/jmuF/cP74l - HhDfFg+Mb48Hx3fEdwb/7/y74ruDE4y/J74vHhZvDMYpv/NOqe0r0rYSTnRffaqt0vfoeEutr6eEL3lY - 2q2OpUmc3DtwOw4m5iXBmzkcz38MfjoeG/w/zcfHzwaH658YTwo++vpz8fPxC/GUeGo8LfgevxTPiGfG - s+KX49nxK/Gc+LX49XhucGG234znxwvi8vit+O3g0zi/Ey8KPrb84vj94PelsOPIAuepcE4VJ5/z6Seu - pcN1n7hAJldo5n5f3JuOm/hyF/nXB8sMTLhvCv5f4FvjbcFJmO+Id8a74j3x3nhfcBuHD8aHguujfCQ+ - Gpyj8Ffx18Gnhf4m/jbYntoPirqdUttXpDlhGA9DubRbHUuTOLl34HYcTMzvBW9WfxRMFE4UUBRSFFQU - VhRYFFoUXBReFGAUYhRkFGYUaBRqFGwUbhRwFHIUdBR2FHgUehR8FH4UgBSCFIQUhhSIFIoUjBSOFJAU - khSUFJYUmBSaFJwUnhSgFKIUpBSmFKgUqhSsFK4UsBSyFLQUthS4FLoUvBS+FMAUwhTEFMYUyBTKFMwU - zhTQFNIU1BTWFNgU2hTcFN4U4BTiFOQU5hToFOoU7BTuPxk/ET8eHD3bKbV9RZoThvEwlEu71bE0yTi5 - 8x8iHu8LZ+I/6gSdxs9jO1ok7R6WQh4eLGmwtMESB0sdLHmw9MESCEshLImwNMISCUslLJmwdMISCksp - fB+WVlhiYamFJReWXliCYSmGJRmWZliiYamGJRuWbljCYSmHJR2WdljiYamHJR+WflgCYimIJSGOIrDc - wlIRS0YsHbGExFISS0osLbHExFITS04sPbEExVIUS1IsTTHJslTFkhVLVyxhsZTFkhZLWyxxsdTFkhdL - XyyBsRTGkhhLYyyRsVTGkhlLZyyhsZTGkhpLayyxmQNKbV+R5oRhPAzl0m51LE1CAbP6N56AT5ygk/55 - 4GdaJBljzkptX5HmhGE8DOXSbnUsUbJ51Gcf9n2katNJ/7yV2vY9JsaYc1PbV6Q5YRgPQ7m0Wx2S2owx - 56a2r0hzwjAehnJptzoktRljzk1tX5HmhGE8DOXSbnVIajPGnJvaviLNCcN4GMql3eqQ1GaMOTe1fUWa - E4bxMJRLu9Uhqc0Yc25q+4o0JwzjYSiXdqtDUpsx5tzU9hVpThjGw1Au7VaHpDZjzLmp7SvSnDCMh6Fc - 2q0OSW1mman9rSUdD/4zMPynoLRbHZIkScdksxZqdkiSJB2TzVqo2SFJknRMNmuhZockSdIx2ayFmh2S - JEnHZLMWanZIkiQdk81aqNkhSZJ0TDZroWaHJEnSMdmshZodkiRJx2SzFmp2SJIkHZPNWqjZIUmSdEw2 - a6FmhyRJ0jHZrIWaHZIkScdksxZqdkiSJB2TzVqo2SFJknRMNmuhczokSZKOmUWSJElSxTlFkiRJkkaf - /LT/D/XHWcQRIejmAAAAAElFTkSuQmCC - - \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmControllerConfig.cs b/GUI.NET/Forms/Config/frmControllerConfig.cs index 13c6c9a7..1f27e60b 100644 --- a/GUI.NET/Forms/Config/frmControllerConfig.cs +++ b/GUI.NET/Forms/Config/frmControllerConfig.cs @@ -15,7 +15,7 @@ namespace Mesen.GUI.Forms.Config { private KeyPresets _presets = new KeyPresets(); - public frmControllerConfig(ControllerInfo controllerInfo, int portNumber) + public frmControllerConfig(ControllerInfo controllerInfo, int portNumber, ConsoleType consoleType) { InitializeComponent(); @@ -27,6 +27,13 @@ namespace Mesen.GUI.Forms.Config ctrlStandardController2.Initialize(controllerInfo.Keys[2]); ctrlStandardController3.Initialize(controllerInfo.Keys[3]); + if(portNumber == 1 && consoleType == ConsoleType.Famicom) { + ctrlStandardController0.ShowMicrophone = true; + ctrlStandardController1.ShowMicrophone = true; + ctrlStandardController2.ShowMicrophone = true; + ctrlStandardController3.ShowMicrophone = true; + } + ResourceHelper.ApplyResources(this, mnuStripPreset); this.Text += ": " + ResourceHelper.GetMessage("PlayerNumber", (portNumber + 1).ToString()); diff --git a/GUI.NET/Forms/Config/frmInputConfig.Designer.cs b/GUI.NET/Forms/Config/frmInputConfig.Designer.cs index 6b3504bc..2829a33d 100644 --- a/GUI.NET/Forms/Config/frmInputConfig.Designer.cs +++ b/GUI.NET/Forms/Config/frmInputConfig.Designer.cs @@ -53,6 +53,7 @@ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.picWarning = new System.Windows.Forms.PictureBox(); this.lblKeyBinding = new System.Windows.Forms.Label(); + this.btnSetupExp = new System.Windows.Forms.Button(); this.tpgAdvanced = new System.Windows.Forms.TabPage(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.grpDisplayInput = new System.Windows.Forms.GroupBox(); @@ -66,7 +67,6 @@ this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); this.lblDisplayPosition = new System.Windows.Forms.Label(); this.cboDisplayInputPosition = new System.Windows.Forms.ComboBox(); - this.btnSetupExp = new System.Windows.Forms.Button(); this.tabMain.SuspendLayout(); this.tpgControllers.SuspendLayout(); this.tlpControllers.SuspendLayout(); @@ -398,6 +398,19 @@ this.lblKeyBinding.TabIndex = 1; this.lblKeyBinding.Text = resources.GetString("lblKeyBinding.Text"); // + // btnSetupExp + // + this.btnSetupExp.AutoSize = true; + this.btnSetupExp.Location = new System.Drawing.Point(297, 197); + this.btnSetupExp.Name = "btnSetupExp"; + this.btnSetupExp.Size = new System.Drawing.Size(62, 23); + this.btnSetupExp.TabIndex = 20; + this.btnSetupExp.Text = "Setup"; + this.btnSetupExp.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.btnSetupExp.UseVisualStyleBackColor = true; + this.btnSetupExp.Visible = false; + this.btnSetupExp.Click += new System.EventHandler(this.btnSetup_Click); + // // tpgAdvanced // this.tpgAdvanced.Controls.Add(this.tableLayoutPanel2); @@ -544,18 +557,6 @@ this.cboDisplayInputPosition.Size = new System.Drawing.Size(121, 21); this.cboDisplayInputPosition.TabIndex = 1; // - // btnSetupExp - // - this.btnSetupExp.AutoSize = true; - this.btnSetupExp.Location = new System.Drawing.Point(297, 197); - this.btnSetupExp.Name = "btnSetupExp"; - this.btnSetupExp.Size = new System.Drawing.Size(62, 23); - this.btnSetupExp.TabIndex = 20; - this.btnSetupExp.Text = "Setup"; - this.btnSetupExp.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; - this.btnSetupExp.UseVisualStyleBackColor = true; - this.btnSetupExp.Click += new System.EventHandler(this.btnSetup_Click); - // // frmInputConfig // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/GUI.NET/Forms/Config/frmInputConfig.cs b/GUI.NET/Forms/Config/frmInputConfig.cs index 7a54718a..4a61b856 100644 --- a/GUI.NET/Forms/Config/frmInputConfig.cs +++ b/GUI.NET/Forms/Config/frmInputConfig.cs @@ -111,6 +111,7 @@ namespace Mesen.GUI.Forms.Config bool isNes = ((InputInfo)Entity).ConsoleType == ConsoleType.Nes; cboExpansionPort.Visible = !isNes; lblExpansionPort.Visible = !isNes; + btnSetupExp.Visible = !isNes; chkFourScore.Visible = isNes; UpdatePlayer3And4Visibility(); @@ -219,7 +220,7 @@ namespace Mesen.GUI.Forms.Config Form frm = null; if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.StandardController))) { - frm = new frmControllerConfig(ConfigManager.Config.InputInfo.Controllers[index], index); + frm = new frmControllerConfig(ConfigManager.Config.InputInfo.Controllers[index], index, cboConsoleType.GetEnumValue()); } else if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.Zapper))) { frm = new frmZapperConfig(ConfigManager.Config.InputInfo.Zapper); } else if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ExpansionPortDevice.Zapper))) { diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj index d97dde72..554aec94 100644 --- a/GUI.NET/GUI.NET.csproj +++ b/GUI.NET/GUI.NET.csproj @@ -537,12 +537,6 @@ ctrlEmulatorShortcuts.cs - - UserControl - - - ctrlInputPortConfig.cs - UserControl @@ -876,9 +870,6 @@ ctrlEmulatorShortcuts.cs - - ctrlInputPortConfig.cs - ctrlPathSelection.cs diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 77df0ac8..c5d41a9e 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -733,6 +733,7 @@ namespace Mesen.GUI public UInt32 TurboB; public UInt32 TurboStart; public UInt32 TurboSelect; + public UInt32 Microphone; } public enum StereoFilter