/* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: * Copyright (C) 2002 Xodnizel * * 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 */ #include #include "main.h" #include "dface.h" #include "input.h" #include "../common/cheat.h" /* UsrInputType[] is user-specified. InputType[] is current (game loading can override user settings) */ int UsrInputType[3]={SI_GAMEPAD,SI_GAMEPAD,SIFC_NONE}; int InputType[3]={0,0,0}; static int cspec=0; extern int gametype; /* Necessary for proper GUI functioning(configuring when a game isn't loaded). */ void InputUserActiveFix(void) { int x; for(x=0;x<3;x++) InputType[x]=UsrInputType[x]; } void ParseGIInput(FCEUGI *gi) { gametype=gi->type; InputType[0]=UsrInputType[0]; InputType[1]=UsrInputType[1]; InputType[2]=UsrInputType[2]; if(gi->input[0]>=0) InputType[0]=gi->input[0]; if(gi->input[1]>=0) InputType[1]=gi->input[1]; if(gi->inputfc>=0) InputType[2]=gi->inputfc; cspec = gi->cspecial; #ifdef EXTGUI Giggles(gi->cspecial); #endif } static uint8 QuizKingData=0; static uint8 HyperShotData=0; static uint32 MahjongData=0; static uint32 FTrainerData=0; static uint8 TopRiderData=0; static uint8 BWorldData[1+13+1]; static void UpdateFKB(void); static void UpdateGamepad(void); static void UpdateQuizKing(void); static void UpdateHyperShot(void); static void UpdateMahjong(void); static void UpdateFTrainer(void); static void UpdateTopRider(void); static uint32 JSreturn=0; int NoWaiting=1; #ifndef EXTGUI static void DoCheatSeq(void) { #if defined(DOS) || defined(SDL) SilenceSound(1); #endif KillKeyboard(); KillVideo(); DoConsoleCheatConfig(); InitVideo(CurGame); InitKeyboard(); #if defined(DOS) || defined(SDL) SilenceSound(0); #endif } #endif #include "keyscan.h" static char *keys=0; static int DIPS=0; static uint8 keyonce[MKK_COUNT]; #define KEY(__a) keys[MKK(__a)] static int _keyonly(int a) { if(keys[a]) { if(!keyonce[a]) { keyonce[a]=1; return(1); } } else keyonce[a]=0; return(0); } #define keyonly(__a) _keyonly(MKK(__a)) static int cidisabled=0; static void KeyboardCommands(void) { int is_shift, is_alt; keys=GetKeyboard(); if(InputType[2]==SIFC_FKB) { if(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; } is_shift = KEY(LEFTSHIFT) | KEY(RIGHTSHIFT); is_alt = KEY(LEFTALT) | KEY(RIGHTALT); if(keyonly(F4)) { if(is_shift) FCEUI_SetRenderDisable(-1, 2); else FCEUI_SetRenderDisable(2, -1); } #ifdef SDL if(keyonly(ENTER) && is_alt) ToggleFS(); #endif NoWaiting&=~1; if(KEY(GRAVE)) NoWaiting|=1; if(gametype==GIT_FDS) { if(keyonly(F6)) FCEUI_FDSSelect(); if(keyonly(F8)) FCEUI_FDSInsert(); } if(keyonly(F9)) FCEUI_SaveSnapshot(); if(gametype!=GIT_NSF) { #ifndef EXTGUI if(keyonly(F2)) DoCheatSeq(); #endif if(keyonly(F5)) { if(is_shift) FCEUI_SaveMovie(NULL,0,NULL); else FCEUI_SaveState(NULL); } if(keyonly(F7)) { if(is_shift) FCEUI_LoadMovie(NULL,0,0); //mbg merge 7/23/06 loadmovie takes another arg now else FCEUI_LoadState(NULL); } } if(keyonly(F1)) FCEUI_ToggleTileView(); if(keyonly(MINUS)) DecreaseEmulationSpeed(); if(keyonly(EQUAL)) IncreaseEmulationSpeed(); if(keyonly(BACKSPACE)) FCEUI_MovieToggleFrameDisplay(); if(keyonly(BACKSLASH)) FCEUI_ToggleEmulationPause(); if(keyonly(RIGHTCONTROL)) FCEUI_FrameAdvance(); if(keyonly(F10)) FCEUI_ResetNES(); if(keyonly(F11)) FCEUI_PowerNES(); #ifdef EXTGUI if(keyonly(F3)) GUI_Hide(-1); if(KEY(F12)) GUI_RequestExit(); if(KEY(ESCAPE)) CloseGame(); #else if(KEY(F12) || KEY(ESCAPE)) CloseGame(); #endif if(gametype==GIT_VSUNI) { if(keyonly(F8)) FCEUI_VSUniCoin(); if(keyonly(F6)) { DIPS^=1; FCEUI_VSUniToggleDIPView(); } if(!(DIPS&1)) goto DIPSless; if(keyonly(1)) FCEUI_VSUniToggleDIP(0); if(keyonly(2)) FCEUI_VSUniToggleDIP(1); if(keyonly(3)) FCEUI_VSUniToggleDIP(2); if(keyonly(4)) FCEUI_VSUniToggleDIP(3); if(keyonly(5)) FCEUI_VSUniToggleDIP(4); if(keyonly(6)) FCEUI_VSUniToggleDIP(5); if(keyonly(7)) FCEUI_VSUniToggleDIP(6); if(keyonly(8)) FCEUI_VSUniToggleDIP(7); } else { static uint8 bbuf[32]; static int bbuft; static int barcoder = 0; if(keyonly(H)) FCEUI_NTSCSELHUE(); if(keyonly(T)) FCEUI_NTSCSELTINT(); if(KEY(KP_MINUS) || KEY(MINUS)) FCEUI_NTSCDEC(); if(KEY(KP_PLUS) || KEY(EQUAL)) FCEUI_NTSCINC(); if((InputType[2] == SIFC_BWORLD) || (cspec == SIS_DATACH)) { if(keyonly(F8)) { barcoder ^= 1; if(!barcoder) { if(InputType[2] == SIFC_BWORLD) { strcpy((char *)&BWorldData[1],(char *)bbuf); BWorldData[0]=1; } else FCEUI_DatachSet(bbuf); FCEUI_DispMessage("Barcode Entered"); } else { bbuft = 0; FCEUI_DispMessage("Enter Barcode");} } } else barcoder = 0; #define SSM(x) \ { if(barcoder) { if(bbuft < 13) {bbuf[bbuft++] = '0' + x; bbuf[bbuft] = 0;} FCEUI_DispMessage("Barcode: %s",bbuf);} \ else { \ if(is_shift) FCEUI_SelectMovie(x,1); \ else FCEUI_SelectState(x,1); \ } } DIPSless: if(keyonly(0)) SSM(0); if(keyonly(1)) SSM(1); if(keyonly(2)) SSM(2); if(keyonly(3)) SSM(3); if(keyonly(4)) SSM(4); if(keyonly(5)) SSM(5); if(keyonly(6)) SSM(6); if(keyonly(7)) SSM(7); if(keyonly(8)) SSM(8); if(keyonly(9)) SSM(9); #undef SSM } } #define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1} #define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2} #define MKZ() {{0},{0},{0},0} #define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()} ButtConfig GamePadConfig[4][10]={ /* Gamepad 1 */ { MK(KP3), MK(KP2), MK(TAB), MK(ENTER), MK(W),MK(Z), MK(A), MK(S), MKZ(), MKZ() }, /* Gamepad 2 */ GPZ(), /* Gamepad 3 */ GPZ(), /* Gamepad 4 */ GPZ() }; static void UpdateGamepad(void) { if(FCEUI_IsMovieActive()<0) return; static int rapid=0; uint32 JS=0; int x; int wg; rapid^=1; for(wg=0;wg<4;wg++) { for(x=0;x<8;x++) if(DTestButton(&GamePadConfig[wg][x])) JS|=(1<ButtType[wc]==bc->ButtType[wc-1] && bc->DeviceNum[wc]==bc->DeviceNum[wc-1] && bc->ButtonNum[wc]==bc->ButtonNum[wc-1]) break; } bc->NumC=wc; } void ConfigDevice(int which, int arg) { uint8 buf[256]; int x; ButtonConfigBegin(); switch(which) { case FCFGD_QUIZKING: for(x=0;x<6;x++) { sprintf((char *)buf,"Quiz King Buzzer #%d", x+1); subcon((char *)buf,&QuizKingButtons[x]); } break; case FCFGD_HYPERSHOT: for(x=0;x<4;x++) { sprintf((char *)buf,"Hyper Shot %d: %s",((x&2)>>1)+1,(x&1)?"JUMP":"RUN"); subcon((char *)buf,&HyperShotButtons[x]); } break; case FCFGD_POWERPAD: for(x=0;x<12;x++) { sprintf((char *)buf,"PowerPad %d: %d", (arg&1)+1,x+11); subcon((char *)buf,&powerpadsc[arg&1][x]); } break; case FCFGD_GAMEPAD: { char *str[10]={"A","B","SELECT","START","UP","DOWN","LEFT","RIGHT","Rapid A","Rapid B"}; for(x=0;x<10;x++) { sprintf((char *)buf,"GamePad #%d: %s",arg+1,str[x]); subcon((char *)buf,&GamePadConfig[arg][x]); } } break; } ButtonConfigEnd(); } CFGSTRUCT InputConfig[]={ ACA(UsrInputType), AC(powerpadsc), AC(QuizKingButtons), AC(FTrainerButtons), AC(HyperShotButtons), AC(MahjongButtons), AC(GamePadConfig), AC(fkbmap), ENDCFGSTRUCT }; static void InputCfg(char *text) { if(!strncasecmp(text,"gamepad",strlen("gamepad"))) { ConfigDevice(FCFGD_GAMEPAD,(text[strlen("gamepad")]-'1')&3); } else if(!strncasecmp(text,"powerpad",strlen("powerpad"))) { ConfigDevice(FCFGD_POWERPAD,(text[strlen("powerpad")]-'1')&1); } else if(!strcasecmp(text,"hypershot")) ConfigDevice(FCFGD_HYPERSHOT,0); else if(!strcasecmp(text,"quizking")) ConfigDevice(FCFGD_QUIZKING,0); } static void FCExp(char *text) { static char *fccortab[11]={"none","arkanoid","shadow","4player","fkb","hypershot", "mahjong","quizking","ftrainera","ftrainerb","oekakids"}; static int fccortabi[11]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW, SIFC_4PLAYER,SIFC_FKB,SIFC_HYPERSHOT,SIFC_MAHJONG,SIFC_QUIZKING, SIFC_FTRAINERA,SIFC_FTRAINERB,SIFC_OEKAKIDS}; int y; for(y=0;y<11;y++) if(!strcmp(fccortab[y],text)) UsrInputType[2]=fccortabi[y]; } static char *cortab[6]={"none","gamepad","zapper","powerpada","powerpadb","arkanoid"}; static int cortabi[6]={SI_NONE,SI_GAMEPAD, SI_ZAPPER,SI_POWERPADA,SI_POWERPADB,SI_ARKANOID}; static void Input1(char *text) { int y; for(y=0;y<6;y++) if(!strcmp(cortab[y],text)) UsrInputType[0]=cortabi[y]; } static void Input2(char *text) { int y; for(y=0;y<6;y++) if(!strcmp(cortab[y],text)) UsrInputType[1]=cortabi[y]; } ARGPSTRUCT InputArgs[]={ {"-inputcfg",0,(void *)InputCfg,0x2000}, {"-fcexp",0,(void *)FCExp,0x2000}, {"-input1",0,(void *)Input1,0x2000}, {"-input2",0,(void *)Input2,0x2000}, {0,0,0,0} };