From fb9ac2f3af112fd166fd99f58b5f5c2afb567379 Mon Sep 17 00:00:00 2001
From: alyosha-tas <alexei.f.k@gmail.com>
Date: Sun, 16 Jun 2019 08:17:34 -0400
Subject: [PATCH] Vectrex: hook up controllers

---
 .../movie/bk2/Bk2MnemonicConstants.cs         |  2 ++
 .../Consoles/GCE/Vectrex/Audio.cs             |  2 +-
 .../Consoles/GCE/Vectrex/HW_Registers.cs      |  1 +
 .../GCE/Vectrex/VectrexHawk.IEmulator.cs      |  4 +++
 .../GCE/Vectrex/VectrexHawk.ISettable.cs      | 27 +++++++++++++++----
 .../Consoles/GCE/Vectrex/VectrexHawk.cs       |  2 +-
 .../GCE/Vectrex/VectrexHawkControllerDeck.cs  | 27 +++++++++++++++++--
 .../GCE/Vectrex/VectrexHawkControllers.cs     | 16 ++++++++---
 8 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs b/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs
index 4607722cd4..308b08a1c5 100644
--- a/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs
+++ b/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs
@@ -81,6 +81,8 @@ namespace BizHawk.Client.Common
 			["Button"] = 'B',
 			["Button 1"] = '1',
 			["Button 2"] = '2',
+			["Button 3"] = '3',
+			["Button 4"] = '4',
 			["B1"] = '1',
 			["B2"] = '2',
 
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
index 69e470392e..876c755b54 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
@@ -183,7 +183,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 			psg_clock++;
 			master_audio_clock++;
 
-			if (psg_clock == 1)
+			if (psg_clock == 8)
 			{
 				psg_clock = 0;
 
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/HW_Registers.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/HW_Registers.cs
index f3ea985d46..8ffed8ac34 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/HW_Registers.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/HW_Registers.cs
@@ -53,6 +53,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 					if (!bdir && bc1)
 					{
 						ret = audio.ReadReg(0);
+						if (audio.port_sel == 14) { _islag = false; }
 					}
 					else
 					{
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.IEmulator.cs
index f6fe6b8c94..b0d97a692a 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.IEmulator.cs
@@ -32,6 +32,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 
 			_islag = true;
 
+			// button inputs go to port 14 in the audio registers
+			audio.Register[14] = _controllerDeck.ReadPort1(controller);
+			audio.Register[14] |= (byte)(_controllerDeck.ReadPort2(controller) << 4);
+
 			do_frame();
 
 			if (_islag)
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ISettable.cs
index 53b8c11013..32dd9eeabb 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ISettable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ISettable.cs
@@ -49,6 +49,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 		{
 			[JsonIgnore]
 			public string Port1 = VectrexHawkControllerDeck.DefaultControllerName;
+			public string Port2 = VectrexHawkControllerDeck.DefaultControllerName;
 
 			public enum ControllerType
 			{
@@ -56,20 +57,36 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 			}
 
 			[JsonIgnore]
-			private ControllerType _VectrexController;
+			private ControllerType _VectrexController1;
+			private ControllerType _VectrexController2;
 
-			[DisplayName("Controller")]
+			[DisplayName("Controller 1")]
 			[Description("Select Controller Type")]
 			[DefaultValue(ControllerType.Default)]
-			public ControllerType VectrexController
+			public ControllerType VectrexController1
 			{
-				get { return _VectrexController; }
+				get { return _VectrexController1; }
 				set
 				{
 					if (value == ControllerType.Default) { Port1 = VectrexHawkControllerDeck.DefaultControllerName; }
 					else { Port1 = VectrexHawkControllerDeck.DefaultControllerName; }
 
-					_VectrexController = value;
+					_VectrexController1 = value;
+				}
+			}
+
+			[DisplayName("Controller 2")]
+			[Description("Select Controller Type")]
+			[DefaultValue(ControllerType.Default)]
+			public ControllerType VectrexController2
+			{
+				get { return _VectrexController2; }
+				set
+				{
+					if (value == ControllerType.Default) { Port2 = VectrexHawkControllerDeck.DefaultControllerName; }
+					else { Port2 = VectrexHawkControllerDeck.DefaultControllerName; }
+
+					_VectrexController2 = value;
 				}
 			}
 
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs
index 6e297f9b6a..00fdc1c9d3 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs
@@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 
 			_settings = (VectrexSettings)settings ?? new VectrexSettings();
 			_syncSettings = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();
-			_controllerDeck = new VectrexHawkControllerDeck(_syncSettings.Port1);
+			_controllerDeck = new VectrexHawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
 
 			byte[] Bios = null;
 			Bios = comm.CoreFileProvider.GetFirmware("Vectrex", "Bios", true, "BIOS Not Found, Cannot Load");			
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs
index 39ca11d579..bf0508410d 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs
@@ -10,25 +10,38 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 {
 	public class VectrexHawkControllerDeck
 	{
-		public VectrexHawkControllerDeck(string controller1Name)
+		public VectrexHawkControllerDeck(string controller1Name, string controller2Name)
 		{
 			if (!ValidControllerTypes.ContainsKey(controller1Name))
 			{
 				throw new InvalidOperationException("Invalid controller type: " + controller1Name);
 			}
 
+			if (!ValidControllerTypes.ContainsKey(controller2Name))
+			{
+				throw new InvalidOperationException("Invalid controller type: " + controller2Name);
+			}
+
 			Port1 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller1Name], 1);
+			Port2 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller2Name], 2);
 
 			Definition = new ControllerDefinition
 			{
 				Name = Port1.Definition.Name,
 				BoolButtons = Port1.Definition.BoolButtons
-					.ToList()
+							.Concat(Port2.Definition.BoolButtons)
+							.Concat(new[]
+							{
+								"Power"
+							})
+							.ToList()
 			};
 
 			Definition.FloatControls.AddRange(Port1.Definition.FloatControls);
+			Definition.FloatControls.AddRange(Port2.Definition.FloatControls);
 
 			Definition.FloatRanges.AddRange(Port1.Definition.FloatRanges);
+			Definition.FloatRanges.AddRange(Port2.Definition.FloatRanges);
 		}
 
 		public byte ReadPort1(IController c)
@@ -36,6 +49,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 			return Port1.Read(c);
 		}
 
+		public byte ReadPort2(IController c)
+		{
+			return Port2.Read(c);
+		}
+
 		public ControllerDefinition Definition { get; }
 
 		public void SyncState(Serializer ser)
@@ -43,9 +61,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 			ser.BeginSection("Port1");
 			Port1.SyncState(ser);
 			ser.EndSection();
+
+			ser.BeginSection("Port2");
+			Port2.SyncState(ser);
+			ser.EndSection();
 		}
 
 		private readonly IPort Port1;
+		private readonly IPort Port2;
 
 		private static Dictionary<string, Type> _controllerTypes;
 
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllers.cs
index 08ae1262d4..cf7d15bb0a 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllers.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllers.cs
@@ -33,7 +33,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 				Name = "Vectrex Controller",
 				BoolButtons = BaseDefinition
 				.Select(b => "P" + PortNum + " " + b)
-				.ToList()
+				.ToList(),
+				FloatControls = { "P" + PortNum + " Stick X", "P" + PortNum + " Stick Y" },
+				FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } }
 			};
 		}
 
@@ -43,14 +45,22 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
 
 		public byte Read(IController c)
 		{
-			byte result = 0xFF;
+			byte result = 0x0;
+
+			if (c.IsPressed($"P{PortNum} Button 1")) { result |= 0x1; }
+			if (c.IsPressed($"P{PortNum} Button 2")) { result |= 0x2; }
+			if (c.IsPressed($"P{PortNum} Button 3")) { result |= 0x4; }
+			if (c.IsPressed($"P{PortNum} Button 4")) { result |= 0x8; }
 
 			return result;
 		}
 
 		private static readonly string[] BaseDefinition =
 		{
-
+			"Button 1",
+			"Button 2",
+			"Button 3",
+			"Button 4"
 		};
 
 		public void SyncState(Serializer ser)