using SFML.System; using SFML.Window; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Firebird2D.Core { internal struct JoystickMapping { public uint joysticnumber; public uint buttonnumber; } public static class InputMapper { private static Dictionary KeyboardMapping = new Dictionary(); private static Dictionary JoystickButtonMapping = new Dictionary(); private static Dictionary MouseButtonMapping = new Dictionary(); private static List<(Keyboard.Key, Keyboard.Key)> Keyremaps = new List<(Keyboard.Key, Keyboard.Key)>(); private static List<(Mouse.Button, Mouse.Button)> MouseButtonremaps = new List<(Mouse.Button, Mouse.Button)>(); private static List<(uint, uint, uint)> JoystickButtonremaps = new List<(uint, uint, uint)>(); public delegate void KeyboardHandler(Keyboard.Key key); public delegate void MouseHandler(Mouse.Button button); public delegate void JoystickButtonHandler(uint JoystickId, uint ButtonNumber); public delegate void JoystickAxisHandler(uint JoystickId, float x, float y, float z, float r, float u, float v); public delegate void JoystickHatHandler(uint JoystickId, float PovX, float PovY); public delegate void MouseCursorPositionhandler(Vector2i mousePosition); public static event JoystickAxisHandler? JoystickAxisEvent; public static event JoystickHatHandler? JoystickHatEvent; public static event MouseCursorPositionhandler? MouseCursorPositionEvent; public static void Map(KeyboardHandler Method, Keyboard.Key key) { KeyboardMapping.Add(key, Method); } public static void Map(MouseHandler Method, Mouse.Button button) { MouseButtonMapping.Add(button, Method); } public static void Map(JoystickButtonHandler Method, uint joysticknumber, uint buttonnumber) { JoystickMapping mapping = new JoystickMapping { joysticnumber = joysticknumber, buttonnumber = buttonnumber }; JoystickButtonMapping.Add(mapping, Method); } public static void Remap(Keyboard.Key key1, Keyboard.Key key2) { if (KeyboardMapping.ContainsKey(key2)) throw new ArgumentException("Key2 already exists"); if (!KeyboardMapping.ContainsKey(key1)) throw new ArgumentException("Key1 not existing"); var keyboardHandler = KeyboardMapping[key1]; KeyboardMapping.Remove(key1); KeyboardMapping.Add(key2, keyboardHandler); if (!Keyremaps.Contains((key1, key2))) Keyremaps.Add((key1, key2)); } public static void Remap(Mouse.Button button1, Mouse.Button button2) { if (MouseButtonMapping.ContainsKey(button2)) throw new ArgumentException("Button2 already exists"); if (!MouseButtonMapping.ContainsKey(button1)) throw new ArgumentException("Button1 not existing"); var mouseHandler = MouseButtonMapping[button1]; MouseButtonMapping.Remove(button1); MouseButtonMapping.Add(button2, mouseHandler); if (!MouseButtonremaps.Contains((button1, button2))) MouseButtonremaps.Add((button1, button2)); } public static void Remap(uint joysticknumber, uint buttonnumber1, uint buttonnumber2) { JoystickMapping mappOld = new JoystickMapping { joysticnumber = joysticknumber, buttonnumber = buttonnumber1 }; JoystickMapping mappNew = new JoystickMapping { joysticnumber = joysticknumber, buttonnumber = buttonnumber2 }; if (JoystickButtonMapping.ContainsKey(mappNew)) throw new ArgumentException("Button2 already exists"); if (!JoystickButtonMapping.ContainsKey(mappOld)) throw new ArgumentException("Button1 not existing"); var joystickHandler = JoystickButtonMapping[mappOld]; JoystickButtonMapping.Remove(mappOld); JoystickButtonMapping.Add(mappNew, joystickHandler); if (!JoystickButtonremaps.Contains((joysticknumber, buttonnumber1, buttonnumber2))) JoystickButtonremaps.Add((joysticknumber, buttonnumber1, buttonnumber2)); } public static void ClearRemappingLog() { JoystickButtonremaps.Clear(); MouseButtonremaps.Clear(); Keyremaps.Clear(); } public static async Task UpdateOrSafeRemapsAsync(string filepath) { if (string.IsNullOrEmpty(filepath)) throw new ArgumentException(nameof(filepath)); if (File.Exists(filepath)) { await UpdateRemapsAsync(filepath); } else { string directoryName = Path.GetDirectoryName(filepath); if (directoryName != null) Directory.CreateDirectory(directoryName); await SafeRemapsAsync(new FileStream(filepath, FileMode.Create)); } } private static async Task SafeRemapsAsync(FileStream fileStream) { using (StreamWriter writer = new StreamWriter(fileStream)) { writer.WriteLine(""); foreach (var keyRemap in Keyremaps) { writer.WriteLine($"{keyRemap.Item1};{keyRemap.Item2}"); } writer.WriteLine(""); writer.WriteLine(""); foreach (var mouseRemap in MouseButtonremaps) { writer.WriteLine($"{mouseRemap.Item1};{mouseRemap.Item2}"); } writer.WriteLine(""); writer.WriteLine(""); foreach (var joyRemap in JoystickButtonremaps) { writer.WriteLine($"{joyRemap.Item1};{joyRemap.Item2};{joyRemap.Item3}"); } writer.WriteLine(""); writer.Flush(); } await fileStream.FlushAsync(); fileStream.Close(); } private static async Task UpdateRemapsAsync(string filepath) { string Filecontent = null; using (StreamReader reader = new StreamReader(filepath)) { Filecontent = await reader.ReadToEndAsync(); } string[] keyRemaps = ExtractMappings(Filecontent, "", ""); string[] mouseButtonRemaps = ExtractMappings(Filecontent, "", ""); string[] joyButtonRemaps = ExtractMappings(Filecontent, "", ""); Keyremaps.InsertRange(0, keyRemaps.Select(k => ParseKeyMapping(k)).ToArray()); MouseButtonremaps.InsertRange(0, mouseButtonRemaps.Select(m => ParseMouseMapping(m)).ToArray()); JoystickButtonremaps.InsertRange(0, joyButtonRemaps.Select(j => ParseJoystickMapping(j)).ToArray()); using (var fileStream = new FileStream(filepath, FileMode.Create)) { await SafeRemapsAsync(fileStream); } } private static string[] ExtractMappings(string content, string startTag, string endTag) { int start = content.IndexOf(startTag) + startTag.Length; int end = content.IndexOf(endTag); if (start < 0 || end < 0) return new string[0]; // Falls das Tag nicht gefunden wurde string mappings = content.Substring(start, end - start); return mappings.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); } private static (Keyboard.Key, Keyboard.Key) ParseKeyMapping(string keyMapping) { var keys = keyMapping.Split(";"); return (Enum.Parse(keys[0]), Enum.Parse(keys[1])); } private static (Mouse.Button, Mouse.Button) ParseMouseMapping(string mouseMapping) { var buttons = mouseMapping.Split(";"); return (Enum.Parse(buttons[0]), Enum.Parse(buttons[1])); } private static (uint, uint, uint) ParseJoystickMapping(string joystickMapping) { var joyButtons = joystickMapping.Split(";"); return (uint.Parse(joyButtons[0]), uint.Parse(joyButtons[1]), uint.Parse(joyButtons[2])); } public static void revertLastKeyRemap() { if (Keyremaps.Any()) { var lastKeyRemap = Keyremaps.Last(); Keyremaps.Remove(lastKeyRemap); KeyboardMapping[lastKeyRemap.Item2] = KeyboardMapping[lastKeyRemap.Item1]; } } public static void revertLastMouseButtonRemap() { if (MouseButtonremaps.Any()) { var lastMouseButtonRemap = MouseButtonremaps.Last(); MouseButtonremaps.Remove(lastMouseButtonRemap); MouseButtonMapping[lastMouseButtonRemap.Item2] = MouseButtonMapping[lastMouseButtonRemap.Item1]; } } public static void revertLastJoystickButtonRemap() { if (JoystickButtonremaps.Any()) { var lastJoystickButtonRemap = JoystickButtonremaps.Last(); JoystickButtonremaps.Remove(lastJoystickButtonRemap); var mappOld = new JoystickMapping { joysticnumber = lastJoystickButtonRemap.Item1, buttonnumber = lastJoystickButtonRemap.Item2 }; var mappNew = new JoystickMapping { joysticnumber = lastJoystickButtonRemap.Item1, buttonnumber = lastJoystickButtonRemap.Item3 }; JoystickButtonMapping[mappNew] = JoystickButtonMapping[mappOld]; JoystickButtonMapping.Remove(mappOld); } } public static void HandleKeyboardInput(Keyboard.Key key) { if (KeyboardMapping.ContainsKey(key)) { KeyboardMapping[key](key); // Event auslösen } } public static void HandleMouseInput(Mouse.Button button) { if (MouseButtonMapping.ContainsKey(button)) { MouseButtonMapping[button](button); } } public static void HandleJoystickButtonInput(uint joystickId, uint buttonNumber) { var joymap = new JoystickMapping { buttonnumber = buttonNumber, joysticnumber = joystickId }; if (JoystickButtonMapping.ContainsKey(joymap)) { JoystickButtonMapping[joymap](joystickId, buttonNumber); } } public static void HandleMouseMovement(Vector2i mouseposition) { MouseCursorPositionEvent?.Invoke(mouseposition); } public static void HandleJoytickMove(uint JoystickId, float x, float y, float z, float r, float u, float v, float PovX, float PovY) { JoystickAxisEvent?.Invoke(JoystickId, x, y, z, r, u, v); JoystickHatEvent?.Invoke(JoystickId, PovX, PovY); } } }