From 42a19a4008a43b6c7a90beff60a3a26746324edc Mon Sep 17 00:00:00 2001 From: gered Date: Thu, 15 Aug 2013 18:33:07 -0400 Subject: [PATCH] add SDL input device class implementations --- .../Blarg.GameFramework.SDL2.csproj | 5 + Blarg.GameFramework.SDL2/Input/SDLKeyboard.cs | 112 ++++++++++++++ Blarg.GameFramework.SDL2/Input/SDLMouse.cs | 141 ++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 Blarg.GameFramework.SDL2/Input/SDLKeyboard.cs create mode 100644 Blarg.GameFramework.SDL2/Input/SDLMouse.cs diff --git a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj index 10be6e0..5996778 100644 --- a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj +++ b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj @@ -44,6 +44,8 @@ + + @@ -52,4 +54,7 @@ Blarg.GameFramework + + + \ No newline at end of file diff --git a/Blarg.GameFramework.SDL2/Input/SDLKeyboard.cs b/Blarg.GameFramework.SDL2/Input/SDLKeyboard.cs new file mode 100644 index 0000000..f74e775 --- /dev/null +++ b/Blarg.GameFramework.SDL2/Input/SDLKeyboard.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using SDL2; + +namespace Blarg.GameFramework.Input +{ + public class SDLKeyboard : IKeyboard + { + bool[] _keys; + bool[] _lockedKeys; + IList _listeners; + + public SDLKeyboard() + { + _keys = new bool[(int)Key.LastKey]; + _lockedKeys = new bool[(int)Key.LastKey]; + _listeners = new List(); + } + + public bool OnKeyEvent(SDL.SDL_KeyboardEvent e) + { + int keyCode = (int)e.keysym.sym; + + if (e.state == SDL.SDL_PRESSED) + { + _keys[keyCode] = !(_lockedKeys[keyCode]); // pressed only if not locked + + // always report keydown events + // NOTE: we're ignoring the "locked key" state because listeners + // don't have support for it (yet) + for (int i = 0; i < _listeners.Count; ++i) + { + if (_listeners[i].OnKeyDown((Key)keyCode)) + break; + } + } + else + { + // if the key is just being released this tick, then trigger an event in all listeners + if (_keys[keyCode]) + { + for (int i = 0; i < _listeners.Count; ++i) + { + if (_listeners[i].OnKeyUp((Key)keyCode)) + break; + } + } + + _keys[keyCode] = false; + _lockedKeys[keyCode] = false; + } + + return true; + } + + public bool IsDown(Key key) + { + return _keys[(int)key] && !_lockedKeys[(int)key]; + } + + public bool IsPressed(Key key) + { + if (_keys[(int)key] && !_lockedKeys[(int)key]) + { + _lockedKeys[(int)key] = true; + return true; + } + else + return false; + } + + public void Lock(Key key) + { + _lockedKeys[(int)key] = true; + } + + public void OnPostUpdate(float delta) + { + } + + public void Reset() + { + for (int i = 0; i < _keys.Length; ++i) + _keys[i] = false; + for (int i = 0; i < _lockedKeys.Length; ++i) + _lockedKeys[i] = false; + } + + public void RegisterListener(IKeyboardListener listener) + { + if (_listeners.Contains(listener)) + throw new InvalidOperationException("Duplicate listener registration."); + + _listeners.Add(listener); + } + + public void UnregisterListener(IKeyboardListener listener) + { + int index = _listeners.IndexOf(listener); + if (index == -1) + throw new InvalidOperationException("Listener not registered."); + + _listeners.RemoveAt(index); + } + + public bool HasPhysicalKeysForGameControls + { + get { return true; } + } + } +} + diff --git a/Blarg.GameFramework.SDL2/Input/SDLMouse.cs b/Blarg.GameFramework.SDL2/Input/SDLMouse.cs new file mode 100644 index 0000000..4f0c227 --- /dev/null +++ b/Blarg.GameFramework.SDL2/Input/SDLMouse.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using SDL2; + +namespace Blarg.GameFramework.Input +{ + public class SDLMouse : IMouse + { + bool[] _buttons; + bool[] _lockedButtons; + IList _listeners; + + public SDLMouse() + { + _buttons = new bool[(int)MouseButton.LastButton]; + _lockedButtons = new bool[(int)MouseButton.LastButton]; + _listeners = new List(); + } + + public bool OnButtonEvent(SDL.SDL_MouseButtonEvent e) + { + int button = (int)e.button - 1; + + if (e.state == SDL.SDL_PRESSED) + { + // Pressed only if not locked + _buttons[button] = !(_lockedButtons[button]); + + // always report button down events + // NOTE: we're ignoring the "locked button" state because listeners + // don't have support for it (yet) + for (int i = 0; i < _listeners.Count; ++i) + { + if (_listeners[i].OnMouseButtonDown((MouseButton)button, X, Y)) + break; + } + } + else + { + // if the button is just being released this tick, then trigger an event in all listeners + if (_buttons[button]) + { + for (int i = 0; i < _listeners.Count; ++i) + { + if (_listeners[i].OnMouseButtonUp((MouseButton)button, X, Y)) + break; + } + } + + _buttons[button] = false; + _lockedButtons[button] = false; + } + + return true; + } + + public bool OnMotionEvent(SDL.SDL_MouseMotionEvent e) + { + DeltaX = e.x - X; + DeltaY = e.y - Y; + + X = e.x; + Y = e.y; + + // raise listener events for the mouse position only if it's moved this tick + if (DeltaX != 0 || DeltaY != 0) + { + for (int i = 0; i < _listeners.Count; ++i) + { + if (_listeners[i].OnMouseMove(X, Y, DeltaX, DeltaY)) + break; + } + } + + return true; + } + + public int X { get; private set; } + public int Y { get; private set; } + public int DeltaX { get; private set; } + public int DeltaY { get; private set; } + + public bool IsDown(MouseButton button) + { + return _buttons[(int)button] && !_lockedButtons[(int)button]; + } + + public bool IsPressed(MouseButton button) + { + if (_buttons[(int)button] && !_lockedButtons[(int)button]) + { + _lockedButtons[(int)button] = true; + return true; + } + else + return true; + } + + public void Lock(MouseButton button) + { + _lockedButtons[(int)button] = true; + } + + public void OnPostUpdate(float delta) + { + DeltaX = 0; + DeltaY = 0; + } + + public void Reset() + { + for (int i = 0; i < _buttons.Length; ++i) + _buttons[i] = false; + for (int i = 0; i < _lockedButtons.Length; ++i) + _lockedButtons[i] = false; + + X = 0; + Y = 0; + DeltaX = 0; + DeltaY = 0; + } + + public void RegisterListener(IMouseListener listener) + { + if (_listeners.Contains(listener)) + throw new InvalidOperationException("Duplicate listener registration."); + + _listeners.Add(listener); + } + + public void UnregisterListener(IMouseListener listener) + { + int index = _listeners.IndexOf(listener); + if (index == -1) + throw new InvalidOperationException("Listener not registered."); + + _listeners.RemoveAt(index); + } + } +} +