1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
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.
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.
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
28 #define JOY_RIGHT 0x80
32 extern int swapbuttons;
33 extern int stretch_offset;
34 extern int FSkip_setting;
36 extern void SetVideoScaling(int pixels,int width,int height);
37 INLINE long UpdateGamepadGP2X(void);
41 /* UsrInputType[] is user-specified. InputType[] is current
42 (game loading can override user settings)
44 static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
45 static int InputType[2];
47 static int UsrInputTypeFC={SI_NONE};
48 static int InputTypeFC;
50 static uint32 JSreturn;
53 static int powerpadsc[2][12];
54 static int powerpadside=0;
57 static uint32 MouseData[3];
58 static uint8 fkbkeys[0x48];
59 unsigned long lastpad=0;
61 void FCEUD_UpdateInput(void)
64 long lastpad2=lastpad;
65 long pad = UpdateGamepadGP2X();
67 // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8);
71 if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH)))
73 DriverInterface(DES_FDSSELECT,0);
75 else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L)))
77 DriverInterface(DES_FDSINSERT,0);
79 else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R)))
81 DriverInterface(DES_FDSEJECT,0);
90 extern void ResetNES(void);
91 extern void CleanSurface(void);
93 char soundvolmeter[21];
97 extern int CurrentState;
99 int TurboFireTop=0; // 0 is none // 1 is A & X turbo // 2 is Y & B turbo
100 int TurboFireBottom=0;
101 int turbo_toggle_A=0;
102 int turbo_toggle_B=0;
104 static void setsoundvol(int soundvolume)
106 //FCEUI_SetSoundVolume(soundvol);
108 gp2x_sound_volume(soundvolume, soundvolume);
109 int meterval=soundvolume/5;
110 for (soundvolIndex=0; soundvolIndex < 20; soundvolIndex++)
112 if (soundvolIndex < meterval)
114 soundvolmeter[soundvolIndex]='*';
118 soundvolmeter[soundvolIndex]='_';
122 FCEU_DispMessage("|%s|", soundvolmeter);
125 * GP2x joystick reader
128 INLINE long UpdateGamepadGP2X(void)
132 unsigned long pad=gp2x_joystick_read();
133 #define down(b) (pad & GP2X_##b)
134 #define last_down(b) (lastpad & GP2X_##b)
135 #define L_down (pad & GP2X_L)
136 #define R_down (pad & GP2X_R)
137 #define last_L_down (lastpad & GP2X_L)
138 #define last_R_down (lastpad & GP2X_R)
139 #define shift ((pad & GP2X_PUSH) || ((pad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
140 #define last_shift ((lastpad & GP2X_PUSH) || ((lastpad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
142 if (L_down && R_down && !(pad & GP2X_PUSH) && !(last_R_down && last_L_down))
149 if (down(VOL_UP) && !down(VOL_DOWN))
152 if (soundvol >= 100) soundvol=100;
153 //FCEUI_SetSoundVolume(soundvol);
154 setsoundvol(soundvol);
156 else if (down(VOL_DOWN) && !down(VOL_UP))
159 if (soundvol < 0) soundvol=0;
160 //FCEUI_SetSoundVolume(soundvol);
161 setsoundvol(soundvol);
166 // only if it's something else then last time, and not moving around the joystick
167 if (!(pad & (GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT)))
171 if (last_down(SELECT) && last_shift)
173 // still pressed down from stretching from last one
176 if (stretch_offset == 32)
185 if (stretch_offset == 32)
187 SetVideoScaling(320, 320, 240);
192 SetVideoScaling(320, 256, 240);
197 else if (L_down && R_down)
203 else if (R_down && !(last_R_down && last_shift))
208 else if (L_down && !(last_L_down && last_shift))
213 else if (down(A) && !(last_down(A) && last_shift))
216 if (FSkip_setting < 0) {
218 FCEUI_DispMessage("Auto frameskip");
221 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
224 else if (down(Y) && !(last_down(Y) && last_shift))
227 if (FSkip_setting > 8) FSkip_setting = 8;
228 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
234 // r is toggle savestate
240 if ((R_count & 31)== 31)
242 CurrentState=(CurrentState+1) % 10;
243 FCEUI_DispMessage("Now Using Save State %d", CurrentState);
258 if ((L_count & 31)== 31)
260 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
261 if ((!TurboFireTop) && (!TurboFireBottom))
268 FCEUI_DispMessage("Turbo A and Y");
272 FCEUI_DispMessage("Turbo Y and B");
275 else if (TurboFireTop)
281 FCEUI_DispMessage("Turbo X and B");
285 FCEUI_DispMessage("Turbo A and X");
292 FCEUI_DispMessage("Turbo Off");
303 //unsigned long padTmp=0;
306 //padTmp=(pad & GP2X_UP) ; // 1 is 2^0,
307 JS |= ((pad & GP2X_UP) << (4-0)); // 0x10 is 2^4
309 //padTmp=(pad & GP2X_DOWN); // 0x10 is 2^4,
310 JS |= ((pad & GP2X_DOWN) << (5-4)); // 0x20 is 2^5
312 //padTmp=(pad & GP2X_LEFT); // 0x4 is 2^2,
313 JS |= ((pad & GP2X_LEFT) << (6-2)); // 0x40 is 2^6
315 //padTmp=(pad & GP2X_RIGHT); // 0x40 is 2^6,
316 JS |= ((pad & GP2X_RIGHT) << (7-6)); // 0x80 is 2^7
319 #define A_down (pad & GP2X_A)
320 #define B_down (pad & GP2X_B)
321 #define X_down (pad & GP2X_X)
322 #define Y_down (pad & GP2X_Y)
324 // should be 2 cycles held, 1 cycle release
325 turbo_toggle_A=(turbo_toggle_A+1) % 3;
326 turbo_toggle_B=(turbo_toggle_B+1) % 3;
328 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
329 // B or X are both considered A
330 //padTmp=B_down >> 13; // 2^13,
332 if (!(TurboFireTop && (!turbo_toggle_A)))
334 JS |= ((B_down >> 13) << 0); // 0x1 is 2^0
336 // A or Y are both considered B
337 //padTmp=A_down >> 12; // 2^13,
338 if (!(TurboFireBottom && (!turbo_toggle_B)))
340 JS |= ((A_down >> 12) << 1); // 0x2 is 2^1
345 //padTmp=X_down >> 14; // 2^13,
346 if (!(TurboFireBottom && (!turbo_toggle_A)))
348 // JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
349 JS |= ((Y_down >> 15) << 0); // 0x1 is 2^0
352 //padTmp=Y_down >> 15; // 2^13,
353 if (!(TurboFireTop && (!turbo_toggle_B)))
355 JS |= ((X_down >> 14) << 1); // 0x2 is 2^1
360 //padTmp=X_down >> 14; // 2^13,
361 if (!(TurboFireBottom && (!turbo_toggle_A)))
363 JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
366 //padTmp=Y_down >> 15; // 2^13,
367 if (!(TurboFireTop && (!turbo_toggle_B)))
369 JS |= ((Y_down >> 15) << 1); // 0x2 is 2^1
374 //padTmp=(pad & GP2X_SELECT) >> 9; // 0x40 is 2^9,
375 JS |= (((pad & GP2X_SELECT) >> 9) << 2); // 0x4 is 2^2
378 //padTmp=(pad & GP2X_START) >> 8; // 2^8,
379 JS |= (((pad & GP2X_START) >> 8) << 3); // 0x8 is 2^3
386 //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
395 static void InitOtherInput(void)
410 //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
411 case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
412 case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
413 case SI_ZAPPER:InputDPtr=MouseData;
418 FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
425 case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
426 case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
427 case SIFC_FKB:InputDPtr=fkbkeys;break;
430 FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
431 FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
433 if(t && !(inited&16))