1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef AGS_SHARED_AC_KEYCODE_H
24 #define AGS_SHARED_AC_KEYCODE_H
25 
26 #include "ags/shared/core/platform.h"
27 #include "ags/shared/core/types.h"
28 
29 namespace AGS3 {
30 
31 #define EXTENDED_KEY_CODE ('\0')
32 #define EXTENDED_KEY_CODE_MACOS ('?')
33 
34 // Constant used to define Alt+Key codes
35 #define AGS_EXT_KEY_SHIFT  300
36 #define AGS_EXT_KEY_ALPHA(key)  (AGS_EXT_KEY_SHIFT + (key - eAGSKeyCodeCtrlA) + 1)
37 
38 // These are based on eKeyCode values in AGS Script.
39 // The actual values are based on scan codes of the old backend (allegro 3 and/or 4),
40 // which in turn mostly match ASCII values (at least for ones below 128), including
41 // Ctrl + letter combination codes.
42 // More codes are added at much higher ranges, for example Alt + letter combo codes
43 // are defined as 300 + letter's order.
44 // It should be specifically noted that eAGSKeyCode is directly conversible to ASCII
45 // at the range of 1 - 128, and AGS script makes use of this.
46 // Another important thing to note is that letter codes are always sent into script
47 // callbacks (like "on_key_pressed") in capitalized form, and that's how they are
48 // declared in script API (that's why in these callbacks user would have to check
49 // the Shift key state if they want to know if it's A or Shift + A).
50 enum eAGSKeyCode {
51 	eAGSKeyCodeNone = 0,
52 
53 	eAGSKeyCodeCtrlA = 1,
54 	eAGSKeyCodeCtrlB = 2,
55 	eAGSKeyCodeCtrlC = 3,
56 	eAGSKeyCodeCtrlD = 4,
57 	eAGSKeyCodeCtrlE = 5,
58 	eAGSKeyCodeCtrlF = 6,
59 	eAGSKeyCodeCtrlG = 7,
60 	eAGSKeyCodeCtrlH = 8,
61 	eAGSKeyCodeCtrlI = 9,
62 	eAGSKeyCodeCtrlJ = 10,
63 	eAGSKeyCodeCtrlK = 11,
64 	eAGSKeyCodeCtrlL = 12,
65 	eAGSKeyCodeCtrlM = 13,
66 	eAGSKeyCodeCtrlN = 14,
67 	eAGSKeyCodeCtrlO = 15,
68 	eAGSKeyCodeCtrlP = 16,
69 	eAGSKeyCodeCtrlQ = 17,
70 	eAGSKeyCodeCtrlR = 18,
71 	eAGSKeyCodeCtrlS = 19,
72 	eAGSKeyCodeCtrlT = 20,
73 	eAGSKeyCodeCtrlU = 21,
74 	eAGSKeyCodeCtrlV = 22,
75 	eAGSKeyCodeCtrlW = 23,
76 	eAGSKeyCodeCtrlX = 24,
77 	eAGSKeyCodeCtrlY = 25,
78 	eAGSKeyCodeCtrlZ = 26,
79 
80 	eAGSKeyCodeBackspace = 8, // matches Ctrl + H
81 	eAGSKeyCodeTab = 9, // matches Ctrl + I
82 	eAGSKeyCodeReturn = 13, // matches Ctrl + M
83 	eAGSKeyCodeEscape = 27,
84 
85 	/* printable chars - from eAGSKeyCodeSpace to eAGSKeyCode_z */
86 	eAGSKeyCodeSpace = 32,
87 	eAGSKeyCodeExclamationMark = 33,
88 	eAGSKeyCodeDoubleQuote = 34,
89 	eAGSKeyCodeHash = 35,
90 	eAGSKeyCodeDollar = 36,
91 	eAGSKeyCodePercent = 37,
92 	eAGSKeyCodeAmpersand = 38,
93 	eAGSKeyCodeSingleQuote = 39,
94 	eAGSKeyCodeOpenParenthesis = 40,
95 	eAGSKeyCodeCloseParenthesis = 41,
96 	eAGSKeyCodeAsterisk = 42,
97 	eAGSKeyCodePlus = 43,
98 	eAGSKeyCodeComma = 44,
99 	eAGSKeyCodeHyphen = 45,
100 	eAGSKeyCodePeriod = 46,
101 	eAGSKeyCodeForwardSlash = 47,
102 
103 	eAGSKeyCode0 = 48,
104 	eAGSKeyCode1 = 49,
105 	eAGSKeyCode2 = 50,
106 	eAGSKeyCode3 = 51,
107 	eAGSKeyCode4 = 52,
108 	eAGSKeyCode5 = 53,
109 	eAGSKeyCode6 = 54,
110 	eAGSKeyCode7 = 55,
111 	eAGSKeyCode8 = 56,
112 	eAGSKeyCode9 = 57,
113 
114 	eAGSKeyCodeColon = 58,
115 	eAGSKeyCodeSemiColon = 59,
116 	eAGSKeyCodeLessThan = 60,
117 	eAGSKeyCodeEquals = 61,
118 	eAGSKeyCodeGreaterThan = 62,
119 	eAGSKeyCodeQuestionMark = 63,
120 	eAGSKeyCodeAt = 64, // '@'
121 
122 	/* Notice that default letter codes match capital ASCII letters */
123 	eAGSKeyCodeA = 65, // 'A'
124 	eAGSKeyCodeB = 66, // 'B', etc
125 	eAGSKeyCodeC = 67,
126 	eAGSKeyCodeD = 68,
127 	eAGSKeyCodeE = 69,
128 	eAGSKeyCodeF = 70,
129 	eAGSKeyCodeG = 71,
130 	eAGSKeyCodeH = 72,
131 	eAGSKeyCodeI = 73,
132 	eAGSKeyCodeJ = 74,
133 	eAGSKeyCodeK = 75,
134 	eAGSKeyCodeL = 76,
135 	eAGSKeyCodeM = 77,
136 	eAGSKeyCodeN = 78,
137 	eAGSKeyCodeO = 79,
138 	eAGSKeyCodeP = 80,
139 	eAGSKeyCodeQ = 81,
140 	eAGSKeyCodeR = 82,
141 	eAGSKeyCodeS = 83,
142 	eAGSKeyCodeT = 84,
143 	eAGSKeyCodeU = 85,
144 	eAGSKeyCodeV = 86,
145 	eAGSKeyCodeW = 87,
146 	eAGSKeyCodeX = 88,
147 	eAGSKeyCodeY = 89,
148 	eAGSKeyCodeZ = 90, // 'Z'
149 
150 	eAGSKeyCodeOpenBracket = 91,
151 	eAGSKeyCodeBackSlash = 92,
152 	eAGSKeyCodeCloseBracket = 93,
153 	eAGSKeyCodeCaret = 94, // '^'
154 	eAGSKeyCodeUnderscore = 95,
155 	eAGSKeyCodeBackquote = 96, // '`'
156 
157 	/* Small ASCII letter codes are declared here for consistency, but unused in script callbacks */
158 	eAGSKeyCode_a = 97, // 'a'
159 	eAGSKeyCode_b = 98, // 'b', etc
160 	eAGSKeyCode_c = 99,
161 	eAGSKeyCode_d = 100,
162 	eAGSKeyCode_e = 101,
163 	eAGSKeyCode_f = 102,
164 	eAGSKeyCode_g = 103,
165 	eAGSKeyCode_h = 104,
166 	eAGSKeyCode_i = 105,
167 	eAGSKeyCode_j = 106,
168 	eAGSKeyCode_k = 107,
169 	eAGSKeyCode_l = 108,
170 	eAGSKeyCode_m = 109,
171 	eAGSKeyCode_n = 110,
172 	eAGSKeyCode_o = 111,
173 	eAGSKeyCode_p = 112,
174 	eAGSKeyCode_q = 113,
175 	eAGSKeyCode_r = 114,
176 	eAGSKeyCode_s = 115,
177 	eAGSKeyCode_t = 116,
178 	eAGSKeyCode_u = 117,
179 	eAGSKeyCode_v = 118,
180 	eAGSKeyCode_w = 119,
181 	eAGSKeyCode_x = 120,
182 	eAGSKeyCode_y = 121,
183 	eAGSKeyCode_z = 122, // 'z'
184 
185 	/* extended symbol codes */
186 	eAGSKeyCodeF1 = AGS_EXT_KEY_SHIFT + 59,
187 	eAGSKeyCodeF2 = AGS_EXT_KEY_SHIFT + 60,
188 	eAGSKeyCodeF3 = AGS_EXT_KEY_SHIFT + 61,
189 	eAGSKeyCodeF4 = AGS_EXT_KEY_SHIFT + 62,
190 	eAGSKeyCodeF5 = AGS_EXT_KEY_SHIFT + 63,
191 	eAGSKeyCodeF6 = AGS_EXT_KEY_SHIFT + 64,
192 	eAGSKeyCodeF7 = AGS_EXT_KEY_SHIFT + 65,
193 	eAGSKeyCodeF8 = AGS_EXT_KEY_SHIFT + 66,
194 	eAGSKeyCodeF9 = AGS_EXT_KEY_SHIFT + 67,
195 	eAGSKeyCodeF10 = AGS_EXT_KEY_SHIFT + 68,
196 	eAGSKeyCodeF11 = AGS_EXT_KEY_SHIFT + 133,
197 	eAGSKeyCodeF12 = AGS_EXT_KEY_SHIFT + 134,
198 
199 	eAGSKeyCodeHome = AGS_EXT_KEY_SHIFT + 71,
200 	eAGSKeyCodeUpArrow = AGS_EXT_KEY_SHIFT + 72,
201 	eAGSKeyCodePageUp = AGS_EXT_KEY_SHIFT + 73,
202 	eAGSKeyCodeLeftArrow = AGS_EXT_KEY_SHIFT + 75,
203 	eAGSKeyCodeNumPad5 = AGS_EXT_KEY_SHIFT + 76,
204 	eAGSKeyCodeRightArrow = AGS_EXT_KEY_SHIFT + 77,
205 	eAGSKeyCodeEnd = AGS_EXT_KEY_SHIFT + 79,
206 	eAGSKeyCodeDownArrow = AGS_EXT_KEY_SHIFT + 80,
207 	eAGSKeyCodePageDown = AGS_EXT_KEY_SHIFT + 81,
208 	eAGSKeyCodeInsert = AGS_EXT_KEY_SHIFT + 82,
209 	eAGSKeyCodeDelete = AGS_EXT_KEY_SHIFT + 83,
210 
211 	// not certain if necessary anymore (and not certain what was the origin of this value)
212 	eAGSKeyCodeAltTab = AGS_EXT_KEY_SHIFT + 99,
213 
214 	// [sonneveld] These are only used by debugging and abort keys.
215 	// They're based on allegro4 codes ...
216 	eAGSKeyCodeAltV = AGS_EXT_KEY_ALPHA(eAGSKeyCodeV),
217 	eAGSKeyCodeAltX = AGS_EXT_KEY_ALPHA(eAGSKeyCodeX),
218 
219 	// These keys are not defined in the script eAGSKey enum but are in the manual
220 	// https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html
221 	// *Probably* made-up numbers not derived from allegro scan codes.
222 	eAGSKeyCodeLShift = 403,
223 	eAGSKeyCodeRShift = 404,
224 	eAGSKeyCodeLCtrl = 405,
225 	eAGSKeyCodeRCtrl = 406,
226 	eAGSKeyCodeLAlt = 407,
227 
228 	// [sonneveld]
229 	// The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes.
230 	// These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints.
231 	eAGSKeyCodeRAlt = 420,
232 	// TODO: judging that above works (at least on Win), following might also work,
233 	// but idk which ones may be necessary; still keeping here this excerpt from an old code
234 	// if they'd want to be restored (also add them to script API then!).
235 	// Also see allegro 4's keyboard.h, where these were declared.
236 	/*
237 	case 392: __allegro_KEY_PRTSCR
238 	case 393: __allegro_KEY_PAUSE
239 	case 394: __allegro_KEY_ABNT_C1  // The ABNT_C1 (Brazilian) key
240 	case 395: __allegro_KEY_YEN)
241 	case 396: __allegro_KEY_KANA
242 	case 397: __allegro_KEY_CONVERT
243 	case 398: __allegro_KEY_NOCONVERT
244 	case 400: __allegro_KEY_CIRCUMFLEX
245 	case 402: __allegro_KEY_KANJI
246 	case 421: __allegro_KEY_LWIN
247 	case 422: __allegro_KEY_RWIN
248 	case 423: __allegro_KEY_MENU
249 	case 424: __allegro_KEY_SCRLOCK
250 	case 425: __allegro_KEY_NUMLOCK
251 	case 426: __allegro_KEY_CAPSLOCK
252 	*/
253 };
254 
255 // Combined key code and a textual representation in UTF-8
256 struct KeyInput {
257 	const static size_t UTF8_ARR_SIZE = 5;
258 
259 	eAGSKeyCode Key = eAGSKeyCodeNone;
260 	char        Text[UTF8_ARR_SIZE] = { 0 };
261 
262 	KeyInput() = default;
263 };
264 
265 // Converts eAGSKeyCode to script API code, for "on_key_press" and similar callbacks
266 int AGSKeyToScriptKey(int keycode);
267 // Converts eAGSKeyCode to ASCII text representation with the range check; returns 0 on failure
268 // Not unicode compatible.
269 char AGSKeyToText(int keycode);
270 
271 } // namespace AGS3
272 
273 #endif
274