diff --git a/StreamViewer.Designer.cs b/StreamViewer.Designer.cs index 570bf70..f9a8c20 100644 --- a/StreamViewer.Designer.cs +++ b/StreamViewer.Designer.cs @@ -37,8 +37,22 @@ namespace robospot_camera_finder timerUpdateZoom = new System.Windows.Forms.Timer(components); btnZoomMin = new Button(); btnZoomMax = new Button(); + grpSACN = new GroupBox(); + tbTilt = new TrackBar(); + tbPan = new TrackBar(); + label2 = new Label(); + numDMXAddr = new NumericUpDown(); + label1 = new Label(); + numUniv = new NumericUpDown(); + timerDMX = new System.Windows.Forms.Timer(components); + cbEnableXboxCtrl = new CheckBox(); ((System.ComponentModel.ISupportInitialize)videoView).BeginInit(); ((System.ComponentModel.ISupportInitialize)tbZoom).BeginInit(); + grpSACN.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)tbTilt).BeginInit(); + ((System.ComponentModel.ISupportInitialize)tbPan).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numDMXAddr).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numUniv).BeginInit(); SuspendLayout(); // // videoView @@ -48,7 +62,7 @@ namespace robospot_camera_finder videoView.Location = new Point(12, 12); videoView.MediaPlayer = null; videoView.Name = "videoView"; - videoView.Size = new Size(870, 495); + videoView.Size = new Size(823, 495); videoView.TabIndex = 0; videoView.Text = "videoView"; // @@ -56,7 +70,7 @@ namespace robospot_camera_finder // tbZoom.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; tbZoom.LargeChange = 20; - tbZoom.Location = new Point(889, 30); + tbZoom.Location = new Point(841, 31); tbZoom.Maximum = 9999; tbZoom.Name = "tbZoom"; tbZoom.Orientation = Orientation.Vertical; @@ -79,7 +93,7 @@ namespace robospot_camera_finder // btnZoomMin.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; btnZoomMin.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); - btnZoomMin.Location = new Point(886, 484); + btnZoomMin.Location = new Point(838, 484); btnZoomMin.Name = "btnZoomMin"; btnZoomMin.Size = new Size(42, 23); btnZoomMin.TabIndex = 2; @@ -91,7 +105,7 @@ namespace robospot_camera_finder // btnZoomMax.Anchor = AnchorStyles.Top | AnchorStyles.Right; btnZoomMax.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); - btnZoomMax.Location = new Point(886, 12); + btnZoomMax.Location = new Point(838, 12); btnZoomMax.Name = "btnZoomMax"; btnZoomMax.Size = new Size(42, 23); btnZoomMax.TabIndex = 3; @@ -99,11 +113,107 @@ namespace robospot_camera_finder btnZoomMax.UseVisualStyleBackColor = true; btnZoomMax.Click += btnZoomMax_Click; // + // grpSACN + // + grpSACN.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; + grpSACN.Controls.Add(tbTilt); + grpSACN.Controls.Add(tbPan); + grpSACN.Controls.Add(label2); + grpSACN.Controls.Add(numDMXAddr); + grpSACN.Controls.Add(label1); + grpSACN.Controls.Add(numUniv); + grpSACN.Location = new Point(892, 12); + grpSACN.Name = "grpSACN"; + grpSACN.Size = new Size(236, 253); + grpSACN.TabIndex = 4; + grpSACN.TabStop = false; + grpSACN.Text = "sACN Control"; + // + // tbTilt + // + tbTilt.Location = new Point(19, 97); + tbTilt.Maximum = 65535; + tbTilt.Name = "tbTilt"; + tbTilt.Orientation = Orientation.Vertical; + tbTilt.Size = new Size(45, 150); + tbTilt.TabIndex = 5; + tbTilt.TickFrequency = 10; + tbTilt.Value = 32768; + // + // tbPan + // + tbPan.Location = new Point(70, 150); + tbPan.Maximum = 65535; + tbPan.Name = "tbPan"; + tbPan.Size = new Size(150, 45); + tbPan.TabIndex = 4; + tbPan.TickFrequency = 10; + tbPan.Value = 32768; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(26, 64); + label2.Name = "label2"; + label2.Size = new Size(78, 15); + label2.TabIndex = 3; + label2.Text = "DMX Address"; + label2.TextAlign = ContentAlignment.MiddleRight; + // + // numDMXAddr + // + numDMXAddr.Location = new Point(110, 62); + numDMXAddr.Maximum = new decimal(new int[] { 504, 0, 0, 0 }); + numDMXAddr.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numDMXAddr.Name = "numDMXAddr"; + numDMXAddr.Size = new Size(120, 23); + numDMXAddr.TabIndex = 2; + numDMXAddr.Value = new decimal(new int[] { 1, 0, 0, 0 }); + numDMXAddr.ValueChanged += numDMXAddr_ValueChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(19, 35); + label1.Name = "label1"; + label1.Size = new Size(85, 15); + label1.TabIndex = 1; + label1.Text = "sACN Universe"; + label1.TextAlign = ContentAlignment.MiddleRight; + // + // numUniv + // + numUniv.Location = new Point(110, 33); + numUniv.Maximum = new decimal(new int[] { 63999, 0, 0, 0 }); + numUniv.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numUniv.Name = "numUniv"; + numUniv.Size = new Size(120, 23); + numUniv.TabIndex = 0; + numUniv.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // timerDMX + // + timerDMX.Enabled = true; + timerDMX.Tick += timerDMX_Tick; + // + // cbEnableXboxCtrl + // + cbEnableXboxCtrl.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + cbEnableXboxCtrl.AutoSize = true; + cbEnableXboxCtrl.Location = new Point(892, 271); + cbEnableXboxCtrl.Name = "cbEnableXboxCtrl"; + cbEnableXboxCtrl.Size = new Size(152, 19); + cbEnableXboxCtrl.TabIndex = 5; + cbEnableXboxCtrl.Text = "Enable Xbox360 Control"; + cbEnableXboxCtrl.UseVisualStyleBackColor = true; + // // StreamViewer // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(933, 519); + ClientSize = new Size(1140, 519); + Controls.Add(cbEnableXboxCtrl); + Controls.Add(grpSACN); Controls.Add(btnZoomMax); Controls.Add(btnZoomMin); Controls.Add(tbZoom); @@ -115,6 +225,12 @@ namespace robospot_camera_finder FormClosed += StreamViewer_FormClosed; ((System.ComponentModel.ISupportInitialize)videoView).EndInit(); ((System.ComponentModel.ISupportInitialize)tbZoom).EndInit(); + grpSACN.ResumeLayout(false); + grpSACN.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)tbTilt).EndInit(); + ((System.ComponentModel.ISupportInitialize)tbPan).EndInit(); + ((System.ComponentModel.ISupportInitialize)numDMXAddr).EndInit(); + ((System.ComponentModel.ISupportInitialize)numUniv).EndInit(); ResumeLayout(false); PerformLayout(); } @@ -126,5 +242,14 @@ namespace robospot_camera_finder private System.Windows.Forms.Timer timerUpdateZoom; private Button btnZoomMin; private Button btnZoomMax; + private GroupBox grpSACN; + private TrackBar tbTilt; + private TrackBar tbPan; + private Label label2; + private NumericUpDown numDMXAddr; + private Label label1; + private NumericUpDown numUniv; + private System.Windows.Forms.Timer timerDMX; + private CheckBox cbEnableXboxCtrl; } } \ No newline at end of file diff --git a/StreamViewer.cs b/StreamViewer.cs index 7a720e6..af34ceb 100644 --- a/StreamViewer.cs +++ b/StreamViewer.cs @@ -1,4 +1,5 @@ -using LibVLCSharp.Shared; +using Haukcode.sACN; +using LibVLCSharp.Shared; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,6 +11,7 @@ using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using XboxControllerTest; namespace robospot_camera_finder { @@ -18,6 +20,11 @@ namespace robospot_camera_finder public LibVLC _libVLC; public MediaPlayer _mp; + private static readonly Guid acnSourceId = new Guid("{B32625A6-C280-4389-BD25-E0D13F5B50E0}"); + private static readonly string acnSourceName = "RoboSpotCamViewer"; + + static SACNClient sendClient = new SACNClient(senderId: acnSourceId, senderName: acnSourceName, localAddress: SACNCommon.GetFirstBindAddress().IPAddress); + string username = "admin"; string password = "RoboSpot10"; string cam_ip = ""; @@ -25,6 +32,10 @@ namespace robospot_camera_finder int max_zoom_pulse = 9999; int min_zoom_pulse = 10; + byte[] dmx_universe = new byte[512]; + + Xbox360Controller controller; + public StreamViewer(string name, string ip) { InitializeComponent(); @@ -35,12 +46,18 @@ namespace robospot_camera_finder timerUpdateZoom.Start(); updateZoomSlider(); + timerDMX.Start(); + videoView.MediaPlayer = _mp; var media = new Media(_libVLC, new Uri("rtsp://" + ip + "/profile2/media.smp")); media.AddOption(":network-caching=25"); _mp.Play(media); media.Dispose(); this.Text = name; + + controller = new Xbox360Controller(); + controller.update(); + cbEnableXboxCtrl.Enabled = controller.connected; } private void updateZoomSlider() @@ -106,5 +123,114 @@ namespace robospot_camera_finder tbZoom.Value = min_zoom_pulse; sendZoomValue(tbZoom.Value.ToString()); } + + + private void timerDMX_Tick(object sender, EventArgs e) + { + controller.update(); + + if (!controller.connected) + { + cbEnableXboxCtrl.Checked = false; + cbEnableXboxCtrl.Enabled = false; + } + else + { + cbEnableXboxCtrl.Enabled = true; + } + + if (cbEnableXboxCtrl.Checked) + { + Point ls = controller.leftThumb; + Point rs = controller.rightThumb; + + bool fast_pt = controller.buttons.LeftStick; + + if ((tbPan.Value + ls.X) < 0 ) + { + tbPan.Value = 0; + } else if ((tbPan.Value + ls.X) > 65535) + { + tbPan.Value = 65535; + } else + { + if (fast_pt) + { + tbPan.Value += (ls.X) * 5; + } else + { + tbPan.Value += ls.X; + } + } + + if ((tbTilt.Value + ls.Y) < 0) + { + tbTilt.Value = 0; + } + else if ((tbTilt.Value + ls.Y) > 65535) + { + tbTilt.Value = 65535; + } + else + { + if (fast_pt) + { + tbTilt.Value += (ls.Y) * 5; + } + else + { + tbTilt.Value += ls.Y; + } + } + + if ((tbZoom.Value + rs.Y) < min_zoom_pulse) + { + tbZoom.Value = min_zoom_pulse; + } + else if ((tbZoom.Value + rs.Y) > max_zoom_pulse) + { + tbZoom.Value = max_zoom_pulse; + } + else + { + tbZoom.Value += (rs.Y) * 5; + } + sendZoomValue(tbZoom.Value.ToString()); + + + if (controller.buttons.LB) + { + tbZoom.Value = min_zoom_pulse; + sendZoomValue(tbZoom.Value.ToString()); + } + if (controller.buttons.RB) + { + tbZoom.Value = max_zoom_pulse; + sendZoomValue(tbZoom.Value.ToString()); + } + } + + byte[] pan = BitConverter.GetBytes(tbPan.Value); + byte[] tilt = BitConverter.GetBytes(tbTilt.Value); + int dmx_addr = int.Parse(numDMXAddr.Value.ToString()); + + dmx_universe[dmx_addr - 1] = pan[1]; + dmx_universe[dmx_addr] = pan[0]; + dmx_universe[dmx_addr + 1] = tilt[1]; + dmx_universe[dmx_addr + 2] = tilt[0]; + + sendClient.SendMulticast(Convert.ToUInt16(numUniv.Value.ToString()), dmx_universe); + } + + private void numDMXAddr_ValueChanged(object sender, EventArgs e) + { + tbPan.Value = 128; + tbTilt.Value = 128; + + for (int i = 0; i < dmx_universe.Length; i++) + { + dmx_universe[i] = 0; + } + } } } diff --git a/StreamViewer.resx b/StreamViewer.resx index 156a45f..6e41f1c 100644 --- a/StreamViewer.resx +++ b/StreamViewer.resx @@ -60,6 +60,9 @@ 17, 17 + + 169, 17 + diff --git a/Xbox360Controller.cs b/Xbox360Controller.cs new file mode 100644 index 0000000..732a49d --- /dev/null +++ b/Xbox360Controller.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; + +using SharpDX.XInput; + + +// A class to interface with an xbox 360 controller +namespace XboxControllerTest { + class Xbox360Controller { + public struct Buttons { + public bool A; + public bool B; + public bool X; + public bool Y; + public bool LB; + public bool RB; + public bool LeftStick; + public bool RightStick; + public bool Back; + public bool Start; + public bool DLeft; + public bool DUp; + public bool DRight; + public bool DDown; + } + + // Public variables + public Buttons buttons; + public Point leftThumb = new Point(0, 0); + public Point rightThumb = new Point(0, 0); + public bool connected = false; + public int deadband = 2500; + public float leftTrigger = 0; + public float rightTrigger = 0; + public int leftVibration = 0; + public int rightVibration = 0; + public string batteryLevel = ""; + public string batteryType = ""; + public Color batteryColor; + + // private variables + private Controller controller; + private Gamepad gamepad; + private Vibration vibration; + private BatteryInformation batteryInfo; + + // Constructor + public Xbox360Controller() { + controller = new Controller(UserIndex.One); + } + + // Updates the public variables + public void update() { + + // Make sure controller is connected + try { + connected = controller.IsConnected; + } catch (Exception err) { return; } + if(connected == false) { return; } + + // Helper variables + gamepad = controller.GetState().Gamepad; + GamepadButtonFlags btns = controller.GetState().Gamepad.Buttons; + batteryInfo = controller.GetBatteryInformation(BatteryDeviceType.Gamepad); + + + // Thumbsticks + leftThumb.X = Convert.ToInt32((Math.Abs((float)gamepad.LeftThumbX) < deadband) ? 0 : (float)gamepad.LeftThumbX / short.MinValue * -100); + leftThumb.Y = Convert.ToInt32((Math.Abs((float)gamepad.LeftThumbY) < deadband) ? 0 : (float)gamepad.LeftThumbY / short.MaxValue * 100); + rightThumb.X = Convert.ToInt32((Math.Abs((float)gamepad.RightThumbX) < deadband) ? 0 : (float)gamepad.RightThumbX / short.MaxValue * 100); + rightThumb.Y = Convert.ToInt32((Math.Abs((float)gamepad.RightThumbY) < deadband) ? 0 : (float)gamepad.RightThumbY / short.MaxValue * 100); + + // Triggers + leftTrigger = gamepad.LeftTrigger; + rightTrigger = gamepad.RightTrigger; + + // A, B, X, Y + buttons.A = (btns & GamepadButtonFlags.A) != 0; + buttons.B = (btns & GamepadButtonFlags.B) != 0; + buttons.X = (btns & GamepadButtonFlags.X) != 0; + buttons.Y = (btns & GamepadButtonFlags.Y) != 0; + + // Left and Right bumpers + buttons.LB = (btns & GamepadButtonFlags.LeftShoulder) != 0; + buttons.RB = (btns & GamepadButtonFlags.RightShoulder) != 0; + + // Clicking left and right thumbsticks + buttons.LeftStick = (btns & GamepadButtonFlags.LeftThumb) != 0; + buttons.RightStick = (btns & GamepadButtonFlags.RightThumb) != 0; + + // Start & Back + buttons.Back = (btns & GamepadButtonFlags.Back) != 0; + buttons.Start = (btns & GamepadButtonFlags.Start) != 0; + + // D-Pad + buttons.DLeft = (btns & GamepadButtonFlags.DPadLeft) != 0; + buttons.DUp = (btns & GamepadButtonFlags.DPadUp) != 0; + buttons.DRight = (btns & GamepadButtonFlags.DPadRight) != 0; + buttons.DDown = (btns & GamepadButtonFlags.DPadDown) != 0; + + // Battery + batteryLevel = batteryInfo.BatteryLevel.ToString(); + batteryType = batteryInfo.BatteryType.ToString(); + + switch (batteryInfo.BatteryLevel) { + case BatteryLevel.Empty: + batteryColor = Color.DarkGray; + break; + case BatteryLevel.Low: + batteryColor = Color.Red; + break; + case BatteryLevel.Medium: + batteryColor = Color.Orange; + break; + case BatteryLevel.Full: + batteryColor = Color.Green; + break; + } + } + + // Sets the vibration strength + public void setVibration(int lv, int rv) { + if (!connected) { return; } + + vibration.LeftMotorSpeed = Convert.ToUInt16(lv * 655); + vibration.RightMotorSpeed = Convert.ToUInt16(rv * 655); + controller.SetVibration(vibration); + } + } +} diff --git a/robospot-camera-finder.csproj b/robospot-camera-finder.csproj index 75708d6..7575a91 100644 --- a/robospot-camera-finder.csproj +++ b/robospot-camera-finder.csproj @@ -10,9 +10,11 @@ + +