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