cleanups, savestates, input (combos), menu
[fceu.git] / drivers / gp2x / input.c
CommitLineData
35868d35 1/* FCE Ultra - NES/Famicom Emulator
35868d35 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
971a1d07 18#include "../../state.h"
19#include "../../general.h"
35868d35 20
21/* UsrInputType[] is user-specified. InputType[] is current
971a1d07 22 (game loading can override user settings)
35868d35 23*/
24static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
35868d35 25static int UsrInputTypeFC={SI_NONE};
971a1d07 26
27static int InputType[2];
35868d35 28static int InputTypeFC;
29
30static uint32 JSreturn;
35868d35 31
32static int powerpadsc[2][12];
33static int powerpadside=0;
34
35868d35 35static uint32 MouseData[3];
36static uint8 fkbkeys[0x48];
35868d35 37
971a1d07 38static uint32 combo_acts = 0, combo_keys = 0;
39static uint32 prev_emu_acts = 0;
35868d35 40
13624c8f 41
35868d35 42static void setsoundvol(int soundvolume)
43{
971a1d07 44 int soundvolIndex;
45 static char soundvolmeter[24];
46
47 // draw on screen :D
48 gp2x_sound_volume(soundvolume, soundvolume);
49 int meterval=soundvolume/5;
50 for (soundvolIndex = 0; soundvolIndex < 20; soundvolIndex++)
51 {
52 if (soundvolIndex < meterval)
53 {
54 soundvolmeter[soundvolIndex]='*';
55 }
56 else
57 {
58 soundvolmeter[soundvolIndex]='_';
59 }
60 }
61 soundvolmeter[20]=0;
62 FCEU_DispMessage("|%s|", soundvolmeter);
35868d35 63}
13624c8f 64
65
971a1d07 66static void do_emu_acts(uint32 acts)
67{
68 uint32 actsc = acts;
69 acts &= acts ^ prev_emu_acts;
70 prev_emu_acts = actsc;
71
72 if (acts & (3 << 30))
73 {
74 if (acts & (1 << 30))
75 {
76 FCEUI_LoadState();
77 }
78 else
79 {
80 FCEUI_SaveState();
81 }
82 }
83 else if (acts & (1 << 29))
84 {
85 FILE *st;
86 char *fname;
87
88 CurrentState++;
89 if (CurrentState > 9) CurrentState = 0;
90
91 fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0);
92 st=fopen(fname,"rb");
93 free(fname);
94 FCEU_DispMessage("[%s] State Slot %i", st ? "USED" : "FREE", CurrentState);
95 if (st) fclose(st);
96 }
97}
98
13624c8f 99
100void FCEUD_UpdateInput(void)
35868d35 101{
b547bda7 102 static int volpushed_frames = 0;
989672f4 103 static int turbo_rate_cnt_a = 0, turbo_rate_cnt_b = 0;
b547bda7 104 unsigned long keys = gp2x_joystick_read(0);
971a1d07 105 uint32 all_acts = 0;
b547bda7 106 int i;
107
108 #define down(b) (keys & GP2X_##b)
109 if ((down(VOL_DOWN) && down(VOL_UP)) || (keys & (GP2X_L|GP2X_L|GP2X_START)) == (GP2X_L|GP2X_L|GP2X_START))
35868d35 110 {
b547bda7 111 Exit = 1;
b547bda7 112 return;
35868d35 113 }
b547bda7 114 else if (down(VOL_UP))
35868d35 115 {
b547bda7 116 /* wait for at least 10 updates, because user may be just trying to enter menu */
117 if (volpushed_frames++ > 10) {
118 soundvol++;
119 if (soundvol > 100) soundvol=100;
120 //FCEUI_SetSoundVolume(soundvol);
121 setsoundvol(soundvol);
122 }
35868d35 123 }
b547bda7 124 else if (down(VOL_DOWN))
35868d35 125 {
b547bda7 126 if (volpushed_frames++ > 10) {
127 soundvol-=1;
128 if (soundvol < 0) soundvol=0;
129 //FCEUI_SetSoundVolume(soundvol);
130 setsoundvol(soundvol);
131 }
132 }
133 else
134 {
135 volpushed_frames = 0;
35868d35 136 }
137
35868d35 138
971a1d07 139 JSreturn = 0; // RLDU SEBA
140
b547bda7 141 for (i = 0; i < 32; i++)
142 {
971a1d07 143 if (keys & (1 << i))
144 {
145 uint32 acts, u = 32;
146 acts = Settings.KeyBinds[i];
b547bda7 147 if (!acts) continue;
971a1d07 148 if ((1 << i) & combo_keys)
149 {
150 // combo key detected, try to find if other is pressed
151 for (u = i+1; u < 32; u++)
152 {
153 if ((keys & (1 << u)) && (Settings.KeyBinds[u] & acts))
154 {
155 keys &= ~(1 << u);
156 break;
157 }
158 }
989672f4 159 }
971a1d07 160 if (u != 32) acts &= combo_acts; // other combo key pressed
161 else acts &= ~combo_acts;
162 all_acts |= acts;
b547bda7 163 }
164 }
35868d35 165
971a1d07 166 JSreturn |= all_acts & 0xff;
167 if (all_acts & 0x100) { // A turbo
168 turbo_rate_cnt_a += Settings.turbo_rate_add;
169 JSreturn |= (turbo_rate_cnt_a >> 24) & 1;
170 }
171 if (all_acts & 0x200) { // B turbo
172 turbo_rate_cnt_b += Settings.turbo_rate_add;
173 JSreturn |= (turbo_rate_cnt_b >> 23) & 2;
174 }
35868d35 175
971a1d07 176 do_emu_acts(all_acts);
35868d35 177
13624c8f 178
971a1d07 179 //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
13624c8f 180
181 // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8);
182 // TODO: make these bindable, use new interface
971a1d07 183 /*
13624c8f 184 if(gametype==GIT_FDS)
185 {
13624c8f 186 if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH)))
187 {
188 DriverInterface(DES_FDSSELECT,0);
189 }
190 else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L)))
191 {
192 DriverInterface(DES_FDSINSERT,0);
193 }
194 else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R)))
195 {
196 DriverInterface(DES_FDSEJECT,0);
197 }
198 }
199 return;
971a1d07 200 */
35868d35 201}
35868d35 202
203
204static void InitOtherInput(void)
205{
206
207 void *InputDPtr;
208
209 int t;
210 int x;
211 int attrib;
212
213 for(t=0,x=0;x<2;x++)
214 {
215 attrib=0;
216 InputDPtr=0;
217 switch(InputType[x])
218 {
219 //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
220 case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
221 case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
222 case SI_ZAPPER:InputDPtr=MouseData;
223 t|=1;
224 attrib=1;
225 break;
226 }
227 FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
228 }
229
230 attrib=0;
231 InputDPtr=0;
232 switch(InputTypeFC)
233 {
234 case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
235 case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
236 case SIFC_FKB:InputDPtr=fkbkeys;break;
237 }
238
239 FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
240 FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
241
971a1d07 242 inited|=16;
243}
244
245
246static void PrepareOtherInput(void)
247{
248 uint32 act, key, seen_acts;
249
250 combo_acts = combo_keys = prev_emu_acts = seen_acts = 0;
251
252 // find combo_acts
253 for (act = 1; act; act <<= 1)
254 {
255 for (key = 1; key < 32; key++)
256 {
257 if (Settings.KeyBinds[key] & act)
258 {
259 if (seen_acts & act) combo_acts |= act;
260 else seen_acts |= act;
261 }
262 }
263 }
264
265 // find combo_keys
266 for (act = 1; act; act <<= 1)
267 {
268 for (key = 0; key < 32; key++)
269 {
270 if (Settings.KeyBinds[key] & combo_acts)
271 {
272 combo_keys |= 1 << key;
273 }
274 }
275 }
276
277 printf("generated combo_acts: %08x, combo_keys: %08x\n", combo_acts, combo_keys);
35868d35 278}
971a1d07 279