1 #include <stdio.h>
2 #include <string.h>
3 #include "joystick.h"
4 #include "input.h"
5 #include "../timer.h"
6 
7 int num_joyst = 0;
8 int js_dead = 1;
9 
10 static struct btns {
11 	char menu_btns[7];
12 	char ingame_btns[5];
13 } btns_joyst[2];
14 
getbtn(int b,const char * p,int n)15 static const char *getbtn(int b, const char *p, int n)
16 {
17 	while (n) {
18 		if (*p == b)
19 			return p;
20 		p++;
21 		n--;
22 	}
23 	return (char *) 0;
24 }
25 
getbtnfor(struct btns * js,int keypress)26 static char *getbtnfor(struct btns *js, int keypress)
27 {
28 	char *btns;
29 	int i;
30 	if (keypress & IN_GAME) {
31 		btns = js->ingame_btns;
32 		if (keypress == (HARDDROP | IN_GAME))
33 			i = 4;
34 		else
35 			i = (keypress & 7)-MVUP;
36 	} else {
37 		btns = js->menu_btns;
38 		if (keypress == STARTBTN)
39 			i = 6;
40 		else
41 			i = (keypress & 7)-MVLEFT;
42 	}
43 	return btns+i;
44 }
45 
transl_btn(struct btns * js,int b,int flags)46 static int transl_btn(struct btns *js, int b, int flags)
47 {
48 	const char *btns, *p;
49 	if (flags & IN_GAME) {
50 		btns = js->ingame_btns;
51 		if (p = getbtn(b, btns, 5))
52 			return p==btns+4 ? HARDDROP : MVUP+p-btns;
53 	}
54 	btns = js->menu_btns;
55 	if (p = getbtn(b, btns, 7))
56 		return p==btns+6 ? STARTBTN : MVLEFT+p-btns;
57 	return 0;
58 }
59 
test_up_rotate(struct btns * js,int b,int keypr)60 static int test_up_rotate(struct btns *js, int b, int keypr)
61 {
62 	if (b==MVUP && keypr==MVUP) {
63 		b = *getbtnfor(js, MVUP | IN_GAME);
64 		if (b != MVUP)
65 			return 0;
66 	}
67 	return 1;
68 }
69 
js_getpress(int i,int flags)70 int js_getpress(int i, int flags)
71 {
72 	struct btns *js = btns_joyst+i;
73 	int b, ret;
74 	int ingame = flags & IN_GAME;
75 next:	b = js_readbtn(i);
76 	if (!b)
77 		return 0;
78 	js_dead = 0;
79 	ret = transl_btn(js, b & 0x7F, flags);
80 	if (!ret) {
81 		if (ingame)
82 			goto next;
83 		return '.';
84 	}
85 	if (b > MVDOWN && (ret <= MVRIGHT || !ingame && ret <= MVDOWN)) {
86 		js_pressbtn(i, b);
87 		js_releasebtn(i, *getbtnfor(js, (ret%4)%2 ? ret+1 : ret-1));
88 	} else if (ingame) {
89 		if (!test_up_rotate(js, b, ret))
90 			goto next;
91 	} else if (autorep_a_b_btns && b > MVDOWN &&
92 		   (ret == A_BTN || ret == B_BTN))
93 		js_pressbtn(i, b);
94 	return ret;
95 }
96 
js_getautorepeat(int i,int flags)97 static int js_getautorepeat(int i, int flags)
98 {
99 	struct btns *js = btns_joyst+i;
100 	short *tm;
101 	int b = js_autorep(i, &tm);
102 	if (!b)
103 		return 0;
104 	i = transl_btn(js, b, flags);
105 	if (flags & IN_GAME) {
106 		if (i==MVDOWN)
107 			*tm -= DAS_DELAY/2;
108 		else if (i > MVRIGHT)
109 			return 0;
110 	}
111 	return i;
112 }
113 
getautorepeat(int flags)114 int getautorepeat(int flags)
115 {
116 	int keypress = 0;
117 	int i = 0;
118 	while (i < num_joyst) {
119 		if (js_pressed(i)) {
120 			keypress = js_getautorepeat(i, flags);
121 			break;
122 		}
123 		i++;
124 	}
125 	i++;
126 	if (keypress && inputdevs_player[i] && !(flags & SINGLE_PL))
127 		keypress |= inputdevs_player[i]==1 ? PLAYER_1 : PLAYER_2;
128 	return keypress;
129 }
130 
test_autorep_tm(short * tm)131 int test_autorep_tm(short *tm)
132 {
133 	int t = *tm;
134 	t = gettm(t)-t;
135 	if (t >= DAS_INITIAL_DELAY) {
136 		*tm = gettm(0)-t+DAS_DELAY+10000;
137 		return 1;
138 	}
139 	return 0;
140 }
141 
rmbtn(struct btns * js,int b,int keypress)142 static void rmbtn(struct btns *js, int b, int keypress)
143 {
144 	int flags = keypress & IN_GAME;
145 	int old = transl_btn(js, b, flags);
146 	if (old && old != (keypress & 63)) {
147 		if (flags) {
148 			old |= flags;
149 			if (b != *getbtnfor(js, old))
150 				return;
151 		}
152 		js_rmmapping(js!=btns_joyst, old);
153 	}
154 }
155 
js_setmapping(int i,int btn,int keypress)156 void js_setmapping(int i, int btn, int keypress)
157 {
158 	struct btns *js = btns_joyst+i;
159 	char *b;
160 	keypress &= 63 | IN_GAME;
161 	rmbtn(js, btn, keypress);
162 	b = getbtnfor(js, keypress);
163 	if (*b && !(keypress & IN_GAME) && keypress >= MVUP) {
164 		keypress |= IN_GAME;
165 		if (*b == *getbtnfor(js, keypress))
166 			js_setmapping(i, btn, keypress);
167 	}
168 	*b = btn;
169 }
170 
js_getbtnfor(int i,int keypress)171 int js_getbtnfor(int i, int keypress)
172 {
173 	struct btns *js = btns_joyst+i;
174 	int b;
175 	keypress &= 63 | IN_GAME;
176 	b = *getbtnfor(js, keypress);
177 	if (b)
178 		return b;
179 	if ((keypress & 63) == HARDDROP || keypress == (MVUP | IN_GAME))
180 		return 0;
181 	if (keypress & IN_GAME) {
182 		b = js_getbtnfor(i, keypress ^ IN_GAME);
183 		if (!b || getbtn(b, js->ingame_btns, 5))
184 			return 0;
185 		return b;
186 	}
187 	return 0;
188 }
189 
js_rmmapping(int i,int keypress)190 void js_rmmapping(int i, int keypress)
191 {
192 	char *b = getbtnfor(btns_joyst+i, keypress & (63 | IN_GAME));
193 	if (*b)
194 		*b = 0;
195 }
196 
js_setifnull(int i,int btn,int keypress)197 void js_setifnull(int i, int btn, int keypress)
198 {
199 	if (!js_getbtnfor(i, keypress))
200 		js_setmapping(i, btn, keypress);
201 }
202 
js_default_buttons(int i)203 void js_default_buttons(int i)
204 {
205 	char *btns = btns_joyst[i].menu_btns;
206 	char defaults[6] = {MVLEFT, MVRIGHT, MVUP, MVDOWN, '0', '1'};
207 	if (memchr(btns, '0', 6))
208 		defaults[4] = 0;
209 	if (memchr(btns, '1', 6))
210 		defaults[5] = 0;
211 	for (i=0; i < 6; i++)
212 		if (!btns[i])
213 			btns[i] = defaults[i];
214 }
215 
js_btnname(int btn)216 const char *js_btnname(int btn)
217 {
218 	static char name[4];
219 	if (btn < '0')
220 		return (const char *) 0;
221 	btn -= '0';
222 	if (btn < 26) {
223 		name[0] = btn+'A';
224 		name[1] = '\0';
225 	} else
226 		sprintf(name, "%d", btn);
227 	return name;
228 }
229