diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..940e78c --- /dev/null +++ b/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..de2eeb3 --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,12 @@ +using System.Configuration; +using System.Data; +using System.Windows; + +namespace WpfMaiTouchEmulator; +/// +/// Interaction logic for App.xaml +/// +public partial class App : Application +{ +} + diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..b0ec827 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/MaiTouchComConnector.cs b/MaiTouchComConnector.cs new file mode 100644 index 0000000..1045f46 --- /dev/null +++ b/MaiTouchComConnector.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace WpfMaiTouchEmulator; +internal class MaiTouchComConnector +{ + private static SerialPort? serialPort; + private bool isActiveMode; + private readonly MaiTouchSensorButtonStateManager _buttonState; + + public Action OnConnectStatusChange + { + get; + internal set; + } + public Action OnDataSent + { + get; + internal set; + } + public Action OnDataRecieved + { + get; + internal set; + } + + public MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState) + { + _buttonState = buttonState; + } + + public async Task startLoopAsync() + { + string virtualPort = "COM23"; // Adjust as needed + + + try + { + + // Use setupc.exe to create a virtual COM port pair + //StartProcessWithAdminRights("C:\\Program Files (x86)\\com0com\\setupc.exe", $"PortName=COM3 PortName=COM23"); + + serialPort = new SerialPort(virtualPort, 9600, Parity.None, 8, StopBits.One); + serialPort.DataReceived += SerialPort_DataReceived; + serialPort.Open(); + Console.WriteLine("Serial port opened successfully."); + OnConnectStatusChange("Connected"); + + + + // Simulate receiving a STAT packet + // Keep the program running to simulate active mode + while (true) + { + if (isActiveMode) + { + SendTouchscreenState(); + await Task.Delay(1); + } + else + { + await Task.Delay(100); + } + } + + } + catch (Exception ex) + { + Console.WriteLine($"Error opening serial port: {ex.Message}"); + Application.Current.Dispatcher.Invoke(() => + { + MessageBox.Show(ex.Message, "Error connecting to COM port", MessageBoxButton.OK, MessageBoxImage.Error); + }); + + } + finally + { + OnConnectStatusChange("Not Connected"); + // Close the serial port when done + if (serialPort.IsOpen) + { + serialPort.Close(); + } + + // Use setupc.exe to remove the virtual COM port pair with administrator privileges + //StartProcessWithAdminRights("C:\\Program Files (x86)\\com0com\\setupc.exe", $"remove 0"); + } + } + + void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + string recievedData = serialPort.ReadExisting(); + var commands = recievedData.Split(new[] { '}' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string command in commands) + { + string cleanedCommand = command.TrimStart('{'); + // Implement your logic to process the received data here + Console.WriteLine($"Received data: {cleanedCommand}"); + OnDataRecieved(cleanedCommand); + + + // Check if the received packet is a STAT packet + if (cleanedCommand == "STAT") + { + // Simulate entering active mode + isActiveMode = true; + Console.WriteLine("Entered Active Mode"); + } + else if (cleanedCommand == "RSET") + { + + } + else if (cleanedCommand == "HALT") + { + isActiveMode = false; + } + else if (cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k') + { + char leftOrRight = cleanedCommand[0]; + char sensor = cleanedCommand[1]; + char ratio = cleanedCommand[3]; + + // Create the new string in the specified format + string newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})"; + serialPort.Write(newString); + OnDataSent(newString); + } + else + { + Console.WriteLine(cleanedCommand); + } + } + } + + void SendTouchscreenState() + { + var currentState = _buttonState.GetCurrentState(); + serialPort?.Write(currentState, 0, currentState.Length); + //Console.WriteLine($"Sent Touchscreen State: {report}");*/ + } +} diff --git a/MaiTouchSensorButtonStateManager.cs b/MaiTouchSensorButtonStateManager.cs new file mode 100644 index 0000000..66e427e --- /dev/null +++ b/MaiTouchSensorButtonStateManager.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace WpfMaiTouchEmulator; + +enum TouchValue: long +{ + A1 = 1 << 0, // 2^0 + A2 = 1 << 1, // 2^1 + A3 = 1 << 2, // 2^2 + A4 = 1 << 3, // 2^3 + A5 = 1 << 4, // 2^4 + A6 = 1 << 5, // 2^5 + A7 = 1 << 6, // 2^6 + A8 = 1 << 7, // 2^7 + B1 = 1 << 8, // 2^8 + B2 = 1 << 9, // 2^9 + B3 = 1 << 10, // 2^10 + B4 = 1 << 11, // 2^11 + B5 = 1 << 12, // 2^12 + B6 = 1 << 13, // 2^13 + B7 = 1 << 14, // 2^14 + B8 = 1 << 15, // 2^15 + C1 = 1 << 16, // 2^16 + C2 = 1 << 17, // 2^17 + D1 = 1 << 18, // 2^18 + D2 = 1 << 19, // 2^19 + D3 = 1 << 20, // 2^20 + D4 = 1 << 21, // 2^21 + D5 = 1 << 22, // 2^22 + D6 = 1 << 23, // 2^23 + D7 = 1 << 24, // 2^24 + D8 = 1 << 25, // 2^25 + E1 = 1 << 26, // 2^26 + E2 = 1 << 27, // 2^27 + E3 = 1 << 28, // 2^28 + E4 = 1 << 29, // 2^29 + E5 = 1 << 30, // 2^30 + E6 = 1L << 31, // Note: Use 1L for long literals, as this and subsequent values exceed Int32.MaxValue + E7 = 1L << 32, + E8 = 1L << 33, +} + +internal class MaiTouchSensorButtonStateManager +{ + static long buttonState = 0L; + private readonly Label buttonStateValue; + + public MaiTouchSensorButtonStateManager(Label buttonStateValue) + { + this.buttonStateValue = buttonStateValue; + SetupUpdateLoop(); + + } + + private async void SetupUpdateLoop() + { + while (true) + { + Application.Current.Dispatcher.Invoke(() => + { + buttonStateValue.Content = buttonState.ToString(); + }); + await Task.Delay(1); + } + } + + public void Reset() + { + buttonState = 0L; + } + + public void PressButton(TouchValue button) + { + buttonState |= ((long)button); + } + + public void ReleaseButton(TouchValue button) + { + buttonState &= ~((long)button); + } + + public byte[] GetCurrentState() + { + Application.Current.Dispatcher.Invoke(() => + { + buttonStateValue.Content = buttonState.ToString(); + }); + + + return + [ + 0x28, + (byte)(buttonState & 0b11111), + (byte)(buttonState >> 5 & 0b11111), + (byte)(buttonState >> 10 & 0b11111), + (byte)(buttonState >> 15 & 0b11111), + (byte)(buttonState >> 20 & 0b11111), + (byte)(buttonState >> 25 & 0b11111), + (byte)(buttonState >> 30 & 0b11111), + 0x29 + ]; + } +} diff --git a/MainWindow.xaml b/MainWindow.xaml new file mode 100644 index 0000000..bdb101f --- /dev/null +++ b/MainWindow.xaml @@ -0,0 +1,34 @@ + + +