summary refs log tree commit diff
path: root/src/Input.h
blob: e4e491e56592443524f647b68ac3fc8ac2c48831 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#ifndef CC_INPUT_H
#define CC_INPUT_H
#include "Core.h"
/* 
Manages input state, raising input related events, and base input handling
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
*/
struct IGameComponent;
struct StringsBuffer;
extern struct IGameComponent Input_Component;

enum InputButtons {
	INPUT_NONE, /* Unrecognised key */

	CCKEY_F1, CCKEY_F2, CCKEY_F3, CCKEY_F4, CCKEY_F5, CCKEY_F6, CCKEY_F7, CCKEY_F8, CCKEY_F9, CCKEY_F10,
	CCKEY_F11, CCKEY_F12, CCKEY_F13, CCKEY_F14, CCKEY_F15, CCKEY_F16, CCKEY_F17, CCKEY_F18, CCKEY_F19, CCKEY_F20,
	CCKEY_F21, CCKEY_F22, CCKEY_F23, CCKEY_F24,

	CCKEY_TILDE, CCKEY_MINUS, CCKEY_EQUALS, CCKEY_LBRACKET, CCKEY_RBRACKET, CCKEY_SLASH,
	CCKEY_SEMICOLON, CCKEY_QUOTE, CCKEY_COMMA, CCKEY_PERIOD, CCKEY_BACKSLASH,

	CCKEY_LSHIFT, CCKEY_RSHIFT, CCKEY_LCTRL, CCKEY_RCTRL,
	CCKEY_LALT, CCKEY_RALT, CCKEY_LWIN, CCKEY_RWIN,

	CCKEY_UP, CCKEY_DOWN, CCKEY_LEFT, CCKEY_RIGHT,

	CCKEY_0, CCKEY_1, CCKEY_2, CCKEY_3, CCKEY_4,
	CCKEY_5, CCKEY_6, CCKEY_7, CCKEY_8, CCKEY_9, /* same as '0'-'9' */

	CCKEY_INSERT, CCKEY_DELETE, CCKEY_HOME, CCKEY_END, CCKEY_PAGEUP, CCKEY_PAGEDOWN,
	CCKEY_MENU,

	CCKEY_A, CCKEY_B, CCKEY_C, CCKEY_D, CCKEY_E, CCKEY_F, CCKEY_G, CCKEY_H, CCKEY_I, CCKEY_J,
	CCKEY_K, CCKEY_L, CCKEY_M, CCKEY_N, CCKEY_O, CCKEY_P, CCKEY_Q, CCKEY_R, CCKEY_S, CCKEY_T,
	CCKEY_U, CCKEY_V, CCKEY_W, CCKEY_X, CCKEY_Y, CCKEY_Z, /* same as 'A'-'Z' */

	CCKEY_ENTER, CCKEY_ESCAPE, CCKEY_SPACE, CCKEY_BACKSPACE, CCKEY_TAB, CCKEY_CAPSLOCK,
	CCKEY_SCROLLLOCK, CCKEY_PRINTSCREEN, CCKEY_PAUSE, CCKEY_NUMLOCK,

	CCKEY_KP0, CCKEY_KP1, CCKEY_KP2, CCKEY_KP3, CCKEY_KP4,
	CCKEY_KP5, CCKEY_KP6, CCKEY_KP7, CCKEY_KP8, CCKEY_KP9,
	CCKEY_KP_DIVIDE, CCKEY_KP_MULTIPLY, CCKEY_KP_MINUS,
	CCKEY_KP_PLUS, CCKEY_KP_DECIMAL, CCKEY_KP_ENTER,

	/* NOTE: RMOUSE must be before MMOUSE for PlayerClick compatibility */
	CCMOUSE_X1, CCMOUSE_X2, CCMOUSE_L, CCMOUSE_R, CCMOUSE_M,
	CCWHEEL_UP, CCWHEEL_DOWN, CCWHEEL_LEFT, CCWHEEL_RIGHT,
	CCMOUSE_X3, CCMOUSE_X4, CCMOUSE_X5, CCMOUSE_X6,
	
	CCKEY_VOLUME_MUTE, CCKEY_VOLUME_UP, CCKEY_VOLUME_DOWN, CCKEY_SLEEP,
	CCKEY_MEDIA_NEXT, CCKEY_MEDIA_PREV, CCKEY_MEDIA_PLAY, CCKEY_MEDIA_STOP,
	CCKEY_BROWSER_PREV, CCKEY_BROWSER_NEXT, CCKEY_BROWSER_REFRESH, CCKEY_BROWSER_STOP, CCKEY_BROWSER_SEARCH, CCKEY_BROWSER_FAVORITES, CCKEY_BROWSER_HOME,
	CCKEY_LAUNCH_MAIL, CCKEY_LAUNCH_MEDIA, CCKEY_LAUNCH_APP1, CCKEY_LAUNCH_CALC, 

	CCPAD_A, CCPAD_B, CCPAD_X, CCPAD_Y, CCPAD_L, CCPAD_R, 
	CCPAD_Z, CCPAD_C, CCPAD_D,
	CCPAD_LEFT, CCPAD_RIGHT, CCPAD_UP, CCPAD_DOWN,
	CCPAD_START, CCPAD_SELECT, CCPAD_ZL, CCPAD_ZR,
	CCPAD_LSTICK, CCPAD_RSTICK,
	CCPAD_CLEFT, CCPAD_CRIGHT, CCPAD_CUP, CCPAD_CDOWN,

	INPUT_COUNT,

	INPUT_CLIPBOARD_COPY  = 1001,
	INPUT_CLIPBOARD_PASTE = 1002
};
#define Input_IsPadButton(btn) ((btn) >= CCPAD_A && (btn) < INPUT_COUNT)

extern const char* const Input_DisplayNames[INPUT_COUNT];

extern struct _InputState {
	/* Pressed state of each input button. Use Input_Set to change */
	cc_bool Pressed[INPUT_COUNT];
	/* Whether raw mouse/touch input is currently being listened for */
	cc_bool RawMode;
	/* Sources available for input (Mouse/Keyboard, Gamepad) */
	cc_uint8 Sources;
} Input;

#define INPUT_SOURCE_NORMAL  (1 << 0)
#define INPUT_SOURCE_GAMEPAD (1 << 1)

/* Sets Input_Pressed[key] to true and raises InputEvents.Down */
void Input_SetPressed(int key);
/* Sets Input_Pressed[key] to false and raises InputEvents.Up */
void Input_SetReleased(int key);
/* Calls either Input_SetPressed or Input_SetReleased */
void Input_Set(int key, int pressed);
void Input_SetNonRepeatable(int key, int pressed);
/* Resets all input buttons to released state. (Input_SetReleased) */
void Input_Clear(void);


#define Input_IsWinPressed()   (Input.Pressed[CCKEY_LWIN]   || Input.Pressed[CCKEY_RWIN])
#define Input_IsAltPressed()   (Input.Pressed[CCKEY_LALT]   || Input.Pressed[CCKEY_RALT])
#define Input_IsCtrlPressed()  (Input.Pressed[CCKEY_LCTRL]  || Input.Pressed[CCKEY_RCTRL])
#define Input_IsShiftPressed() (Input.Pressed[CCKEY_LSHIFT] || Input.Pressed[CCKEY_RSHIFT])

#define Input_IsUpButton(btn)     ((btn) == CCKEY_UP     || (btn) == CCPAD_UP)
#define Input_IsDownButton(btn)   ((btn) == CCKEY_DOWN   || (btn) == CCPAD_DOWN)
#define Input_IsLeftButton(btn)   ((btn) == CCKEY_LEFT   || (btn) == CCPAD_LEFT)
#define Input_IsRightButton(btn)  ((btn) == CCKEY_RIGHT  || (btn) == CCPAD_RIGHT)

#define Input_IsEnterButton(btn)  ((btn) == CCKEY_ENTER  || (btn) == CCPAD_START || (btn) == CCKEY_KP_ENTER)
#define Input_IsPauseButton(btn)  ((btn) == CCKEY_ESCAPE || (btn) == CCPAD_START || (btn) == CCKEY_PAUSE)
#define Input_IsEscapeButton(btn) ((btn) == CCKEY_ESCAPE || (btn) == CCPAD_SELECT)

#if defined CC_BUILD_HAIKU
	/* Haiku uses ALT instead of CTRL for clipboard and stuff */
	#define Input_IsActionPressed() Input_IsAltPressed()
#elif defined CC_BUILD_DARWIN
	/* macOS uses CMD instead of CTRL for clipboard and stuff */
	#define Input_IsActionPressed() Input_IsWinPressed()
#else
	#define Input_IsActionPressed() Input_IsCtrlPressed()
#endif
int Input_CalcDelta(int btn, int horDelta, int verDelta);


#ifdef CC_BUILD_TOUCH
#define INPUT_MAX_POINTERS 32
enum INPUT_MODE { INPUT_MODE_PLACE, INPUT_MODE_DELETE, INPUT_MODE_NONE, INPUT_MODE_COUNT };

extern int Pointers_Count;
extern int Input_TapMode, Input_HoldMode;
/* Whether touch input is being used. */
extern cc_bool Input_TouchMode;
void Input_SetTouchMode(cc_bool enabled);

void Input_AddTouch(long id,    int x, int y);
void Input_UpdateTouch(long id, int x, int y);
void Input_RemoveTouch(long id, int x, int y);
#else
#define INPUT_MAX_POINTERS 1
#define Pointers_Count 1
#define Input_TouchMode false
#endif

/* Touch fingers are initially are 'all' type, meaning they could */
/*  trigger menu clicks, camera movement, or place/delete blocks  */
/* But for example, after clicking on a menu button, you wouldn't */
/*  want moving that finger anymore to move the camera */
#define TOUCH_TYPE_GUI    1
#define TOUCH_TYPE_CAMERA 2
#define TOUCH_TYPE_BLOCKS 4
#define TOUCH_TYPE_ALL (TOUCH_TYPE_GUI | TOUCH_TYPE_CAMERA | TOUCH_TYPE_BLOCKS)

/* Data for mouse and touch */
extern struct Pointer { int x, y; } Pointers[INPUT_MAX_POINTERS];
/* Raises appropriate events for a mouse vertical scroll */
void Mouse_ScrollVWheel(float delta);
/* Raises appropriate events for a mouse horizontal scroll */
void Mouse_ScrollHWheel(float delta);
/* Sets X and Y position of the given pointer, then raises appropriate events */
void Pointer_SetPosition(int idx, int x, int y);


/* Enumeration of all input bindings. */
enum InputBind_ {
	BIND_FORWARD, BIND_BACK, BIND_LEFT, BIND_RIGHT,
	BIND_JUMP, BIND_RESPAWN, BIND_SET_SPAWN, BIND_CHAT,
	BIND_INVENTORY, BIND_FOG, BIND_SEND_CHAT, BIND_TABLIST,
	BIND_SPEED, BIND_NOCLIP, BIND_FLY, BIND_FLY_UP, BIND_FLY_DOWN,
	BIND_EXT_INPUT, BIND_HIDE_FPS, BIND_SCREENSHOT, BIND_FULLSCREEN,
	BIND_THIRD_PERSON, BIND_HIDE_GUI, BIND_AXIS_LINES, BIND_ZOOM_SCROLL,
	BIND_HALF_SPEED, BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK,
	BIND_AUTOROTATE, BIND_HOTBAR_SWITCH, BIND_SMOOTH_CAMERA,
	BIND_DROP_BLOCK, BIND_IDOVERLAY, BIND_BREAK_LIQUIDS,
	BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT,
	BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3,
	BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6,
	BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9,
	BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT,
	BIND_COUNT
};
typedef int InputBind;
typedef struct BindMapping_ { cc_uint8 button1, button2; } BindMapping;
typedef cc_bool (*BindTriggered)(int key);
typedef void    (*BindReleased)(int key);
#define BindMapping_Set(mapping, btn1, btn2) (mapping)->button1 = btn1; (mapping)->button2 = btn2;

/* The keyboard/mouse buttons that are bound to each input binding */
extern BindMapping KeyBind_Mappings[BIND_COUNT];
/* The gamepad buttons that are bound to each input binding */
extern BindMapping PadBind_Mappings[BIND_COUNT];
/* Default keyboard/mouse button that each input binding is bound to */
extern const BindMapping KeyBind_Defaults[BIND_COUNT];
/* Default gamepad button that each input binding is bound to */
extern const BindMapping PadBind_Defaults[BIND_COUNT];
/* Callback behaviour for when the given input binding is triggered */
extern BindTriggered Bind_OnTriggered[BIND_COUNT];
/* Callback behaviour for when the given input binding is released */
extern BindReleased  Bind_OnReleased[BIND_COUNT];

/* InputBind_IsPressed is what should be used, but export KeyBind_IsPressed for backwards compatibility */
#define InputBind_IsPressed KeyBind_IsPressed
/* Whether the given binding should be triggered in response to given input button being pressed */
CC_API cc_bool InputBind_Claims(InputBind binding, int btn);
/* Gets whether the given input binding is currently being triggered */
CC_API cc_bool InputBind_IsPressed(InputBind binding);

/* Sets the key/mouse button that the given input binding is bound to */
void KeyBind_Set(InputBind binding, int btn);
/* Sets the gamepad button that the given input binding is bound to */
void PadBind_Set(InputBind binding, int btn);
/* Resets the key/mouse button that the given input binding is bound to */
void KeyBind_Reset(InputBind binding);
/* Resets the gamepad button that the given input binding is bound to*/
void PadBind_Reset(InputBind binding);


/* Gamepad axes. Default behaviour is: */
/*  - left axis:  player movement  */
/*  - right axis: camera movement */
enum PAD_AXIS         { PAD_AXIS_LEFT, PAD_AXIS_RIGHT };
enum AXIS_SENSITIVITY { AXIS_SENSI_LOWER, AXIS_SENSI_LOW, AXIS_SENSI_NORMAL, AXIS_SENSI_HIGH, AXIS_SENSI_HIGHER };
enum AXIS_BEHAVIOUR   { AXIS_BEHAVIOUR_MOVEMENT, AXIS_BEHAVIOUR_CAMERA };
extern int Gamepad_AxisBehaviour[2];
extern int Gamepad_AxisSensitivity[2];

/* Sets value of the given gamepad button */
void Gamepad_SetButton(int port, int btn, int pressed);
/* Sets value of the given axis */
void Gamepad_SetAxis(int port, int axis, float x, float y, float delta);
void Gamepad_Tick(float delta);
#define INPUT_MAX_GAMEPADS 4


/* whether to leave text input open for user to enter further input */
#define HOTKEY_FLAG_STAYS_OPEN   0x01
/* Whether the hotkey was auto defined (e.g. by server) */
#define HOTKEY_FLAG_AUTO_DEFINED 0x02

extern const cc_uint8 Hotkeys_LWJGL[256];
struct HotkeyData {
	int textIndex;     /* contents to copy directly into the input bar */
	cc_uint8 trigger;  /* Member of Key enumeration */
	cc_uint8 mods;     /* HotkeyModifiers bitflags */
	cc_uint8 flags;    /* HOTKEY_FLAG flags */
};

#define HOTKEYS_MAX_COUNT 256
extern struct HotkeyData HotkeysList[HOTKEYS_MAX_COUNT];
extern struct StringsBuffer HotkeysText;
enum HotkeyModifiers {
	HOTKEY_MOD_CTRL = 1, HOTKEY_MOD_SHIFT = 2, HOTKEY_MOD_ALT = 4
};

/* Adds or updates a new hotkey. */
void Hotkeys_Add(int trigger, cc_uint8 modifiers, const cc_string* text, cc_uint8 flags);
/* Removes the given hotkey. */
cc_bool Hotkeys_Remove(int trigger, cc_uint8 modifiers);
/* Returns the first hotkey which is bound to the given key and has its modifiers pressed. */
/* NOTE: The hotkeys list is sorted, so hotkeys with most modifiers are checked first. */
int Hotkeys_FindPartial(int key);

/* Loads the given hotkey from options. (if it exists) */
void StoredHotkeys_Load(int trigger, cc_uint8 modifiers);
/* Removes the given hotkey from options. */
void StoredHotkeys_Remove(int trigger, cc_uint8 modifiers);
/* Adds the given hotkey from options. */
void StoredHotkeys_Add(int trigger, cc_uint8 modifiers, cc_bool moreInput, const cc_string* text);


cc_bool InputHandler_SetFOV(int fov);
cc_bool Input_HandleMouseWheel(float delta);
void InputHandler_Tick(void);
void InputHandler_OnScreensChanged(void);
void InputHandler_DeleteBlock(void);
void InputHandler_PlaceBlock(void);
void InputHandler_PickBlock(void);
#endif