X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpc%2Finput.c;fp=drivers%2Fpc%2Finput.c;h=212c34d07b1cd25b300eb641042ac6b6383c43ab;hb=4d2721282a59f1dcb66a91291a85b2604517371f;hp=0000000000000000000000000000000000000000;hpb=987332078d2c97ba37b73d2b946377906fb486d7;p=fceu.git diff --git a/drivers/pc/input.c b/drivers/pc/input.c new file mode 100644 index 0000000..212c34d --- /dev/null +++ b/drivers/pc/input.c @@ -0,0 +1,719 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Ben Parnell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define JOY_A 1 +#define JOY_B 2 +#define JOY_SELECT 4 +#define JOY_START 8 +#define JOY_UP 0x10 +#define JOY_DOWN 0x20 +#define JOY_LEFT 0x40 +#define JOY_RIGHT 0x80 + + +#include "minimal.h" +extern int swapbuttons; +extern int stretch_offset; +extern void SetVideoScaling(int pixels,int width,int height); +long UpdateGamepadGP2X(void); + + + + + +static void UpdateFKB(void); + + + + + +/* UsrInputType[] is user-specified. InputType[] is current + (game loading can override user settings) +*/ +static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD}; +static int InputType[2]; + +static int UsrInputTypeFC={SI_NONE}; +static int InputTypeFC; + +static uint32 JSreturn; +int NoWaiting=0; + +static void DoCheatSeq(void) +{ + #if defined(DOS) || defined(SDL) + if(inited&1) + SilenceSound(1); + #endif + KillKeyboard(); + KillVideo(); + + DoConsoleCheatConfig(); + InitVideo(); + InitKeyboard(); + #if defined(DOS) || defined(SDL) + if(inited&1) + SilenceSound(0); + #endif +} + +#include "keyscan.h" +static char *keys; +static int DIPS=0; +#ifndef GP2X +static uint8 keyonce[MK_COUNT]; +#define KEY(__a) keys[MK(__a)] +#define keyonly(__a,__z) {if(KEY(__a)){if(!keyonce[MK(__a)]) {keyonce[MK(__a)]=1;__z}}else{keyonce[MK(__a)]=0;}} +#endif + +static int JoySwap=0; +static int cidisabled=0; +static int KeyboardUpdate(void) +{ +#ifndef GP2X + if(!UpdateKeyboard()) + if(keys) + return 0; + + keys=GetKeyboard(); + + if(InputTypeFC==SIFC_FKB) + { + keyonly(SCROLLLOCK,cidisabled^=1; + FCEUI_DispMessage("Family Keyboard %sabled.",cidisabled?"en":"dis");) + #ifdef SDL + SDL_WM_GrabInput(cidisabled?SDL_GRAB_ON:SDL_GRAB_OFF); + #endif + if(cidisabled) return(1); + } + #ifdef SVGALIB + keyonly(F3,LockConsole();) + keyonly(F4,UnlockConsole();) + #elif SDL + keyonly(F4,ToggleFS();) + #endif + NoWaiting&=~1; + if(KEY(GRAVE)) + NoWaiting|=1; + + if(gametype==GIT_FDS) + { + keyonly(S,DriverInterface(DES_FDSSELECT,0);) + keyonly(I,DriverInterface(DES_FDSINSERT,0);) + keyonly(E,DriverInterface(DES_FDSEJECT,0);) + } + + keyonly(F9,FCEUI_SaveSnapshot();) + if(gametype!=GIT_NSF) + { + keyonly(F2,DoCheatSeq();) + keyonly(F5,FCEUI_SaveState();) + keyonly(F7,FCEUI_LoadState();) + } + else + { + keyonly(CURSORLEFT,DriverInterface(DES_NSFDEC,0);) + keyonly(CURSORRIGHT,DriverInterface(DES_NSFINC,0);) + if( KEY(ENTER)) DriverInterface(DES_NSFRES,0); + if( KEY(CURSORUP)) DriverInterface(DES_NSFINC,0); + if( KEY(CURSORDOWN)) DriverInterface(DES_NSFDEC,0); + } + + keyonly(F10,DriverInterface(DES_RESET,0);) + keyonly(F11,DriverInterface(DES_POWER,0);) + if(KEY(F12) || KEY(ESCAPE)) FCEUI_CloseGame(); + + if(gametype==GIT_VSUNI) + { + keyonly(C,DriverInterface(DES_VSUNICOIN,0);) + keyonly(V,DIPS^=1;DriverInterface(DES_VSUNITOGGLEDIPVIEW,0);) + if(!(DIPS&1)) goto DIPSless; + keyonly(1,DriverInterface(DES_VSUNIDIPSET,(void *)1);) + keyonly(2,DriverInterface(DES_VSUNIDIPSET,(void *)2);) + keyonly(3,DriverInterface(DES_VSUNIDIPSET,(void *)3);) + keyonly(4,DriverInterface(DES_VSUNIDIPSET,(void *)4);) + keyonly(5,DriverInterface(DES_VSUNIDIPSET,(void *)5);) + keyonly(6,DriverInterface(DES_VSUNIDIPSET,(void *)6);) + keyonly(7,DriverInterface(DES_VSUNIDIPSET,(void *)7);) + keyonly(8,DriverInterface(DES_VSUNIDIPSET,(void *)8);) + } + else + { + keyonly(H,DriverInterface(DES_NTSCSELHUE,0);) + keyonly(T,DriverInterface(DES_NTSCSELTINT,0);) + if(KEY(KP_MINUS) || KEY(MINUS)) DriverInterface(DES_NTSCDEC,0); + if(KEY(KP_PLUS) || KEY(EQUAL)) DriverInterface(DES_NTSCINC,0); + + DIPSless: + keyonly(0,FCEUI_SelectState(0);) + keyonly(1,FCEUI_SelectState(1);) + keyonly(2,FCEUI_SelectState(2);) + keyonly(3,FCEUI_SelectState(3);) + keyonly(4,FCEUI_SelectState(4);) + keyonly(5,FCEUI_SelectState(5);) + keyonly(6,FCEUI_SelectState(6);) + keyonly(7,FCEUI_SelectState(7);) + keyonly(8,FCEUI_SelectState(8);) + keyonly(9,FCEUI_SelectState(9);) + } + return 1; +#else + return 1; +#endif +} + +static uint32 KeyboardDodo(void) +{ +#ifndef GP2X + uint32 JS=0; + + if(gametype!=GIT_NSF) + { + int x,y; + x=y=0; + keyonly(CAPSLOCK, + { + char tmp[64]; + JoySwap=(JoySwap+8)%32; + sprintf(tmp,"Joystick %d selected.",(JoySwap>>3)+1); + FCEUI_DispMessage(tmp); + }) + + if(KEY(LEFTALT) || KEY(X)) JS|=JOY_A<>8)|((JSreturn&0xFF00)<<8); + if(gametype==GIT_FDS) + { + NoWaiting&=~1; + if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH))) + { + DriverInterface(DES_FDSSELECT,0); + } + else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L))) + { + DriverInterface(DES_FDSINSERT,0); + } + else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R))) + { + DriverInterface(DES_FDSEJECT,0); + } + } + +#else + UpdateGamepadGP2X(); + b=KeyboardUpdate(); + + for(x=0;x<2;x++) + switch(InputType[x]) + { + case SI_GAMEPAD:t|=1;break; + case SI_ARKANOID:t|=2;break; + case SI_ZAPPER:t|=2;break; + case SI_POWERPAD:powerpadbuf[x]=UpdatePPadData(x);break; + } + + switch(InputTypeFC) + { + case SIFC_ARKANOID:t|=2;break; + case SIFC_SHADOW:t|=2;break; + case SIFC_FKB:if(cidisabled) UpdateFKB();break; + } + + if(t&1) + { + if(b) + KeyBJS=KeyboardDodo(); + JS=KeyBJS; + JS|=(uint32)GetJSOr(); + JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8); + } + if(t&2) + GetMouseData(MouseData); + +#endif +} + + + + + +//#ifdef GP2X + +extern void ResetNES(void); +extern void CleanSurface(void); + +char soundvolmeter[21]; +int soundvolIndex=0; +int L_count=0; +int R_count=0; +extern int CurrentState; +int TurboFireOff=1; +int TurboFireTop=0; // 0 is none // 1 is A & X turbo // 2 is Y & B turbo +int TurboFireBottom=0; +int turbo_toggle_A=0; +int turbo_toggle_B=0; + +static void setsoundvol(int soundvolume) +{ + //FCEUI_SetSoundVolume(soundvol); + // draw on screen :D + gp2x_sound_volume(soundvolume, soundvolume); + int meterval=soundvolume/5; + for (soundvolIndex=0; soundvolIndex < 20; soundvolIndex++) + { + if (soundvolIndex < meterval) + { + soundvolmeter[soundvolIndex]='*'; + } + else + { + soundvolmeter[soundvolIndex]='_'; + } + } + soundvolmeter[20]=0; + FCEU_DispMessage("|%s|", soundvolmeter); +} +/** + * GP2x joystick reader + * + */ +INLINE long UpdateGamepadGP2X(void) +{ + uint32 JS=0; + + unsigned long pad=gp2x_joystick_read(); +#define L_down (pad & GP2X_L) +#define R_down (pad & GP2X_R) +#define last_L_down (lastpad & GP2X_L) +#define last_R_down (lastpad & GP2X_R) + + if (L_down && R_down && (!(pad & GP2X_PUSH)) + && (!(last_R_down && last_L_down))) + { + ResetNES(); + puts("Reset"); + JSreturn=0; + lastpad=pad; + return pad; + } + + + + + if (pad & GP2X_VOL_UP) + { + soundvol+=1; + if (soundvol >= 100) soundvol=100; + //FCEUI_SetSoundVolume(soundvol); + setsoundvol(soundvol); + } + if (pad & GP2X_VOL_DOWN) + { + soundvol-=1; + if (soundvol < 0) soundvol=0; + //FCEUI_SetSoundVolume(soundvol); + setsoundvol(soundvol); + } + if (pad & GP2X_PUSH) + { + // only if it's something else then last time, and not moving around the joystick + if (!((pad & GP2X_UP) ||(pad & GP2X_DOWN) || (pad & GP2X_LEFT) || (pad & GP2X_RIGHT))) + { + if (pad & GP2X_SELECT) + { + if ((lastpad & GP2X_SELECT) && (lastpad & GP2X_PUSH)) + { + // still pressed down from stretching from last one + JSreturn=0; + lastpad=pad; + return 0; + } + if (stretch_offset == 32) + { + stretch_offset=0; + } + else + { + stretch_offset=32; + } + + if (stretch_offset == 32) + { + SetVideoScaling(320, 320, 240); + CleanSurface(); + } + else + { + SetVideoScaling(320, 256, 240); + } + + JSreturn=0; + lastpad=pad; + return pad; + } + else if (L_down && R_down) + { + FCEUI_CloseGame(); + puts("Quit"); + JSreturn=0; + return 0; + } + else if (R_down && (!((lastpad & GP2X_R) && (lastpad & GP2X_PUSH)))) + { + FCEUI_LoadState(); + JSreturn=0; + lastpad=pad; + return 0; + } + else if (L_down && (!((lastpad & GP2X_L) && (lastpad & GP2X_PUSH)))) + { + FCEUI_SaveState(); + JSreturn=0; + lastpad=pad; + return 0; + } + } + } + + // r is toggle savestate + if (R_down) + { + if (last_R_down) + { + R_count++; + if ((R_count & 31)== 31) + { + CurrentState=(CurrentState+1) % 10; + FCEUI_DispMessage("Now Using Save State %d", CurrentState); + } + } + } + else + { + R_count=0; + } + + // l is toggle turbo + if (L_down) + { + if (last_L_down) + { + L_count++; + if ((L_count & 31)== 31) + { + // 0 is none // 1 is Y & B turbo // 2 is X & A turbo + if ((!TurboFireTop) && (!TurboFireBottom)) + { + // was off + TurboFireTop=1; + TurboFireBottom=0; + if (swapbuttons) + { + FCEUI_DispMessage("Turbo A and Y"); + } + else + { + FCEUI_DispMessage("Turbo Y and B"); + } + } + else if (TurboFireTop) + { + TurboFireTop=0; + TurboFireBottom=1; + if (swapbuttons) + { + FCEUI_DispMessage("Turbo X and B"); + } + else + { + FCEUI_DispMessage("Turbo A and X"); + } + } + else + { + TurboFireTop=0; + TurboFireBottom=0; + FCEUI_DispMessage("Turbo Off"); + } + + } + } + } + else + { + L_count=0; + } + + + + //unsigned long padTmp=0; + // shift the bits in + // up + //padTmp=(pad & GP2X_UP) ; // 1 is 2^0, + JS |= ((pad & GP2X_UP) << (4-0)); // 0x10 is 2^4 + + //padTmp=(pad & GP2X_DOWN); // 0x10 is 2^4, + JS |= ((pad & GP2X_DOWN) << (5-4)); // 0x20 is 2^5 + + //padTmp=(pad & GP2X_LEFT); // 0x4 is 2^2, + JS |= ((pad & GP2X_LEFT) << (6-2)); // 0x40 is 2^6 + + //padTmp=(pad & GP2X_RIGHT); // 0x40 is 2^6, + JS |= ((pad & GP2X_RIGHT) << (7-6)); // 0x80 is 2^7 + + +#define A_down (pad & GP2X_A) +#define B_down (pad & GP2X_B) +#define X_down (pad & GP2X_X) +#define Y_down (pad & GP2X_Y) + + // should be 2 cycles held, 1 cycle release + turbo_toggle_A=(turbo_toggle_A+1) % 3; + turbo_toggle_B=(turbo_toggle_B+1) % 3; + + // 0 is none // 1 is Y & B turbo // 2 is X & A turbo + // B or X are both considered A + //padTmp=B_down >> 13; // 2^13, + + if (!(TurboFireTop && (!turbo_toggle_A))) + { + JS |= ((B_down >> 13) << 0); // 0x1 is 2^0 + } + // A or Y are both considered B + //padTmp=A_down >> 12; // 2^13, + if (!(TurboFireBottom && (!turbo_toggle_B))) + { + JS |= ((A_down >> 12) << 1); // 0x2 is 2^1 + } + + if (swapbuttons) + { + //padTmp=X_down >> 14; // 2^13, + if (!(TurboFireBottom && (!turbo_toggle_A))) + { +// JS |= ((X_down >> 14) << 0); // 0x1 is 2^0 + JS |= ((Y_down >> 15) << 0); // 0x1 is 2^0 + } + + //padTmp=Y_down >> 15; // 2^13, + if (!(TurboFireTop && (!turbo_toggle_B))) + { + JS |= ((X_down >> 14) << 1); // 0x2 is 2^1 + } + } + else + { + //padTmp=X_down >> 14; // 2^13, + if (!(TurboFireBottom && (!turbo_toggle_A))) + { + JS |= ((X_down >> 14) << 0); // 0x1 is 2^0 + } + + //padTmp=Y_down >> 15; // 2^13, + if (!(TurboFireTop && (!turbo_toggle_B))) + { + JS |= ((Y_down >> 15) << 1); // 0x2 is 2^1 + } + } + + // select + //padTmp=(pad & GP2X_SELECT) >> 9; // 0x40 is 2^9, + JS |= (((pad & GP2X_SELECT) >> 9) << 2); // 0x4 is 2^2 + + // start + //padTmp=(pad & GP2X_START) >> 8; // 2^8, + JS |= (((pad & GP2X_START) >> 8) << 3); // 0x8 is 2^3 + + + JSreturn = JS; + lastpad=pad; + + return pad; + //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8); +} +//#endif + + + + + + + + + + + + + + +static void InitOtherInput(void) +{ + + void *InputDPtr; + + int t; + int x; + int attrib; + + for(t=0,x=0;x<2;x++) + { + attrib=0; + InputDPtr=0; + switch(InputType[x]) + { + //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break; + case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break; + case SI_ARKANOID:InputDPtr=MouseData;t|=1;break; + case SI_ZAPPER:InputDPtr=MouseData; + t|=1; + attrib=1; + break; + } + FCEUI_SetInput(x,InputType[x],InputDPtr,attrib); + } + + attrib=0; + InputDPtr=0; + switch(InputTypeFC) + { + case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break; + case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break; + case SIFC_FKB:InputDPtr=fkbkeys;break; + } + + FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib); + FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE); + + if(t && !(inited&16)) + { + InitMouse(); + inited|=16; + } + +} +#ifndef GP2X +int fkbmap[0x48]= +{ + MK(F1),MK(F2),MK(F3),MK(F4),MK(F5),MK(F6),MK(F7),MK(F8), + MK(1),MK(2),MK(3),MK(4),MK(5),MK(6),MK(7),MK(8),MK(9),MK(0), + MK(MINUS),MK(EQUAL),MK(BACKSLASH),MK(BACKSPACE), + MK(ESCAPE),MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I),MK(O), + MK(P),MK(GRAVE),MK(BRACKET_LEFT),MK(ENTER), + MK(LEFTCONTROL),MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K), + MK(L),MK(SEMICOLON),MK(APOSTROPHE),MK(BRACKET_RIGHT),MK(INSERT), + MK(LEFTSHIFT),MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M),MK(COMMA), + MK(PERIOD),MK(SLASH),MK(RIGHTALT),MK(RIGHTSHIFT),MK(LEFTALT),MK(SPACE), + MK(DELETE),MK(END),MK(PAGEDOWN), + MK(CURSORUP),MK(CURSORLEFT),MK(CURSORRIGHT),MK(CURSORDOWN) +}; +#endif + +static void UpdateFKB(void) +{ +#ifndef GP2X + int x; + + for(x=0;x<0x48;x++) + { + fkbkeys[x]=0; + if(keys[fkbmap[x]]) + fkbkeys[x]=1; + } +#endif +}