1 module pixelperfectengine.system.input.types; 2 3 /// Key modifiers used by the engine. 4 public enum KeyModifier : ubyte { 5 None = 0x00, 6 Shift = 0x01, 7 Ctrl = 0x02, 8 Alt = 0x04, 9 GUI = 0x08, 10 NumLock = 0x10, 11 CapsLock = 0x20, 12 ScrollLock = 0x40, 13 LockKeys = NumLock | CapsLock | ScrollLock, 14 Mode = 0x80, 15 All = 0xFF, 16 } 17 /// Modifier flags for joystick stuff, e.g. axes. 18 public enum JoyModifier : ubyte { 19 Button = 0x00, 20 DPad = 0x04, 21 Axis = 0x08, 22 23 } 24 /** 25 * Determines input device types. 26 * Currently 0-3 are used, 4-7 is reserved for future use. 27 */ 28 public enum Devicetype : ubyte { 29 Keyboard = 0, 30 Joystick = 1, ///Also used for gamepads, wheels, etc., that can be interpreted as such 31 Mouse = 2, 32 Touchscreen = 3 33 } 34 /** 35 * Keys used during text input. 36 * Multiple enter and backspace keys are not threated as different entities in this case. 37 */ 38 public enum TextInputKey { 39 init, 40 Enter = 1, 41 Escape = 2, 42 Backspace = 3, 43 CursorUp = 4, 44 CursorDown = 5, 45 CursorLeft = 6, 46 CursorRight = 7, 47 Insert = 8, 48 Delete = 9, 49 Home = 10, 50 End = 11, 51 PageUp = 12, 52 PageDown = 13 53 } 54 /** 55 * Mouse Buttons that are numbered by the engine. 56 */ 57 public enum MouseButton : ubyte { 58 Left = 1, 59 Mid = 2, 60 Right = 3, 61 Next = 4, 62 Previous = 5 63 } 64 /** 65 * Mouse Button flags. 66 */ 67 public enum MouseButtonFlags : uint { 68 Left = 1 << 0, 69 Mid = 1 << 1, 70 Right = 1 << 2, 71 Next = 1 << 3, 72 Previous = 1 << 4 73 } 74 /** 75 * Button states. 76 */ 77 public enum ButtonState : ubyte { 78 Released = 0, 79 Pressed = 1 80 } 81 /** 82 * Converts key modifier codes from SDL to the engine's own 83 */ 84 public ubyte keyModConv(ushort input) @nogc pure nothrow @safe { 85 import sdl.keycode; 86 ubyte result; 87 if (input & KMOD_SHIFT) result |= KeyModifier.Shift; 88 if (input & KMOD_CTRL) result |= KeyModifier.Ctrl; 89 if (input & KMOD_ALT) result |= KeyModifier.Alt; 90 if (input & KMOD_GUI) result |= KeyModifier.GUI; 91 if (input & KMOD_NUM) result |= KeyModifier.NumLock; 92 if (input & KMOD_CAPS) result |= KeyModifier.CapsLock; 93 if (input & KMOD_MODE) result |= KeyModifier.Mode; 94 return result; 95 } 96 97 /** 98 * Stores an easy to lookup code for input bindings in integer format. 99 * Keybindings should be stored in the configuration file as a human-readable format, as this struct 100 * might change in the future if more things need to be added 101 */ 102 public struct BindingCode { 103 /** 104 * The basis for all comparison. 105 * bits 0-8: Button/axis number. 106 * bits 9-16: Modifier flags. 107 * bits 17-19: Device type ID. 108 * bits 20-23: Device number. 109 * bits 24-31: Extended area. 110 */ 111 uint base; 112 /** 113 * Modifier flags. 114 * bits 0-8: Unused. 115 * bits 9-16: Keymod ignore. 116 * bits 17-31: Unused. 117 */ 118 uint flags; 119 ///Standard CTOR 120 this(uint base) @nogc @safe pure nothrow { 121 this.base = base; 122 } 123 ///CTOR with individual values 124 this(ushort _buttonNum, ubyte _modifierFlags, ubyte _deviceTypeID, ubyte _deviceNum, ubyte _keymodIgnore = 0) 125 @nogc @safe pure nothrow { 126 buttonNum = _buttonNum; 127 modifierFlags = _modifierFlags; 128 deviceTypeID = _deviceTypeID; 129 deviceNum = _deviceNum; 130 keymodIgnore = _keymodIgnore; 131 } 132 /// Returns the button number portion of the code. 133 @property ushort buttonNum() @nogc @safe pure nothrow const { 134 return cast(ushort)(base & 0x1_FF); 135 } 136 /// Sets the button number portion of the code. 137 @property ushort buttonNum(ushort val) @nogc @safe pure nothrow { 138 base &= ~0x00_00_01_FF; 139 base |= val & 0x1_FF; 140 return cast(ushort)(base & 0x1_FF); 141 } 142 /// Returns the modifier flag portion of the code. 143 @property ubyte modifierFlags() @nogc @safe pure nothrow const { 144 return cast(ubyte)(base >>> 9); 145 } 146 /// Sets the modifier flag portion of the code. 147 @property ubyte modifierFlags(ubyte val) @nogc @safe pure nothrow { 148 base &= ~0x00_01_FE_00; 149 base |= val << 9; 150 return cast(ubyte)(base >>> 9); 151 } 152 /// Returns the keymod ignore code. 153 @property ubyte keymodIgnore() @nogc @safe pure nothrow const { 154 return cast(ubyte)(flags >>> 9); 155 } 156 /// Sets the keymod ignore code. 157 @property ubyte keymodIgnore(ubyte val) @nogc @safe pure nothrow { 158 flags &= ~0x00_01_FE_00; 159 flags |= val << 9; 160 return cast(ubyte)(flags >>> 9); 161 } 162 /// Returns the device type ID portion of the code. 163 @property ubyte deviceTypeID() @nogc @safe pure nothrow const { 164 return cast(ubyte)((base >>> 17) & 0b0000_0111); 165 } 166 /// Sets the device type ID portion of the code. 167 @property ubyte deviceTypeID(ubyte val) @nogc @safe pure nothrow { 168 base &= ~0x00_0E_00_00; 169 base |= (val & 0b0000_0111) << 17; 170 return cast(ubyte)((base >>> 17) & 0b0000_0111); 171 } 172 /// Returns the device type ID portion of the code. 173 @property ubyte deviceNum() @nogc @safe pure nothrow const { 174 return cast(ubyte)((base >>> 20) & 0x0f); 175 } 176 /// Sets the device type ID portion of the code. 177 @property ubyte deviceNum(ubyte val) @nogc @safe pure nothrow { 178 base &= ~0x00_F0_00_00; 179 base |= (val & 0x0f) << 20; 180 return cast(ubyte)((base >>> 20) & 0x0f); 181 } 182 ///Returns the extended area value. 183 @property ubyte extArea() @nogc @safe pure nothrow const { 184 return cast(ubyte)(base >> 24); 185 } 186 ///Sets the extended area value. 187 @property ubyte extArea(ubyte val) @nogc @safe pure nothrow { 188 base &= ~0xFF_00_00_00; 189 base |= val << 24; 190 return cast(ubyte)(base >> 24); 191 } 192 ///Returns the keymod ignore flags 193 ///Return whether the binding code is a joy axis 194 @property bool isJoyAxis() @nogc @safe pure nothrow { 195 return deviceTypeID == Devicetype.Joystick && modifierFlags == JoyModifier.Axis; 196 } 197 int opCmp(const BindingCode other) @nogc @safe pure nothrow const { 198 const uint baseLH = base | flags | other.flags; 199 const uint baseRH = other.base | flags | other.flags; 200 if(baseLH > baseRH) return 1; 201 else if(baseLH < baseRH) return -1; 202 else return 0; 203 } 204 bool opEquals(const BindingCode other) @nogc @safe pure nothrow const { 205 const uint baseLH = base | flags | other.flags; 206 const uint baseRH = other.base | flags | other.flags; 207 return baseLH == baseRH; 208 } 209 } 210 /** 211 * Defines a single Input Binding. 212 */ 213 public struct InputBinding { 214 uint code; ///Code being sent out to the target, should be a MurmurhashV3/32 code. 215 uint flags; ///Stores additional properties of the input binding. 216 float[2] deadzone; ///The deadzone, if the binding is an axis. 217 static enum IS_AXIS_AS_BUTTON = 1<<0; ///If set in the flags field, then it treats the axis as a button. 218 ///Default CTOR 219 this(uint code, uint flags = 0, float[2] deadzone = [0.0, 0.0]) @nogc @safe pure nothrow { 220 this.code = code; 221 this.flags = flags; 222 this.deadzone = deadzone; 223 } 224 ///CTOR that creates code from string 225 this(string code, uint flags = 0, float[2] deadzone = [0.0, 0.0]) @nogc @safe pure nothrow { 226 import collections.commons : defaultHash; 227 this.code = defaultHash(code); 228 this.flags = flags; 229 this.deadzone = deadzone; 230 } 231 int opCmp(const InputBinding other) const @nogc @safe pure nothrow { 232 if (code > other.code) return 1; 233 else if (code < other.code) return -1; 234 else return 0; 235 } 236 237 int opCmp(const uint other) const @nogc @safe pure nothrow { 238 if (code > other) return 1; 239 else if (code < other) return -1; 240 else return 0; 241 } 242 } 243 /** 244 * Common values for mouse events. 245 */ 246 public struct MouseEventCommons { 247 uint timestamp; ///Timestamp of the event 248 uint windowID; ///Identifies the window where the event originated 249 uint mouseID; ///Identifies the mouse that generated the event 250 } 251 /** 252 * Packs mouseclick event information into a single struct. 253 */ 254 public struct MouseClickEvent { 255 import std.bitmanip : bitfields; 256 int x; ///X position of where the event happened 257 int y; ///Y position of where the event happened 258 ubyte button; ///The button that generated the event 259 ubyte clicks; ///The amount of clicks 260 bool state; ///Button state. Might be replaced in the future with flags. 261 } 262 /** 263 * Packs mousewheel event information into a single struct. 264 */ 265 public struct MouseWheelEvent { 266 int x; ///Horizontal scrolling 267 int y; ///Vertical scrolling 268 } 269 /** 270 * Packs mousemotion event information into a single struct. 271 */ 272 public struct MouseMotionEvent { 273 uint buttonState; ///State of the buttons 274 int x; ///Horizontal position of the cursor 275 int y; ///Vertical position of the cursor 276 int relX; ///Horizontal amount of mouse movement 277 int relY; ///Vertical amount of mouse movement 278 }