diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h
index 7a3eb1f1..dded975b 100644
--- a/Core/EmulationSettings.h
+++ b/Core/EmulationSettings.h
@@ -90,6 +90,9 @@ enum EmulationFlags : uint64_t
ReduceSoundInFastForward = 0x100000000000000,
+ VsDualMuteMaster = 0x200000000000000,
+ VsDualMuteSlave = 0x400000000000000,
+
ForceMaxSpeed = 0x4000000000000000,
ConsoleMode = 0x8000000000000000,
};
diff --git a/Core/SoundMixer.cpp b/Core/SoundMixer.cpp
index f077850a..c80ee624 100644
--- a/Core/SoundMixer.cpp
+++ b/Core/SoundMixer.cpp
@@ -116,6 +116,14 @@ void SoundMixer::PlayAudioBuffer(uint32_t time)
_oggMixer->ApplySamples(_outputBuffer, sampleCount);
}
+ if(_console->IsDualSystem()) {
+ if(_console->IsMaster() && EmulationSettings::CheckFlag(EmulationFlags::VsDualMuteMaster)) {
+ _lowPassFilter.ApplyFilter(_outputBuffer, sampleCount, 0, 0);
+ } else if(!_console->IsMaster() && EmulationSettings::CheckFlag(EmulationFlags::VsDualMuteSlave)) {
+ _lowPassFilter.ApplyFilter(_outputBuffer, sampleCount, 0, 0);
+ }
+ }
+
RewindManager* rewindManager = _console->GetRewindManager();
if(!_console->GetVideoRenderer()->IsRecording() && !_waveRecorder && !EmulationSettings::CheckFlag(EmulationFlags::NsfPlayerEnabled)) {
diff --git a/GUI.NET/Config/PreferenceInfo.cs b/GUI.NET/Config/PreferenceInfo.cs
index a2eaf454..79b11497 100644
--- a/GUI.NET/Config/PreferenceInfo.cs
+++ b/GUI.NET/Config/PreferenceInfo.cs
@@ -40,6 +40,9 @@ namespace Mesen.GUI.Config
public bool AssociateMstFiles = false;
public bool AssociateUnfFiles = false;
+ public VsDualOutputOption VsDualVideoOutput = VsDualOutputOption.Both;
+ public VsDualOutputOption VsDualAudioOutput = VsDualOutputOption.Both;
+
public bool NsfEnableApuIrqs = false;
public bool NsfMoveToNextTrackAfterTime = true;
public Int32 NsfMoveToNextTrackTime = 120;
@@ -201,6 +204,9 @@ namespace Mesen.GUI.Config
InteropEmu.SetFlag(EmulationFlags.DisplayDebugInfo, preferenceInfo.DisplayDebugInfo);
+ InteropEmu.SetFlag(EmulationFlags.VsDualMuteMaster, preferenceInfo.VsDualAudioOutput == VsDualOutputOption.SlaveOnly);
+ InteropEmu.SetFlag(EmulationFlags.VsDualMuteSlave, preferenceInfo.VsDualAudioOutput == VsDualOutputOption.MasterOnly);
+
InteropEmu.SetAutoSaveOptions(preferenceInfo.AutoSave ? (uint)preferenceInfo.AutoSaveDelay : 0, preferenceInfo.AutoSaveNotify);
InteropEmu.ClearShortcutKeys();
@@ -230,4 +236,11 @@ namespace Mesen.GUI.Config
KeyCombination = keyCombination;
}
}
+
+ public enum VsDualOutputOption
+ {
+ Both = 0,
+ MasterOnly = 1,
+ SlaveOnly = 2
+ }
}
diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml
index d3e6219b..8aa31bcd 100644
--- a/GUI.NET/Dependencies/resources.ca.xml
+++ b/GUI.NET/Dependencies/resources.ca.xml
@@ -409,6 +409,10 @@
Darrera sincronització:
Resincronitza
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Configuració de Famicom Disk System
Configuració de la interfície d'usuari
Window Settings
@@ -423,7 +427,7 @@
Always display on top of other windows
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Reprodueix la següent pista després de
mil·lisegons de silenci
@@ -948,6 +952,11 @@
Preescalat 8x
Preescalat 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml
index 6e37f258..576b3c4f 100644
--- a/GUI.NET/Dependencies/resources.en.xml
+++ b/GUI.NET/Dependencies/resources.en.xml
@@ -410,6 +410,10 @@
Last Sync:
Resync
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Famicom Disk System Settings
UI Display Settings
Window Settings
@@ -424,7 +428,7 @@
Always display on top of other windows
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Move to next track after
milliseconds of silence
@@ -982,6 +986,11 @@
Prescale 8x
Prescale 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml
index 19cba7ef..d06fdfdc 100644
--- a/GUI.NET/Dependencies/resources.es.xml
+++ b/GUI.NET/Dependencies/resources.es.xml
@@ -407,6 +407,10 @@
Última sincronización:
Resincronizar
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Configuración de Famicom Disk System
Configuración de interfaz de usuario
Ventana de ajustes
@@ -421,7 +425,7 @@
Mostrar siempre sobre otras ventanas
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Reproducir la siguiente pista después
milisegundos de silencio
@@ -965,6 +969,11 @@
Preescala 8x
Preescala 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml
index fb9a430f..a410252c 100644
--- a/GUI.NET/Dependencies/resources.fr.xml
+++ b/GUI.NET/Dependencies/resources.fr.xml
@@ -409,6 +409,10 @@
Dernière synchronisation :
Resynchroniser
+ Options pour le Vs. DualSystem
+ Jouer le son pour :
+ Affichage l'image pour :
+
Options pour le Famicom Disk System
Options d'affichage de l'interface
Options de la fenêtre
@@ -423,7 +427,7 @@
Afficher la fenêtre au premier plan
- FDS / NSF
+ FDS / VS / NSF
Options pour les fichiers NSF
Jouer la piste suivante après
millisecondes de silence
@@ -979,6 +983,11 @@
Prescale 8x
Prescale 10x
+
+ Les deux CPUs
+ CPU #1 uniquement
+ CPU #2 uniquement
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml
index ff1cb2c0..5c0eeccf 100644
--- a/GUI.NET/Dependencies/resources.ja.xml
+++ b/GUI.NET/Dependencies/resources.ja.xml
@@ -408,6 +408,10 @@
同期
最終同期:
+ VS.システム設定
+ 次の音声を再生する:
+ 次の映像を表示する:
+
ファミコンディスクシステム設定
ユーザーインターフェイス表示設定
ウインドウ設定
@@ -422,7 +426,7 @@
他のウインドウより常に手前に表示する
- FDS・NSF
+ FDS・VS・NSF
NSF設定
無音検出:
ミリ秒間で無音の場合、次の曲を再生
@@ -964,6 +968,11 @@
Prescale 8x
Prescale 10x
+
+ 両方
+ マスターのみ
+ スレーブのみ
+
NES
ファミコン
diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml
index 700a1f1f..11855ff7 100644
--- a/GUI.NET/Dependencies/resources.pt.xml
+++ b/GUI.NET/Dependencies/resources.pt.xml
@@ -405,6 +405,10 @@
Última sincronização:
Ressincronizar
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Configurações do Famicom Disk System
Configuração da interface de usuário
Window Settings
@@ -419,7 +423,7 @@
Sempre exibir em cima de outras janelas
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Reproduzir a faixa seguinte depois de
milissegundos de silêncio
@@ -966,6 +970,11 @@
Preescala 8x
Preescala 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml
index cf970e8d..ec17404b 100644
--- a/GUI.NET/Dependencies/resources.ru.xml
+++ b/GUI.NET/Dependencies/resources.ru.xml
@@ -406,6 +406,10 @@
Последняя синхронизация :
Синхронизировать
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Famicom Disk System Settings
UI Display Settings
Window Settings
@@ -420,7 +424,7 @@
Always display on top of other windows
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Переходить на следующий трек после
миллисекунд тишины
@@ -967,6 +971,11 @@
Prescale 8x
Prescale 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml
index 2c79ad93..00f6c065 100644
--- a/GUI.NET/Dependencies/resources.uk.xml
+++ b/GUI.NET/Dependencies/resources.uk.xml
@@ -406,6 +406,10 @@
Востаннє синхронізовано :
Синхронізувати
+ VS. DualSystem Settings
+ Play audio for:
+ Show video for:
+
Famicom Disk System Налаштування
Налаштування дисплея інтерфейсу користувача
Window Settings
@@ -420,7 +424,7 @@
Завжди відображати поверх інших вікон
- FDS / NSF
+ FDS / VS / NSF
NSF Settings
Відтворити наступний трек після
мілісекунд тиші
@@ -967,6 +971,11 @@
Prescale 8x
Prescale 10x
+
+ Both
+ Master Only
+ Slave Only
+
NES
Famicom
diff --git a/GUI.NET/Forms/Config/frmPreferences.Designer.cs b/GUI.NET/Forms/Config/frmPreferences.Designer.cs
index 45bfc4b6..70a6f03d 100644
--- a/GUI.NET/Forms/Config/frmPreferences.Designer.cs
+++ b/GUI.NET/Forms/Config/frmPreferences.Designer.cs
@@ -85,6 +85,12 @@ namespace Mesen.GUI.Forms.Config
this.lblAutoSave = new System.Windows.Forms.Label();
this.tpgFdsNfs = new System.Windows.Forms.TabPage();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.flowLayoutPanel10 = new System.Windows.Forms.FlowLayoutPanel();
+ this.lblVsDualPlayAudio = new System.Windows.Forms.Label();
+ this.cboVsDualAudioOutput = new System.Windows.Forms.ComboBox();
+ this.flowLayoutPanel9 = new System.Windows.Forms.FlowLayoutPanel();
+ this.lblVsDualShowVideo = new System.Windows.Forms.Label();
+ this.cboVsDualVideoOutput = new System.Windows.Forms.ComboBox();
this.lblNsfSettings = new System.Windows.Forms.Label();
this.lblFdsSettings = new System.Windows.Forms.Label();
this.chkFdsAutoLoadDisk = new System.Windows.Forms.CheckBox();
@@ -99,6 +105,7 @@ namespace Mesen.GUI.Forms.Config
this.nudNsfMoveToNextTrackTime = new Mesen.GUI.Controls.MesenNumericUpDown();
this.lblNsfSeconds = new System.Windows.Forms.Label();
this.chkNsfEnableApuIrqs = new Mesen.GUI.Controls.ctrlRiskyOption();
+ this.lblVsDualSystem = new System.Windows.Forms.Label();
this.tpgFiles = new System.Windows.Forms.TabPage();
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
this.grpPathOverrides = new System.Windows.Forms.GroupBox();
@@ -176,6 +183,8 @@ namespace Mesen.GUI.Forms.Config
this.flpAutoSave.SuspendLayout();
this.tpgFdsNfs.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
+ this.flowLayoutPanel10.SuspendLayout();
+ this.flowLayoutPanel9.SuspendLayout();
this.flowLayoutPanel7.SuspendLayout();
this.flowLayoutPanel5.SuspendLayout();
this.tpgFiles.SuspendLayout();
@@ -871,18 +880,21 @@ namespace Mesen.GUI.Forms.Config
//
this.tableLayoutPanel2.ColumnCount = 1;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.tableLayoutPanel2.Controls.Add(this.lblNsfSettings, 0, 4);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel10, 0, 6);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel9, 0, 5);
+ this.tableLayoutPanel2.Controls.Add(this.lblNsfSettings, 0, 7);
this.tableLayoutPanel2.Controls.Add(this.lblFdsSettings, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.chkFdsAutoLoadDisk, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.chkFdsFastForwardOnLoad, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.chkFdsAutoInsertDisk, 0, 3);
- this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel7, 0, 5);
- this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel5, 0, 6);
- this.tableLayoutPanel2.Controls.Add(this.chkNsfEnableApuIrqs, 0, 7);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel7, 0, 8);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel5, 0, 9);
+ this.tableLayoutPanel2.Controls.Add(this.chkNsfEnableApuIrqs, 0, 10);
+ this.tableLayoutPanel2.Controls.Add(this.lblVsDualSystem, 0, 4);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
- this.tableLayoutPanel2.RowCount = 9;
+ this.tableLayoutPanel2.RowCount = 12;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -890,17 +902,82 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(483, 390);
this.tableLayoutPanel2.TabIndex = 0;
//
+ // flowLayoutPanel10
+ //
+ this.flowLayoutPanel10.Controls.Add(this.lblVsDualPlayAudio);
+ this.flowLayoutPanel10.Controls.Add(this.cboVsDualAudioOutput);
+ this.flowLayoutPanel10.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel10.Location = new System.Drawing.Point(0, 129);
+ this.flowLayoutPanel10.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel10.Name = "flowLayoutPanel10";
+ this.flowLayoutPanel10.Size = new System.Drawing.Size(483, 27);
+ this.flowLayoutPanel10.TabIndex = 29;
+ //
+ // lblVsDualPlayAudio
+ //
+ this.lblVsDualPlayAudio.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblVsDualPlayAudio.AutoSize = true;
+ this.lblVsDualPlayAudio.Location = new System.Drawing.Point(10, 7);
+ this.lblVsDualPlayAudio.Margin = new System.Windows.Forms.Padding(10, 0, 3, 0);
+ this.lblVsDualPlayAudio.Name = "lblVsDualPlayAudio";
+ this.lblVsDualPlayAudio.Size = new System.Drawing.Size(74, 13);
+ this.lblVsDualPlayAudio.TabIndex = 4;
+ this.lblVsDualPlayAudio.Text = "Play audio for:";
+ //
+ // cboVsDualAudioOutput
+ //
+ this.cboVsDualAudioOutput.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cboVsDualAudioOutput.FormattingEnabled = true;
+ this.cboVsDualAudioOutput.Location = new System.Drawing.Point(90, 3);
+ this.cboVsDualAudioOutput.Name = "cboVsDualAudioOutput";
+ this.cboVsDualAudioOutput.Size = new System.Drawing.Size(127, 21);
+ this.cboVsDualAudioOutput.TabIndex = 5;
+ //
+ // flowLayoutPanel9
+ //
+ this.flowLayoutPanel9.Controls.Add(this.lblVsDualShowVideo);
+ this.flowLayoutPanel9.Controls.Add(this.cboVsDualVideoOutput);
+ this.flowLayoutPanel9.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel9.Location = new System.Drawing.Point(0, 102);
+ this.flowLayoutPanel9.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel9.Name = "flowLayoutPanel9";
+ this.flowLayoutPanel9.Size = new System.Drawing.Size(483, 27);
+ this.flowLayoutPanel9.TabIndex = 28;
+ //
+ // lblVsDualShowVideo
+ //
+ this.lblVsDualShowVideo.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblVsDualShowVideo.AutoSize = true;
+ this.lblVsDualShowVideo.Location = new System.Drawing.Point(10, 7);
+ this.lblVsDualShowVideo.Margin = new System.Windows.Forms.Padding(10, 0, 3, 0);
+ this.lblVsDualShowVideo.Name = "lblVsDualShowVideo";
+ this.lblVsDualShowVideo.Size = new System.Drawing.Size(114, 13);
+ this.lblVsDualShowVideo.TabIndex = 4;
+ this.lblVsDualShowVideo.Text = "Show video for:";
+ //
+ // cboVsDualVideoOutput
+ //
+ this.cboVsDualVideoOutput.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cboVsDualVideoOutput.FormattingEnabled = true;
+ this.cboVsDualVideoOutput.Location = new System.Drawing.Point(130, 3);
+ this.cboVsDualVideoOutput.Name = "cboVsDualVideoOutput";
+ this.cboVsDualVideoOutput.Size = new System.Drawing.Size(127, 21);
+ this.cboVsDualVideoOutput.TabIndex = 5;
+ //
// lblNsfSettings
//
this.lblNsfSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lblNsfSettings.AutoSize = true;
this.lblNsfSettings.ForeColor = System.Drawing.SystemColors.GrayText;
- this.lblNsfSettings.Location = new System.Drawing.Point(0, 89);
+ this.lblNsfSettings.Location = new System.Drawing.Point(0, 163);
this.lblNsfSettings.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.lblNsfSettings.Name = "lblNsfSettings";
this.lblNsfSettings.Size = new System.Drawing.Size(69, 13);
@@ -958,7 +1035,7 @@ namespace Mesen.GUI.Forms.Config
this.flowLayoutPanel7.Controls.Add(this.nudNsfAutoDetectSilenceDelay);
this.flowLayoutPanel7.Controls.Add(this.lblNsfMillisecondsOfSilence);
this.flowLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
- this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 102);
+ this.flowLayoutPanel7.Location = new System.Drawing.Point(0, 176);
this.flowLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel7.Name = "flowLayoutPanel7";
this.flowLayoutPanel7.Size = new System.Drawing.Size(483, 24);
@@ -1025,7 +1102,7 @@ namespace Mesen.GUI.Forms.Config
this.flowLayoutPanel5.Controls.Add(this.nudNsfMoveToNextTrackTime);
this.flowLayoutPanel5.Controls.Add(this.lblNsfSeconds);
this.flowLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
- this.flowLayoutPanel5.Location = new System.Drawing.Point(0, 126);
+ this.flowLayoutPanel5.Location = new System.Drawing.Point(0, 200);
this.flowLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel5.Name = "flowLayoutPanel5";
this.flowLayoutPanel5.Size = new System.Drawing.Size(483, 24);
@@ -1090,13 +1167,25 @@ namespace Mesen.GUI.Forms.Config
//
this.chkNsfEnableApuIrqs.Checked = false;
this.chkNsfEnableApuIrqs.Dock = System.Windows.Forms.DockStyle.Fill;
- this.chkNsfEnableApuIrqs.Location = new System.Drawing.Point(10, 150);
+ this.chkNsfEnableApuIrqs.Location = new System.Drawing.Point(10, 224);
this.chkNsfEnableApuIrqs.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
this.chkNsfEnableApuIrqs.Name = "chkNsfEnableApuIrqs";
this.chkNsfEnableApuIrqs.Size = new System.Drawing.Size(473, 23);
this.chkNsfEnableApuIrqs.TabIndex = 26;
this.chkNsfEnableApuIrqs.Text = "Enable APU IRQs for NSF files";
//
+ // lblVsDualSystem
+ //
+ this.lblVsDualSystem.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.lblVsDualSystem.AutoSize = true;
+ this.lblVsDualSystem.ForeColor = System.Drawing.SystemColors.GrayText;
+ this.lblVsDualSystem.Location = new System.Drawing.Point(0, 89);
+ this.lblVsDualSystem.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
+ this.lblVsDualSystem.Name = "lblVsDualSystem";
+ this.lblVsDualSystem.Size = new System.Drawing.Size(121, 13);
+ this.lblVsDualSystem.TabIndex = 27;
+ this.lblVsDualSystem.Text = "VS DualSystem Settings";
+ //
// tpgFiles
//
this.tpgFiles.Controls.Add(this.tableLayoutPanel6);
@@ -1894,6 +1983,10 @@ namespace Mesen.GUI.Forms.Config
this.tpgFdsNfs.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
+ this.flowLayoutPanel10.ResumeLayout(false);
+ this.flowLayoutPanel10.PerformLayout();
+ this.flowLayoutPanel9.ResumeLayout(false);
+ this.flowLayoutPanel9.PerformLayout();
this.flowLayoutPanel7.ResumeLayout(false);
this.flowLayoutPanel7.PerformLayout();
this.flowLayoutPanel5.ResumeLayout(false);
@@ -2048,5 +2141,12 @@ namespace Mesen.GUI.Forms.Config
private System.Windows.Forms.Label lblWindowSettings;
private System.Windows.Forms.CheckBox chkDisableMouseResize;
private ctrlRiskyOption chkNsfEnableApuIrqs;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel10;
+ private System.Windows.Forms.Label lblVsDualPlayAudio;
+ private System.Windows.Forms.ComboBox cboVsDualAudioOutput;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel9;
+ private System.Windows.Forms.Label lblVsDualShowVideo;
+ private System.Windows.Forms.ComboBox cboVsDualVideoOutput;
+ private System.Windows.Forms.Label lblVsDualSystem;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Forms/Config/frmPreferences.cs b/GUI.NET/Forms/Config/frmPreferences.cs
index b467e31a..c5fc5a5f 100644
--- a/GUI.NET/Forms/Config/frmPreferences.cs
+++ b/GUI.NET/Forms/Config/frmPreferences.cs
@@ -43,6 +43,9 @@ namespace Mesen.GUI.Forms.Config
AddBinding("NsfAutoDetectSilenceDelay", nudNsfAutoDetectSilenceDelay);
AddBinding("NsfEnableApuIrqs", chkNsfEnableApuIrqs);
+ AddBinding("VsDualVideoOutput", cboVsDualVideoOutput);
+ AddBinding("VsDualAudioOutput", cboVsDualAudioOutput);
+
AddBinding("FdsAutoLoadDisk", chkFdsAutoLoadDisk);
AddBinding("FdsFastForwardOnLoad", chkFdsFastForwardOnLoad);
AddBinding("FdsAutoInsertDisk", chkFdsAutoInsertDisk);
diff --git a/GUI.NET/Forms/frmMain.Options.cs b/GUI.NET/Forms/frmMain.Options.cs
index 5ce61d60..4c369065 100644
--- a/GUI.NET/Forms/frmMain.Options.cs
+++ b/GUI.NET/Forms/frmMain.Options.cs
@@ -122,7 +122,17 @@ namespace Mesen.GUI.Forms
private void mnuPreferences_Click(object sender, EventArgs e)
{
using(frmPreferences frm = new frmPreferences()) {
+ VsDualOutputOption originalVsDualOutput = ConfigManager.Config.PreferenceInfo.VsDualVideoOutput;
+
if(frm.ShowDialog(sender, this) == DialogResult.OK) {
+ VsDualOutputOption newVsDualOutput = ConfigManager.Config.PreferenceInfo.VsDualVideoOutput;
+ if(originalVsDualOutput != newVsDualOutput) {
+ if(newVsDualOutput == VsDualOutputOption.Both || originalVsDualOutput == VsDualOutputOption.Both) {
+ UpdateViewerSize(true);
+ } else {
+ UpdateDualSystemViewer();
+ }
+ }
ResourceHelper.LoadResources(ConfigManager.Config.PreferenceInfo.DisplayLanguage);
ResourceHelper.UpdateEmuLanguage();
ResourceHelper.ApplyResources(this);
diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs
index d446804d..bd2bbd8a 100644
--- a/GUI.NET/Forms/frmMain.cs
+++ b/GUI.NET/Forms/frmMain.cs
@@ -340,26 +340,24 @@ namespace Mesen.GUI.Forms
InteropEmu.ScreenSize size = InteropEmu.GetScreenSize(false);
- int width = _isDualSystem ? (size.Width * 2) : size.Width;
if(forceUpdate || (!_customSize && this.WindowState != FormWindowState.Maximized)) {
Size sizeGap = this.Size - this.ClientSize;
+ bool doubleScreenMode = _isDualSystem && ConfigManager.Config.PreferenceInfo.VsDualVideoOutput == VsDualOutputOption.Both;
+ int width = doubleScreenMode ? (size.Width * 2) : size.Width;
+
UpdateScaleMenu(size.Scale);
this.ClientSize = new Size(Math.Max(this.MinimumSize.Width - sizeGap.Width, width), Math.Max(this.MinimumSize.Height - sizeGap.Height, size.Height + (this.HideMenuStrip ? 0 : menuStrip.Height)));
}
ctrlRenderer.Size = new Size(size.Width, size.Height);
- if(_isDualSystem) {
- ctrlRendererDualSystem.Size = new Size(size.Width, size.Height);
- ctrlRendererDualSystem.Top = (panelRenderer.Height - ctrlRenderer.Height) / 2;
-
- ctrlRenderer.Left = (panelRenderer.Width / 2 - ctrlRenderer.Width) / 2;
- ctrlRendererDualSystem.Left = ctrlRenderer.Left + ctrlRenderer.Width;
- } else {
- ctrlRenderer.Left = (panelRenderer.Width - ctrlRenderer.Width) / 2;
- }
ctrlRenderer.Top = (panelRenderer.Height - ctrlRenderer.Height) / 2;
-
+ ctrlRenderer.Left = (panelRenderer.Width - ctrlRenderer.Width) / 2;
+
+ if(_isDualSystem) {
+ UpdateDualSystemViewer();
+ }
+
if(this.HideMenuStrip) {
this.menuStrip.Visible = false;
}
@@ -367,6 +365,28 @@ namespace Mesen.GUI.Forms
this.Resize += frmMain_Resize;
}
+ private void UpdateDualSystemViewer()
+ {
+ ctrlRendererDualSystem.Size = new Size(ctrlRenderer.Width, ctrlRenderer.Height);
+ ctrlRendererDualSystem.Top = (panelRenderer.Height - ctrlRenderer.Height) / 2;
+
+ if(ConfigManager.Config.PreferenceInfo.VsDualVideoOutput == VsDualOutputOption.Both) {
+ ctrlRenderer.Left = (panelRenderer.Width / 2 - ctrlRenderer.Width) / 2;
+ ctrlRendererDualSystem.Left = ctrlRenderer.Left + ctrlRenderer.Width;
+
+ ctrlRendererDualSystem.Visible = true;
+ } else {
+ ctrlRendererDualSystem.Left = (panelRenderer.Width - ctrlRenderer.Width) / 2;
+
+ if(ConfigManager.Config.PreferenceInfo.VsDualVideoOutput == VsDualOutputOption.SlaveOnly) {
+ ctrlRendererDualSystem.Visible = true;
+ ctrlRendererDualSystem.BringToFront();
+ } else {
+ ctrlRendererDualSystem.Visible = false;
+ }
+ }
+ }
+
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
_yFactor = factor.Height;
@@ -644,7 +664,6 @@ namespace Mesen.GUI.Forms
case InteropEmu.ConsoleNotificationType.VsDualSystemStarted:
_isDualSystem = true;
this.BeginInvoke((MethodInvoker)(() => {
- ctrlRendererDualSystem.Visible = _isDualSystem;
UpdateViewerSize(true);
InteropEmu.InitializeDualSystem(this.Handle, ctrlRendererDualSystem.Handle);
}));
@@ -654,7 +673,6 @@ namespace Mesen.GUI.Forms
_isDualSystem = false;
InteropEmu.ReleaseDualSystemAudioVideo();
this.BeginInvoke((MethodInvoker)(() => {
- ctrlRendererDualSystem.Visible = _isDualSystem;
UpdateViewerSize(true);
}));
break;
diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs
index c83b42b9..9d8b316c 100644
--- a/GUI.NET/InteropEmu.cs
+++ b/GUI.NET/InteropEmu.cs
@@ -1543,6 +1543,9 @@ namespace Mesen.GUI
ReduceSoundInFastForward = 0x100000000000000,
+ VsDualMuteMaster = 0x200000000000000,
+ VsDualMuteSlave = 0x400000000000000,
+
ForceMaxSpeed = 0x4000000000000000,
ConsoleMode = 0x8000000000000000,
}