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 }