partially working menu
[fceu.git] / drivers / gp2x / input.c
CommitLineData
35868d35 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define JOY_A 1
22#define JOY_B 2
23#define JOY_SELECT 4
24#define JOY_START 8
25#define JOY_UP 0x10
26#define JOY_DOWN 0x20
27#define JOY_LEFT 0x40
28#define JOY_RIGHT 0x80
29
35868d35 30#include "minimal.h"
13624c8f 31
b2b95d2e 32extern uint8 Exit; // exit emu loop
13624c8f 33
35868d35 34extern int swapbuttons;
937bf65b 35extern int scaled_display;
35868d35 36extern int FSkip_setting;
37
35868d35 38
39
40/* UsrInputType[] is user-specified. InputType[] is current
41 (game loading can override user settings)
42*/
43static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
44static int InputType[2];
45
46static int UsrInputTypeFC={SI_NONE};
47static int InputTypeFC;
48
49static uint32 JSreturn;
50int NoWaiting=0;
51
52static int powerpadsc[2][12];
53static int powerpadside=0;
54
55
56static uint32 MouseData[3];
57static uint8 fkbkeys[0x48];
58unsigned long lastpad=0;
59
35868d35 60extern void ResetNES(void);
61extern void CleanSurface(void);
62
63char soundvolmeter[21];
64int soundvolIndex=0;
65int L_count=0;
66int R_count=0;
67extern int CurrentState;
68int TurboFireOff=1;
69int TurboFireTop=0; // 0 is none // 1 is A & X turbo // 2 is Y & B turbo
70int TurboFireBottom=0;
71int turbo_toggle_A=0;
72int turbo_toggle_B=0;
73
13624c8f 74
35868d35 75static void setsoundvol(int soundvolume)
76{
77 //FCEUI_SetSoundVolume(soundvol);
78 // draw on screen :D
79 gp2x_sound_volume(soundvolume, soundvolume);
80 int meterval=soundvolume/5;
81 for (soundvolIndex=0; soundvolIndex < 20; soundvolIndex++)
82 {
83 if (soundvolIndex < meterval)
84 {
85 soundvolmeter[soundvolIndex]='*';
86 }
87 else
88 {
89 soundvolmeter[soundvolIndex]='_';
90 }
91 }
92 soundvolmeter[20]=0;
93 FCEU_DispMessage("|%s|", soundvolmeter);
94}
13624c8f 95
96
97
98void FCEUD_UpdateInput(void)
35868d35 99{
13624c8f 100 long lastpad2=lastpad;
b2b95d2e 101 unsigned long pad=gp2x_joystick_read(1); // TODO: USB joys and stuff
35868d35 102 uint32 JS=0;
103
35868d35 104#define down(b) (pad & GP2X_##b)
105#define last_down(b) (lastpad & GP2X_##b)
106#define L_down (pad & GP2X_L)
107#define R_down (pad & GP2X_R)
108#define last_L_down (lastpad & GP2X_L)
109#define last_R_down (lastpad & GP2X_R)
110#define shift ((pad & GP2X_PUSH) || ((pad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
111#define last_shift ((lastpad & GP2X_PUSH) || ((lastpad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
112
113 if (L_down && R_down && !(pad & GP2X_PUSH) && !(last_R_down && last_L_down))
114 {
115 ResetNES();
116 puts("Reset");
117 goto no_pad;
118 }
119
120 if (down(VOL_UP) && !down(VOL_DOWN))
121 {
122 soundvol+=1;
123 if (soundvol >= 100) soundvol=100;
124 //FCEUI_SetSoundVolume(soundvol);
125 setsoundvol(soundvol);
126 }
127 else if (down(VOL_DOWN) && !down(VOL_UP))
128 {
129 soundvol-=1;
130 if (soundvol < 0) soundvol=0;
131 //FCEUI_SetSoundVolume(soundvol);
132 setsoundvol(soundvol);
133 }
b2b95d2e 134 else if (down(VOL_DOWN) && down(VOL_UP))
135 {
136 Exit = 1;
137 }
35868d35 138
139 if (shift)
140 {
141 // only if it's something else then last time, and not moving around the joystick
142 if (!(pad & (GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT)))
143 {
144 if (down(SELECT))
145 {
146 if (last_down(SELECT) && last_shift)
147 {
148 // still pressed down from stretching from last one
149 goto no_pad;
150 }
937bf65b 151 scaled_display = !scaled_display;
35868d35 152
937bf65b 153 if (scaled_display)
35868d35 154 {
b2b95d2e 155 gp2x_video_RGB_setscaling(0, 256, 240);
35868d35 156 }
157 else
158 {
b2b95d2e 159 gp2x_video_RGB_setscaling(0, 320, 240);
35868d35 160 }
161
162 goto no_pad;
163 }
164 else if (L_down && R_down)
165 {
166 FCEUI_CloseGame();
167 puts("Quit");
168 goto no_pad;
169 }
170 else if (R_down && !(last_R_down && last_shift))
171 {
172 FCEUI_LoadState();
173 goto no_pad;
174 }
175 else if (L_down && !(last_L_down && last_shift))
176 {
177 FCEUI_SaveState();
178 goto no_pad;
179 }
180 else if (down(A) && !(last_down(A) && last_shift))
181 {
182 FSkip_setting--;
183 if (FSkip_setting < 0) {
184 FSkip_setting = -1;
185 FCEUI_DispMessage("Auto frameskip");
186 }
187 else
188 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
189 goto no_pad;
190 }
191 else if (down(Y) && !(last_down(Y) && last_shift))
192 {
193 FSkip_setting++;
194 if (FSkip_setting > 8) FSkip_setting = 8;
195 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
196 goto no_pad;
197 }
198 }
199 }
200
201 // r is toggle savestate
202 if (R_down)
203 {
204 if (last_R_down)
205 {
206 R_count++;
207 if ((R_count & 31)== 31)
208 {
209 CurrentState=(CurrentState+1) % 10;
210 FCEUI_DispMessage("Now Using Save State %d", CurrentState);
211 }
212 }
213 }
214 else
215 {
216 R_count=0;
217 }
218
219 // l is toggle turbo
220 if (L_down)
221 {
222 if (last_L_down)
223 {
224 L_count++;
225 if ((L_count & 31)== 31)
226 {
227 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
228 if ((!TurboFireTop) && (!TurboFireBottom))
229 {
230 // was off
231 TurboFireTop=1;
232 TurboFireBottom=0;
233 if (swapbuttons)
234 {
235 FCEUI_DispMessage("Turbo A and Y");
236 }
237 else
238 {
239 FCEUI_DispMessage("Turbo Y and B");
240 }
241 }
242 else if (TurboFireTop)
243 {
244 TurboFireTop=0;
245 TurboFireBottom=1;
246 if (swapbuttons)
247 {
248 FCEUI_DispMessage("Turbo X and B");
249 }
250 else
251 {
252 FCEUI_DispMessage("Turbo A and X");
253 }
254 }
255 else
256 {
257 TurboFireTop=0;
258 TurboFireBottom=0;
259 FCEUI_DispMessage("Turbo Off");
260 }
261
262 }
263 }
264 }
265 else
266 {
267 L_count=0;
268 }
269
270 //unsigned long padTmp=0;
271 // shift the bits in
272 // up
273 //padTmp=(pad & GP2X_UP) ; // 1 is 2^0,
274 JS |= ((pad & GP2X_UP) << (4-0)); // 0x10 is 2^4
275
276 //padTmp=(pad & GP2X_DOWN); // 0x10 is 2^4,
277 JS |= ((pad & GP2X_DOWN) << (5-4)); // 0x20 is 2^5
278
279 //padTmp=(pad & GP2X_LEFT); // 0x4 is 2^2,
280 JS |= ((pad & GP2X_LEFT) << (6-2)); // 0x40 is 2^6
281
282 //padTmp=(pad & GP2X_RIGHT); // 0x40 is 2^6,
283 JS |= ((pad & GP2X_RIGHT) << (7-6)); // 0x80 is 2^7
284
285
286#define A_down (pad & GP2X_A)
287#define B_down (pad & GP2X_B)
288#define X_down (pad & GP2X_X)
289#define Y_down (pad & GP2X_Y)
290
291 // should be 2 cycles held, 1 cycle release
292 turbo_toggle_A=(turbo_toggle_A+1) % 3;
293 turbo_toggle_B=(turbo_toggle_B+1) % 3;
294
295 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
296 // B or X are both considered A
297 //padTmp=B_down >> 13; // 2^13,
298
299 if (!(TurboFireTop && (!turbo_toggle_A)))
300 {
301 JS |= ((B_down >> 13) << 0); // 0x1 is 2^0
302 }
303 // A or Y are both considered B
304 //padTmp=A_down >> 12; // 2^13,
305 if (!(TurboFireBottom && (!turbo_toggle_B)))
306 {
307 JS |= ((A_down >> 12) << 1); // 0x2 is 2^1
308 }
309
310 if (swapbuttons)
311 {
312 //padTmp=X_down >> 14; // 2^13,
313 if (!(TurboFireBottom && (!turbo_toggle_A)))
314 {
315// JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
316 JS |= ((Y_down >> 15) << 0); // 0x1 is 2^0
317 }
318
319 //padTmp=Y_down >> 15; // 2^13,
320 if (!(TurboFireTop && (!turbo_toggle_B)))
321 {
322 JS |= ((X_down >> 14) << 1); // 0x2 is 2^1
323 }
324 }
325 else
326 {
327 //padTmp=X_down >> 14; // 2^13,
328 if (!(TurboFireBottom && (!turbo_toggle_A)))
329 {
330 JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
331 }
332
333 //padTmp=Y_down >> 15; // 2^13,
334 if (!(TurboFireTop && (!turbo_toggle_B)))
335 {
336 JS |= ((Y_down >> 15) << 1); // 0x2 is 2^1
337 }
338 }
339
340 // select
341 //padTmp=(pad & GP2X_SELECT) >> 9; // 0x40 is 2^9,
342 JS |= (((pad & GP2X_SELECT) >> 9) << 2); // 0x4 is 2^2
343
344 // start
345 //padTmp=(pad & GP2X_START) >> 8; // 2^8,
346 JS |= (((pad & GP2X_START) >> 8) << 3); // 0x8 is 2^3
347
35868d35 348 JSreturn = JS;
349 lastpad=pad;
350
35868d35 351 //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
13624c8f 352
353
354 // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8);
355 // TODO: make these bindable, use new interface
356 if(gametype==GIT_FDS)
357 {
358 NoWaiting&=~1;
359 if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH)))
360 {
361 DriverInterface(DES_FDSSELECT,0);
362 }
363 else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L)))
364 {
365 DriverInterface(DES_FDSINSERT,0);
366 }
367 else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R)))
368 {
369 DriverInterface(DES_FDSEJECT,0);
370 }
371 }
372 return;
373
35868d35 374no_pad:
375 JSreturn=0;
376 lastpad=pad;
35868d35 377}
35868d35 378
379
380static void InitOtherInput(void)
381{
382
383 void *InputDPtr;
384
385 int t;
386 int x;
387 int attrib;
388
389 for(t=0,x=0;x<2;x++)
390 {
391 attrib=0;
392 InputDPtr=0;
393 switch(InputType[x])
394 {
395 //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
396 case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
397 case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
398 case SI_ZAPPER:InputDPtr=MouseData;
399 t|=1;
400 attrib=1;
401 break;
402 }
403 FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
404 }
405
406 attrib=0;
407 InputDPtr=0;
408 switch(InputTypeFC)
409 {
410 case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
411 case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
412 case SIFC_FKB:InputDPtr=fkbkeys;break;
413 }
414
415 FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
416 FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
417
418 if(t && !(inited&16))
419 {
420 InitMouse();
421 inited|=16;
422 }
423}