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