using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using System.Threading; using Microsoft.Win32; using System.IO; using Microsoft.DirectX.DirectInput; using System.Runtime.InteropServices; using System.Collections; namespace Fusion_Control_Centre_UberMDX { public partial class MainMDX : Form { #region Constructor and Initialization of Fusion Control Centre Uber MDX Edition... public MainMDX(bool showSplashScreen, bool useBasicGraphics, bool input_useThreading) { input_useThreading = useThreading; InitializeComponent(); DEBUG_InitializeTesting(); UpdateRegistry(); if (showSplashScreen) { SetupSplashScreen(); } MDX_use_GDI_not_DX = useBasicGraphics; SetupMDX_GraphicsArea(); SetupMDX_LogicSection(); SetupSpeech(); RemoteControlClass.InitializeRemoteControl(this); COM_Initialize(); SetupTimersAndThreads(); bool USB_active = true; try { if (!USB_CommunicationClass.Setup_USB_CommunicationClass()) { USB_active = false; } } catch (DllNotFoundException e) { USB_active = false; } Setup_BrainRelationship(); this.MouseDown += new MouseEventHandler(MDX_Form_MouseClick_DOWN); this.MouseUp += new MouseEventHandler(MDX_Form_MouseClick_UP); this.FormClosing += new FormClosingEventHandler(MainMDX_FormClosing); this.Paint += new PaintEventHandler(MDX_Render); this.Resize += new EventHandler(MainMDX_Resize); if (_SCF != null) { _SCF.Die(); } this.StartPosition = FormStartPosition.CenterScreen; int _widthScreenResolution = Screen.PrimaryScreen.Bounds.Width; int _heightScreenResolution = Screen.PrimaryScreen.Bounds.Height; this.Location = new Point((int)(_widthScreenResolution / 2) - (int)(this.Width / 2), (int)(_heightScreenResolution / 2) - (int)(this.Height / 2)); SetupHiddenOperations(); InitializeTimersAndThreads(); DEBUG_ShowAllDebuggingWindows(); } private void DEBUG_InitializeTesting() { //Nothing at the moment } private void DEBUG_ShowAllDebuggingWindows() { foreach (Form _f in DEBUG_FormsToShow) { if (!_f.IsDisposed) { _f.Show(); } } } private void DEBUG_HideAllDebuggingWindows() { foreach (Form _f in DEBUG_FormsToShow) { _f.Hide(); } } private void UpdateRegistry() { RegistryKey registryAppLocation = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Fusion Control Centre\MDX"); string[] _currentInstallPaths = registryAppLocation.GetValueNames(); //bool _isOthers = false; bool _thisIsAlreadyAdded = false; int max_level = 1; string _valueName = "INSTALL_PATH"; if (_currentInstallPaths.Length > 0) { foreach (string _installPathTest in _currentInstallPaths) { if (_installPathTest.StartsWith("INSTALL_PATH_")) { int _tryParseINT = -1; if (int.TryParse(_installPathTest.Substring("INSTALL_PATH_".Length), out _tryParseINT)) { object _testPath = registryAppLocation.GetValue(_installPathTest); if (_testPath.ToString().ToLower() == Application.ExecutablePath.ToLower()) { max_level = _tryParseINT; _thisIsAlreadyAdded = true; } else { string _execPath = registryAppLocation.GetValue(_installPathTest).ToString(); if (!File.Exists(_execPath)) { registryAppLocation.DeleteValue(_installPathTest); } if (!_thisIsAlreadyAdded) { if (_tryParseINT >= max_level) { max_level = _tryParseINT + 1; } } } } } } } registryAppLocation.SetValue(_valueName + "_" + max_level.ToString(), (string)Application.ExecutablePath); return; } public void SetupMDX_GraphicsArea() { if (!SetUpMDXDevice()) { MDX_use_GDI_not_DX = true; } if (!ReadInConfigurationFile()) { DisplayMessageBox("Unknown Error in Configuration File", true); Application.Exit(); return; } Sort_AllGUI_by_Z_OrderDepth(); } public void SetupMDX_LogicSection() { PerformLogicCommands("all"); } #endregion #region Configure Hidden Operations public void SetupHiddenOperations() { if (!RunProgramInSystemTray) { this.Show(); } else { this.Hide(); } } #endregion #region Setup Splash Screen public void SetupSplashScreen() { _SCF = new SplashScreenForm(this); _SCF.Show(); _SCF.TopMost = true; } #endregion #region Verbose Debug Logging public static void MDX_DebugLogging(string SendThisStringForLogging) { if (Debug_VerboseLoggingEvent != null) { Debug_VerboseLoggingEvent(SendThisStringForLogging); } } #endregion protected override void OnPaintBackground(PaintEventArgs pevent) { } #region Setup MDX Device public bool SetUpMDXDevice() { MDX_DebugLogging("Setting Up Display"); this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); if (!MDX_use_GDI_not_DX) { try { MDX_PresentParameters = new PresentParameters(); MDX_PresentParameters.Windowed = true; MDX_PresentParameters.SwapEffect = SwapEffect.Discard; MDX_PresentParameters.BackBufferWidth = this.ClientSize.Width; MDX_PresentParameters.BackBufferHeight = this.ClientSize.Height; MDX_PresentParameters.PresentationInterval = PresentInterval.Immediate; try { MDX_Device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, Microsoft.DirectX.Direct3D.CreateFlags.HardwareVertexProcessing, MDX_PresentParameters); MDX_DebugLogging("Hardware Processing Enabled"); } catch (Exception) { MDX_Device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, Microsoft.DirectX.Direct3D.CreateFlags.SoftwareVertexProcessing, MDX_PresentParameters); MDX_DebugLogging("Software Processing Enabled"); } //Microsoft.DirectX.DirectInput.Device _d = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse); //_d.SetCooperativeLevel(this, CooperativeLevelFlags.Foreground | CooperativeLevelFlags.NonExclusive); MDX_Sprite_BackgroundImages = new Sprite(MDX_Device); MDX_Sprite_NormalLayer = new Sprite(MDX_Device); /* MDX_Mouse = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse); MDX_Mouse.SetCooperativeLevel(this, CooperativeLevelFlags.Foreground | CooperativeLevelFlags.NonExclusive); MDX_Mouse.SetDataFormat(DeviceDataFormat.Mouse); MDX_Mouse.Properties.AxisModeAbsolute = true; MDX_Mouse.Acquire(); */ return true; } catch (Exception) { MDX_use_GDI_not_DX = true; return false; } } else { MDX_use_GDI_not_DX = true; return false; } } #endregion #region MDX Paint Render private void MDX_Render(object sender, PaintEventArgs e) { if (MDX_Device == null || MDX_Sprite_BackgroundImages == null || MDX_Sprite_NormalLayer == null) { return; } UpdateDaGUI(); } #endregion #region Program Closing /* void MainMDX_ProgramClosing(object sender, FormClosingEventArgs e) { try { USB_CommunicationClass.THREAD_SAFETY_SENDOK = false; CloseAllOpenLogStreams(); USB_CommunicationClass.ShutOffAllOutputs(); USB_CommunicationClass.DisposeOfAllBrains(); } catch (Exception) { //Error Closing the Program MessageBox.Show("Error Closing the Program... You shouldn't be seeing this. :(", "UH OH", MessageBoxButtons.OK, MessageBoxIcon.Error); } } */ /* void MainMDX_FormClosed(object sender, FormClosedEventArgs e) { try { USB_CommunicationClass.THREAD_SAFETY_SENDOK = false; CloseAllOpenLogStreams(); USB_CommunicationClass.ShutOffAllOutputs(); USB_CommunicationClass.DisposeOfAllBrains(); uint successOfComRevoke = COM_Revoke(); } catch (Exception) { MessageBox.Show("Error Closing the Program... You shouldn't be seeing this. :(", "UH OH", MessageBoxButtons.OK, MessageBoxIcon.Error); } } */ void MainMDX_FormClosing(object sender, FormClosingEventArgs e) { try { USB_CommunicationClass.THREAD_SAFETY_SENDOK = false; if (useThreading) { THREAD_IO.Abort(); THREAD_Logic.Abort(); } USB_CommunicationClass.ShutOffAllOutputs(); USB_CommunicationClass.DisposeOfAllBrains(); CloseAllOpenLogStreams(); uint successOfComRevoke = COM_Revoke(); } catch (Exception ERRORCLOSINGFORM_e) { Console.WriteLine(ERRORCLOSINGFORM_e.ToString()); return; } } private delegate void DoCloseBrains(); private event DoCloseBrains CloseProgramEvent; #endregion #region Setup & Initialize Timers public void SetupTimersAndThreads() { if (useThreading) { THREAD_Logic = new Thread(THREAD_UPDATE_Logic); THREAD_IO = new Thread(THREAD_UPDATE_IO); //THREAD_GUI = new Thread(THREAD_UPDATE_GUI); //THREAD_INPUT = new Thread(THREAD_UPDATE_Input); //THREAD_OUTPUT = new Thread(THREAD_UPDATE_Output); THREAD_Logic.Name = "Logic Thread"; THREAD_IO.Name = "IO Thread"; //THREAD_GUI.Name = "GUI Thread"; //THREAD_INPUT.Name = "USB Input Thread"; //THREAD_OUTPUT.Name = "USB Output Thread"; THREAD_Logic.IsBackground = true; THREAD_IO.IsBackground = true; //THREAD_GUI.IsBackground = true; //THREAD_INPUT.IsBackground = true; //THREAD_OUTPUT.IsBackground = true; GUI_Timer.Tick += new EventHandler(GUI_Timer_Tick); GUI_Timer.Enabled = false; GUI_Timer.Interval = 50; } else { MDX_DebugLogging("Initializing Timers"); LogicTimer.Tick += new EventHandler(LogicTimer_Tick); LogicTimer.Enabled = false; LogicTimer.Interval = THREAD_LOGIC_SLEEP_INTERVAL; GUI_Timer.Tick += new EventHandler(GUI_Timer_Tick); GUI_Timer.Enabled = false; GUI_Timer.Interval = 50; IO_Timer.Tick += new EventHandler(IO_Timer_Tick); IO_Timer.Enabled = false; IO_Timer.Interval = THREAD_IO_SLEEP_INTERVAL; /* OutputTimer.Tick += new EventHandler(OutputTimer_Tick); OutputTimer.Enabled = false; OutputTimer.Interval = 75; InputTimer.Tick += new EventHandler(InputTimer_Tick); InputTimer.Enabled = false; InputTimer.Interval = 45; */ } } public void InitializeTimersAndThreads() { if (useThreading) { //THREAD_GUI.Start(); GUI_Timer.Enabled = true; THREAD_Logic.Start(); THREAD_IO.Start(); //THREAD_INPUT.Start(); //THREAD_OUTPUT.Start(); } else { LogicTimer.Enabled = true; IO_Timer.Enabled = true; GUI_Timer.Enabled = true; //OutputTimer.Enabled = true; //InputTimer.Enabled = true; } } #endregion #region Timer Events private void LogicTimer_Tick(object sender, EventArgs e) { UPDATE_Logic(); } private void IO_Timer_Tick(object sender, EventArgs e) { UPDATE_IO(); } /* private void OutputTimer_Tick(object sender, EventArgs e) { UPDATE_Output(); } private void InputTimer_Tick(object sender, EventArgs e) { UPDATE_Input(); } */ private void GUI_Timer_Tick(object sender, EventArgs e) { UPDATE_GUI(); } #endregion #region Thread Events public void THREAD_UPDATE_Logic() { while (true) { DateTime _beginning = DateTime.Now; UPDATE_Logic(); TimeSpan _totalTime = DateTime.Now.Subtract(_beginning); if (_totalTime.TotalMilliseconds > THREAD_LOGIC_SLEEP_INTERVAL) { } Thread.Sleep(THREAD_LOGIC_SLEEP_INTERVAL); } } /* public void THREAD_UPDATE_GUI() { while (true) { UPDATE_GUI(); Thread.Sleep(GUI_Timer.Interval); } } */ public void THREAD_UPDATE_IO() { USB_CommunicationClass.USB_CommunicationClass_LOOP(); } /* public void THREAD_UPDATE_Output() { while (true) { UPDATE_Output(); Thread.Sleep(OutputTimer.Interval); } } public void THREAD_UPDATE_Input() { while (true) { UPDATE_Input(); Thread.Sleep(InputTimer.Interval); } } */ #endregion #region Setup Brain Relationships public void Setup_BrainRelationship() { foreach (VirtualBrainClass VB in DEBUG_VirtualBrainList) { foreach (BrainID _brain in AllBrains) { if (VB._human.ToLower() == _brain.humanName.ToLower()) { VB.Initialize(_brain.version, this); break; } } } foreach (BrainID _FB in AllBrains) { foreach (DigitalOutputChannel _doc in AllDigitalOutputs) { if (_doc.BrainID.ToLower() == _FB.humanName.ToLower()) { if (_doc.Port >= 0 && _doc.Port < _FB.DigitalOutputIndexArray_EX.Length) { _FB.DigitalOutputIndexArray_EX[_doc.Port] = AllDigitalOutputs.IndexOf(_doc); continue; } } } foreach (AnalogueInputChannel _aic in AllAnalogueInputs) { if (_aic.BrainID.ToLower() == _FB.humanName.ToLower()) { if (_aic.Port >= 0 && _aic.Port < _FB.AnalogueInputIndexArray_EX.Length) { _FB.AnalogueInputIndexArray_EX[_aic.Port] = AllAnalogueInputs.IndexOf(_aic); if (_aic.id.ToLower() == _FB.Accurate_AnalogueScalingInput_Index_ReferenceID) { _FB.Accurate_AnalogueScalingInput_Index = _FB.AnalogueInputIndexArray_EX[_aic.Port]; } } } } foreach (DigitalInputChannel _dic in AllDigitalInputs) { if (_dic.BrainID.ToLower() == _FB.humanName.ToLower()) { if (_dic.Port >= 0 && _dic.Port < _FB.DigitalInputIndexArray_EX.Length) { _FB.DigitalInputIndexArray_EX[_dic.Port] = AllDigitalInputs.IndexOf(_dic); } } } } } #endregion #region Update Functions public void UPDATE_Logic() { PerformLogicCommands("logic"); UpdateLogs("logic"); COM_RefreshAllValues(); COM_PrintAllValues(); } public void UPDATE_GUI() { UpdateDaGUI(); PerformLogicCommands("gui"); UpdateLogs("gui"); } public void UPDATE_IO() { PerformLogicCommands("io"); USB_CommunicationClass.DoUSB(); UpdateLogs("io"); } /* public void UPDATE_Output() { PerformLogicCommands("output"); USB_OutputSteps(); UpdateLogs("output"); } public void UPDATE_Input() { USB_InputSteps(); PerformLogicCommands("input"); UpdateLogs("input"); } */ #endregion #region Degrees to Radians public double DegreesToRadians(double inDegrees) { return (double)((inDegrees * Math.PI) / (180.0f)); } #endregion #region Error Message Box /// /// When an error occurs, make a message box for the user /// /// The main body text for the error message public void DisplayMessageBox(string error) { if (_SCF != null) { _SCF.Hide(); } if (MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK) { if (_SCF != null) { _SCF.Show(); } } } #endregion #region Fatal Error Message Box /// /// Fatal Error, so display the error and then close the program /// /// /// Should always be true when using this function public void DisplayMessageBox(string error, bool isFatal) { if (_SCF != null && isFatal) { _SCF.Close(); } else if (_SCF != null && !isFatal) { _SCF.Hide(); } MessageBox.Show(error, "FATAL Error", MessageBoxButtons.OK, MessageBoxIcon.Error); if (isFatal) { //Environment.Exit(1); Application.Exit(); return; } else if (_SCF != null && !isFatal) { _SCF.Show(); } } #endregion #region Double Click System Tray Icon private void SystemTrayNotificationIcon_DoubleClick(object sender, EventArgs e) { MDX_ProgramForms_Show(); this.WindowState = FormWindowState.Normal; } #endregion #region Main Form Resized void MainMDX_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) { MDX_ProgramForms_Hide(); } } #endregion #region Minimize To Tray public void MDX_ProgramForms_Hide() { if (MinimizeToSystemTray) { this.Hide(); DEBUG_HideAllDebuggingWindows(); } } public void MDX_ProgramForms_Show() { this.Show(); DEBUG_ShowAllDebuggingWindows(); } #endregion #region System Tray Menu Clicked private void SystemTrayContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem == SYSTRAY_CM_Restore) { MDX_ProgramForms_Show(); this.WindowState = FormWindowState.Normal; } else if (e.ClickedItem == SYSTRAY_CM_Close) { this.Close(); } } #endregion } }