merged ppu code, added input+zapper, FDS/VS insert in menu
[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                 FCEU_DoSimpleCommand(FCEUNPCMD_FDSINSERT);
102         }
103         else if (acts & (1 << 26)) // FDS select
104         {
105                 FCEU_DoSimpleCommand(FCEUNPCMD_FDSSELECT);
106         }
107         else if (acts & (1 << 25)) // VS Unisystem insert coin
108         {
109                 FCEU_DoSimpleCommand(FCEUNPCMD_VSUNICOIN);
110         }
111 }
112
113
114 #define down(b) (keys & GP2X_##b)
115 static void do_fake_mouse(unsigned long keys)
116 {
117         static int x=0, y=0;
118         int speed = 3;
119
120         if (down(A)) speed = 1;
121         if (down(Y)) speed = 5;
122
123         if (down(LEFT))
124         {
125                 x -= speed;
126                 if (x < 0) x = 0;
127         }
128         else if (down(RIGHT))
129         {
130                 x += speed;
131                 if (x > 255) x = 255;
132         }
133
134         if (down(UP))
135         {
136                 y -= speed;
137                 if (y < 0) y = 0;
138         }
139         else if (down(DOWN))
140         {
141                 y += speed;
142                 if (y > 239) y = 239;
143         }
144
145         MouseData[0] = x;
146         MouseData[1] = y;
147         MouseData[2] = 0;
148         if (down(B)) MouseData[2] |= 1;
149         if (down(X)) MouseData[2] |= 2;
150 }
151
152
153 void FCEUD_UpdateInput(void)
154 {
155         static int volpushed_frames = 0;
156         static int turbo_rate_cnt_a = 0, turbo_rate_cnt_b = 0;
157         unsigned long keys = gp2x_joystick_read(0);
158         uint32 all_acts = 0;
159         int i;
160
161         if ((down(VOL_DOWN) && down(VOL_UP)) || (keys & (GP2X_L|GP2X_L|GP2X_START)) == (GP2X_L|GP2X_L|GP2X_START))
162         {
163                 Exit = 1;
164                 return;
165         }
166         else if (down(VOL_UP))
167         {
168                 /* wait for at least 10 updates, because user may be just trying to enter menu */
169                 if (volpushed_frames++ > 10) {
170                         soundvol++;
171                         if (soundvol > 100) soundvol=100;
172                         //FCEUI_SetSoundVolume(soundvol);
173                         setsoundvol(soundvol);
174                 }
175         }
176         else if (down(VOL_DOWN))
177         {
178                 if (volpushed_frames++ > 10) {
179                         soundvol-=1;
180                         if (soundvol < 0) soundvol=0;
181                         //FCEUI_SetSoundVolume(soundvol);
182                         setsoundvol(soundvol);
183                 }
184         }
185         else
186         {
187                 volpushed_frames = 0;
188         }
189
190         JSreturn = 0; // RLDU SEBA
191
192         if (InputType[1] != SI_GAMEPAD)
193         {
194                 /* try to feed fake mouse there */
195                 do_fake_mouse(keys);
196         }
197
198         for (i = 0; i < 32; i++)
199         {
200                 if (keys & (1 << i))
201                 {
202                         uint32 acts, u = 32;
203                         acts = Settings.KeyBinds[i];
204                         if (!acts) continue;
205                         if ((1 << i) & combo_keys)
206                         {
207                                 // combo key detected, try to find if other is pressed
208                                 for (u = i+1; u < 32; u++)
209                                 {
210                                         if ((keys & (1 << u)) && (Settings.KeyBinds[u] & acts))
211                                         {
212                                                 keys &= ~(1 << u);
213                                                 break;
214                                         }
215                                 }
216                         }
217                         if (u != 32) acts &=  combo_acts; // other combo key pressed
218                         else         acts &= ~combo_acts;
219                         all_acts |= acts;
220                 }
221         }
222
223         JSreturn |= all_acts & 0xff;
224         if (all_acts & 0x100) {         // A turbo
225                 turbo_rate_cnt_a += Settings.turbo_rate_add;
226                 JSreturn |= (turbo_rate_cnt_a >> 24) & 1;
227         }
228         if (all_acts & 0x200) {         // B turbo
229                 turbo_rate_cnt_b += Settings.turbo_rate_add;
230                 JSreturn |= (turbo_rate_cnt_b >> 23) & 2;
231         }
232
233         do_emu_acts(all_acts);
234 }
235
236
237 static void InitOtherInput(void)
238 {
239
240    void *InputDPtr;
241
242    int t;
243    int x;
244    int attrib;
245
246    printf("InitOtherInput: InputType[0]: %i, InputType[1]: %i, InputTypeFC: %i\n",
247         InputType[0], InputType[1], InputTypeFC);
248
249    for(t=0,x=0;x<2;x++)
250    {
251     attrib=0;
252     InputDPtr=0;
253     switch(InputType[x])
254     {
255       //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
256      case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
257      case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
258      case SI_ZAPPER:InputDPtr=MouseData;
259                                 t|=1;
260                                 attrib=1;
261                                 break;
262     }
263     FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
264    }
265
266    attrib=0;
267    InputDPtr=0;
268    switch(InputTypeFC)
269    {
270     case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
271     case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
272     case SIFC_FKB:InputDPtr=fkbkeys;break;
273    }
274
275    FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
276    FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
277
278    inited|=16;
279 }
280
281
282 static void PrepareOtherInput(void)
283 {
284         uint32 act, key, seen_acts;
285
286         combo_acts = combo_keys = prev_emu_acts = seen_acts = 0;
287
288         // find combo_acts
289         for (act = 1; act; act <<= 1)
290         {
291                 for (key = 1; key < 32; key++)
292                 {
293                         if (Settings.KeyBinds[key] & act)
294                         {
295                                 if (seen_acts & act) combo_acts |= act;
296                                 else seen_acts |= act;
297                         }
298                 }
299         }
300
301         // find combo_keys
302         for (act = 1; act; act <<= 1)
303         {
304                 for (key = 0; key < 32; key++)
305                 {
306                         if (Settings.KeyBinds[key] & combo_acts)
307                         {
308                                 combo_keys |= 1 << key;
309                         }
310                 }
311         }
312
313         printf("generated combo_acts: %08x, combo_keys: %08x\n", combo_acts, combo_keys);
314 }
315