daadc34a3af0df47c2c815154ce88b8f79dab7cb
[fceu.git] / drivers / gp2x / input.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 #include "../../state.h"
19 #include "../../general.h"
20 #include "../../input.h"
21
22 /* UsrInputType[] is user-specified.  InputType[] is current
23        (game loading can override user settings)
24 */
25 static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
26 static int UsrInputTypeFC={SI_NONE};
27
28 static int InputType[2];
29 static int InputTypeFC;
30
31 static uint32 JSreturn;
32
33 static int powerpadsc[2][12];
34 static int powerpadside=0;
35
36 static uint32 MouseData[3];
37 static uint8 fkbkeys[0x48];
38
39 static uint32 combo_acts = 0, combo_keys = 0;
40 static uint32 prev_emu_acts = 0;
41
42
43 static void setsoundvol(int soundvolume)
44 {
45         int soundvolIndex;
46         static char soundvolmeter[24];
47
48         // draw on screen :D
49         gp2x_sound_volume(soundvolume, soundvolume);
50         int meterval=soundvolume/5;
51         for (soundvolIndex = 0; soundvolIndex < 20; soundvolIndex++)
52         {
53                 if (soundvolIndex < meterval)
54                 {
55                         soundvolmeter[soundvolIndex]='*';
56                 }
57                 else
58                 {
59                         soundvolmeter[soundvolIndex]='_';
60                 }
61         }
62         soundvolmeter[20]=0;
63         FCEU_DispMessage("|%s|", soundvolmeter);
64 }
65
66
67 static void do_emu_acts(uint32 acts)
68 {
69         uint32 actsc = acts;
70         acts &= acts ^ prev_emu_acts;
71         prev_emu_acts = actsc;
72
73         if (acts & (3 << 30))
74         {
75                 if (acts & (1 << 30))
76                 {
77                         FCEUI_LoadState();
78                 }
79                 else
80                 {
81                         FCEUI_SaveState();
82                 }
83         }
84         else if (acts & (3 << 28)) // state slot next/prev
85         {
86                 FILE *st;
87                 char *fname;
88
89                 CurrentState += (acts & (1 << 29)) ? 1 :  -1;
90                 if (CurrentState > 9) CurrentState = 0;
91                 if (CurrentState < 0) CurrentState = 9;
92
93                 fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0);
94                 st=fopen(fname,"rb");
95                 free(fname);
96                 FCEU_DispMessage("[%s] State Slot %i", st ? "USED" : "FREE", CurrentState);
97                 if (st) fclose(st);
98         }
99         else if (acts & (1 << 27)) // FDS insert/eject
100         {
101                 if(FCEUGameInfo.type == GIT_FDS)
102                         FCEU_DoSimpleCommand(FCEUNPCMD_FDSINSERT);
103         }
104         else if (acts & (1 << 26)) // FDS select
105         {
106                 if(FCEUGameInfo.type == GIT_FDS)
107                         FCEU_DoSimpleCommand(FCEUNPCMD_FDSSELECT);
108         }
109         else if (acts & (1 << 25)) // VS Unisystem insert coin
110         {
111                 if(FCEUGameInfo.type == GIT_VSUNI)
112                         FCEU_DoSimpleCommand(FCEUNPCMD_VSUNICOIN);
113         }
114 }
115
116
117 #define down(b) (keys & GP2X_##b)
118 static void do_fake_mouse(unsigned long keys)
119 {
120         static int x=256/2, y=240/2;
121         int speed = 3;
122
123         if (down(A)) speed = 1;
124         if (down(Y)) speed = 5;
125
126         if (down(LEFT))
127         {
128                 x -= speed;
129                 if (x < 0) x = 0;
130         }
131         else if (down(RIGHT))
132         {
133                 x += speed;
134                 if (x > 255) x = 255;
135         }
136
137         if (down(UP))
138         {
139                 y -= speed;
140                 if (y < 0) y = 0;
141         }
142         else if (down(DOWN))
143         {
144                 y += speed;
145                 if (y > 239) y = 239;
146         }
147
148         MouseData[0] = x;
149         MouseData[1] = y;
150         MouseData[2] = 0;
151         if (down(B)) MouseData[2] |= 1;
152         if (down(X)) MouseData[2] |= 2;
153 }
154
155
156 void FCEUD_UpdateInput(void)
157 {
158         static int volpushed_frames = 0;
159         static int turbo_rate_cnt_a = 0, turbo_rate_cnt_b = 0;
160         unsigned long keys = gp2x_joystick_read(0);
161         uint32 all_acts = 0;
162         int i;
163
164         if ((down(VOL_DOWN) && down(VOL_UP)) || (keys & (GP2X_L|GP2X_L|GP2X_START)) == (GP2X_L|GP2X_L|GP2X_START))
165         {
166                 Exit = 1;
167                 return;
168         }
169         else if (down(VOL_UP))
170         {
171                 /* wait for at least 10 updates, because user may be just trying to enter menu */
172                 if (volpushed_frames++ > 10) {
173                         soundvol++;
174                         if (soundvol > 100) soundvol=100;
175                         //FCEUI_SetSoundVolume(soundvol);
176                         setsoundvol(soundvol);
177                 }
178         }
179         else if (down(VOL_DOWN))
180         {
181                 if (volpushed_frames++ > 10) {
182                         soundvol-=1;
183                         if (soundvol < 0) soundvol=0;
184                         //FCEUI_SetSoundVolume(soundvol);
185                         setsoundvol(soundvol);
186                 }
187         }
188         else
189         {
190                 volpushed_frames = 0;
191         }
192
193         JSreturn = 0; // RLDU SEBA
194
195         if (InputType[1] != SI_GAMEPAD)
196         {
197                 /* try to feed fake mouse there */
198                 do_fake_mouse(keys);
199         }
200
201         for (i = 0; i < 32; i++)
202         {
203                 if (keys & (1 << i))
204                 {
205                         uint32 acts, u = 32;
206                         acts = Settings.KeyBinds[i];
207                         if (!acts) continue;
208                         if ((1 << i) & combo_keys)
209                         {
210                                 // combo key detected, try to find if other is pressed
211                                 for (u = i+1; u < 32; u++)
212                                 {
213                                         if ((keys & (1 << u)) && (Settings.KeyBinds[u] & acts))
214                                         {
215                                                 keys &= ~(1 << u);
216                                                 break;
217                                         }
218                                 }
219                         }
220                         if (u != 32) acts &=  combo_acts; // other combo key pressed
221                         else         acts &= ~combo_acts;
222                         all_acts |= acts;
223                 }
224         }
225
226         JSreturn |= all_acts & 0xff;
227         if (all_acts & 0x100) {         // A turbo
228                 turbo_rate_cnt_a += Settings.turbo_rate_add;
229                 JSreturn |= (turbo_rate_cnt_a >> 24) & 1;
230         }
231         if (all_acts & 0x200) {         // B turbo
232                 turbo_rate_cnt_b += Settings.turbo_rate_add;
233                 JSreturn |= (turbo_rate_cnt_b >> 23) & 2;
234         }
235
236         do_emu_acts(all_acts);
237 }
238
239
240 static void InitOtherInput(void)
241 {
242
243    void *InputDPtr;
244
245    int t;
246    int x;
247    int attrib;
248
249    printf("InitOtherInput: InputType[0]: %i, InputType[1]: %i, InputTypeFC: %i\n",
250         InputType[0], InputType[1], InputTypeFC);
251
252    for(t=0,x=0;x<2;x++)
253    {
254     attrib=0;
255     InputDPtr=0;
256     switch(InputType[x])
257     {
258       //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
259      case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
260      case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
261      case SI_ZAPPER:InputDPtr=MouseData;
262                                 t|=1;
263                                 attrib=1;
264                                 break;
265     }
266     FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
267    }
268
269    attrib=0;
270    InputDPtr=0;
271    switch(InputTypeFC)
272    {
273     case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
274     case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
275     case SIFC_FKB:InputDPtr=fkbkeys;break;
276    }
277
278    FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
279    FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
280
281    inited|=16;
282 }
283
284
285 static void PrepareOtherInput(void)
286 {
287         uint32 act, key, seen_acts;
288
289         combo_acts = combo_keys = prev_emu_acts = seen_acts = 0;
290
291         // find combo_acts
292         for (act = 1; act; act <<= 1)
293         {
294                 for (key = 1; key < 32; key++)
295                 {
296                         if (Settings.KeyBinds[key] & act)
297                         {
298                                 if (seen_acts & act) combo_acts |= act;
299                                 else seen_acts |= act;
300                         }
301                 }
302         }
303
304         // find combo_keys
305         for (act = 1; act; act <<= 1)
306         {
307                 for (key = 0; key < 32; key++)
308                 {
309                         if (Settings.KeyBinds[key] & combo_acts)
310                         {
311                                 combo_keys |= 1 << key;
312                         }
313                 }
314         }
315
316         printf("generated combo_acts: %08x, combo_keys: %08x\n", combo_acts, combo_keys);
317 }
318