1 #include <string.h>
2 #include <stdio.h>	/* sprintf */
3 #include <stdlib.h>	/* exit */
4 #include "input.h"
5 #include "keyboard.h"
6 #include "joystick.h"
7 #include "../timer.h"
8 #include "../draw/draw.h"  /* upd_screen */
9 #include "../game/tetris.h"
10 #ifndef SOCKET
11 #define SOCKET_EMPTY_DEFS 1
12 #undef socket_fd
13 #define socket_fd -1
14 #endif
15 #include "../netw/sock.h"
16 
17 #include "../textgfx/textgfx.h" /* upd_termresize */
18 #include "../focus.h"
19 
20 extern int close_button_pressed;
21 
22 const char input_chr9[9][4] = {
23 	"LFT", "RGT", "UP", "DWN", "(A)", "(B)", "BEL", "BS", "HT"
24 };
25 
26 int inputdevs_fd[4] = {-1,-1,-1,-1};
27 char inputdevs_player[4] = {0};
28 
29 int autorep_a_b_btns = 0;
30 int edit_mode = 0;
31 
32 static short spawn_tm[2];
33 static int ignore_dev;
34 
init_inputdevs()35 void init_inputdevs()
36 {
37 	init_keybd();
38 #if JOYSTICK
39 	init_joysticks();
40 #endif
41 }
42 
43 #if TWOPLAYER && NUM_INPUTDEVS > 1
player_flag(int i,int flags)44 static int player_flag(int i, int flags)
45 {
46 	if (socket_fd > -1) {
47 		if (i==3)
48 			return PLAYER_2;
49 	} else if (inputdevs_player[i] && !(flags & SINGLE_PL))
50 		return inputdevs_player[i]==1 ? PLAYER_1 : PLAYER_2;
51 	return 0;
52 }
53 #else
54 #define player_flag(i, flags) 0
55 #endif
56 
getkeypress_select(int tm,int flags)57 static int getkeypress_select(int tm, int flags)
58 {
59 	int keypress = 0;
60 	int i;
61 #if TERM_RESIZING
62 	if (tm > 80)
63 		upd_termresize();
64 #endif
65 #if XLIB || ALLEGRO
66 	if (tm > 80 && in_xterm && game && game_running &&
67 	    !TWOPLAYER_MODE && !xterm_hasfocus())
68 		return STARTBTN;
69 #endif
70 	for (i = inpselect_dev(tm); i < NUM_INPUTDEVS && !keypress; i++) {
71 		if (i+1 == ignore_dev)
72 			continue;
73 		switch (i) {
74 		case 0:
75 			keypress = kb_getpress(flags);
76 			break;
77 #if JOYSTICK
78 		case 1:
79 		case 2:
80 			keypress = js_getpress(i-1, flags);
81 			break;
82 #endif
83 #if SOCKET
84 		case 3:
85 			keypress = sock_getkeypress(flags);
86 			if (ignore_dev)
87 				return 0;
88 #endif
89 		}
90 	}
91 	if (keypress)
92 		keypress |= player_flag(i-1, flags);
93 	return keypress;
94 }
95 
getkeypress(int tm,int flags)96 int getkeypress(int tm, int flags)
97 {
98 	int t = gettm(0);
99 	int keypress;
100 	if (socket_fd > -1)
101 		flags |= SINGLE_PL;
102 	while (1) {
103 		if (tm <= 0)
104 			return 0;
105 		keypress = getkeypress_select(tm, flags);
106 #if JOYSTICK
107 		if (!keypress)
108 			keypress = getautorepeat(flags);
109 #endif
110 		if (keypress)
111 			break;
112 		if (gettm(t) == t)
113 			sleep_msec(1);
114 		tm -= gettm(t)-t;
115 		t = gettm(0);
116 #ifdef ALLEGRO
117 		if (close_button_pressed)
118 			exit(0);
119 #endif
120 	}
121 	return keypress;
122 }
123 
getkeypress_block(int flags)124 int getkeypress_block(int flags)
125 {
126 	int keypress;
127 	while (1) {
128 #if TTY_SOCKET && !NO_MENU
129 		if (!(flags & 1) && (invit || checkinvit()))
130 			return ESC;
131 #endif
132 		keypress = getkeypress(1000, flags);
133 		if (keypress)
134 			break;
135 		sleep_msec(55);
136 	}
137 	return keypress;
138 }
139 
spawn_discard_drops(int pl)140 void spawn_discard_drops(int pl)
141 {
142 	int i = 0;
143 	if (pl==2) {
144 		i = 1;
145 		if (socket_fd > -1) {
146 			spawn_tm[1] = 0;
147 			return;
148 		}
149 	}
150 	spawn_tm[i] = gettm(0);
151 #ifdef ALLEGRO
152 	kb_reset_drop(pl);
153 #endif
154 #ifdef JOYSTICK
155 	if (!num_joyst)
156 		return;
157 	i = !js_pressed(0);
158 	if (pl==2 && inputdevs_player[i+1] != 2) {
159 		if (i || inputdevs_player[2] != 2)
160 			return;
161 		i = 1;
162 	}
163 	if (js_pressed(i))
164 		js_reset_drop(i);
165 #endif
166 }
167 
key_is_valid(unsigned c,int keypr)168 static int key_is_valid(unsigned c, int keypr)
169 {
170 	return c == (keypr & 0x7F) ||
171 		c > MVRIGHT &&
172 		(c > MVDOWN || keypr & IN_GAME) &&
173 		c != STARTBTN && c != '\t';
174 }
175 
setkeymapping_keybd(int keypr)176 static int setkeymapping_keybd(int keypr)
177 {
178 	unsigned char s[5] = "";
179 	unsigned c;
180 	kb_no_autorep = 1;
181 	while (!kb_readkey(s)) {
182 		if (c = getkeypress_select(100, SINGLE_PL))
183 			return c;
184 		sleep_msec(55);
185 	}
186 	c = !s[1] ? s[0] : ESC+1;
187 	if (c == ESC)
188 		kb_rmmapping(keypr);
189 	else {
190 		if (!key_is_valid(c, keypr))
191 			return c;
192 		if (c == MVUP && (keypr & (63 | IN_GAME)) == MVUP) {
193 			c = kb_getchrfor(keypr);
194 			if (c == MVUP)
195 				return MVUP;
196 		}
197 		kb_setmapping(s, keypr);
198 		if (!c && (!(keypr & PLAYER_2) || inputdevs_player[0]==2))
199 			return MVUP;
200 	}
201 	return MVDOWN;
202 }
203 
204 #if JOYSTICK
setkeymapping_js(int i,int keypr)205 static int setkeymapping_js(int i, int keypr)
206 {
207 	int b, b2;
208 	while (!(b = js_readbtn(i))) {
209 		if (inputdevs_fd[i+1] == -1)
210 			return STARTBTN;
211 		if (b = getkeypress_select(100, SINGLE_PL)) {
212 			if (b == ESC) {
213 				js_rmmapping(i, keypr);
214 				return MVDOWN;
215 			}
216 			return b;
217 		}
218 		sleep_msec(55);
219 	}
220 	b2 = js_readbtn(i);
221 	if (b > b2 && b2)
222 		b = b2;
223 	if (!key_is_valid(b, keypr))
224 		return b;
225 	if (b == MVUP && keypr == MVUP && js_getbtnfor(i, MVUP) == MVUP)
226 		return MVUP;
227 	js_setmapping(i, b, keypr);
228 	return MVDOWN;
229 }
230 #endif
231 
setkeymapping(int dev,int keypr)232 int setkeymapping(int dev, int keypr)
233 {
234 	ignore_dev = dev+1;
235 #if JOYSTICK
236 	if (dev > 0)
237 		keypr = setkeymapping_js(dev-1, keypr);
238 	else
239 #endif
240 		keypr = setkeymapping_keybd(keypr);
241 	kb_no_autorep = 0;
242 	ignore_dev = 0;
243 	return keypr;
244 }
245 
getkeyfor_str_keybd(int keypr,int * c)246 static const char *getkeyfor_str_keybd(int keypr, int *c)
247 {
248 	static unsigned char bytes[7];
249 	const char *name;
250 	int n = kb_getkeyfor(keypr, bytes, 1);
251 	if (!n)
252 		return "";
253 	name = kb_keyname(bytes, n);
254 	if (name)
255 		return name;
256 	bytes[n] = '\0';
257 	if (n==1)  {
258 		n = bytes[0];
259 		if (n ==' ')
260 			strcpy((char *) bytes, "SPACE");
261 		else if (n == DEL)
262 			strcpy((char *) bytes, "DEL");
263 		else if (n < ' ') {
264 			if (n < 10) {
265 				*c = n;
266 				return NULL;
267 			}
268 			sprintf((char *) bytes, "%d", n);
269 		}
270 	}
271 	return (const char *) bytes;
272 }
273 
getkeyfor_str(int dev,int keypr)274 const char *getkeyfor_str(int dev, int keypr)
275 {
276 	const char *name;
277 	int c = 0;
278 #if JOYSTICK
279 	if (dev) {
280 		c = js_getbtnfor(dev-1, keypr);
281 		name = js_btnname(c);
282 	} else
283 #endif
284 		name = getkeyfor_str_keybd(keypr, &c);
285 	if (name)
286 		return name;
287 	if (c > 0 && c < 10)
288 		return input_chr9[c-1];
289 	return "";
290 }
291 
dropsafe(int i)292 static int dropsafe(int i)
293 {
294 	int t = spawn_tm[i];
295 	if (t && gettm(t)-t < DAS_DELAY)
296 		return 1;
297 	spawn_tm[i] = 0;
298 	return 0;
299 }
300 
processkey_ingame(int key,int flags)301 int processkey_ingame(int key, int flags)
302 {
303 	static int discard_count;
304 	struct player *plr;
305 	int i = TWOPLAYER_MODE && key & PLAYER_2;
306 	int safe;
307 	switch (key & 0x7F) {
308 	case ESC:
309 	case '\b':
310 		game->state = 0;
311 		return -2;
312 	case 'q':
313 		exit(0);
314 	case STARTBTN:
315 	case 'p':
316 		if (flags & NO_PAUSE || !game_running || TWOPLAYER_MODE)
317 			break;
318 		i = pausegame();
319 		textgfx_flags &= ~LOST_FOCUS;
320 		return i;
321 	}
322 	if (flags & DISCARD_MOVES) {
323 		if (++discard_count > 5)
324 			kb_flushinp();
325 		return -1;
326 	}
327 	discard_count = 0;
328 	plr = game->player+i;
329 	safe = dropsafe(i);
330 	key &= 0x7F;
331 	if (!(flags & DISCARD_DROPS)) {
332 		switch (key) {
333 		case HARDDROP:
334 			if (socket_fd > -1 && !i) {
335 				sock_sendpiece(plr);
336 				if (harddrop(plr, safe) == -1)
337 					return -1;
338 				sock_sendbyte(HARDDROP);
339 				return 0;
340 			}
341 			return harddrop(plr, safe);
342 		case MVDOWN:
343 			if (!TWOPLAYER_MODE)
344 				return softdrop(softdrop_speed, safe);
345 			if (!movedown(plr, 1))
346 				return 0;
347 			if (socket_fd > -1 && !i)
348 				sock_sendbyte(MVDOWN);
349 			return 1;
350 		}
351 	}
352 	switch (key) {
353 	case MVLEFT:
354 		moveleft(plr);
355 		break;
356 	case MVRIGHT:
357 		moveright(plr);
358 		break;
359 	case MVUP:
360 		rotate(plr, plr->rotationsys & ROT_CLOCKWISE);
361 		break;
362 	case A_BTN:
363 		rotate(plr, 1);
364 		break;
365 	case B_BTN:
366 		rotate(plr, 0);
367 		break;
368 	default:
369 		return -1;
370 	}
371 	if (socket_fd > -1 && !i)
372 		sock_sendbyte(key);
373 	upd_screen(1+i);
374 	return 1;
375 }
376