/* 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 "common.h" #include #include "input.h" #include "keyboard.h" static HRESULT ddrval; //mbg merge 7/17/06 made static static LPDIRECTINPUTDEVICE7 lpdid=0; void KeyboardClose(void) { if(lpdid) IDirectInputDevice7_Unacquire(lpdid); lpdid=0; } static unsigned char keys[256] = {0,}; // with repeat static unsigned char keys_nr[256] = {0,}; // non-repeating static unsigned char keys_jd[256] = {0,}; // just-down static unsigned char keys_jd_lock[256] = {0,}; // just-down released lock int autoHoldKey = 0, autoHoldClearKey = 0; void KeyboardUpdateState(void) { unsigned char tk[256]; ddrval=IDirectInputDevice7_GetDeviceState(lpdid,256,tk); // HACK because DirectInput is totally wacky about recognizing the PAUSE/BREAK key if(GetAsyncKeyState(VK_PAUSE)) // normally this should have & 0x8000, but apparently this key is too special for that to work tk[0xC5] = 0x80; switch(ddrval) { case DI_OK: //memcpy(keys,tk,256);break; { extern int soundoptions; #define SO_OLDUP 32 extern int soundo; extern int32 fps_scale; int notAlternateThrottle = !(soundoptions&SO_OLDUP) && soundo && ((NoWaiting&1)?(256*16):fps_scale) >= 64; #define KEY_REPEAT_INITIAL_DELAY ((!notAlternateThrottle) ? (16) : (64)) // must be >= 0 and <= 255 #define KEY_REPEAT_REPEATING_DELAY (6) // must be >= 1 and <= 255 #define KEY_JUST_DOWN_DURATION (4) // must be >= 1 and <= 255 int i; for(i = 0 ; i < 256 ; i++) if(tk[i]) if(keys_nr[i] < 255) keys_nr[i]++; // activate key, and count up for repeat else keys_nr[i] = 255 - KEY_REPEAT_REPEATING_DELAY; // oscillate for repeat else keys_nr[i] = 0; // deactivate key memcpy(keys,keys_nr,256); // key-down detection for(i = 0 ; i < 256 ; i++) if(!keys_nr[i]) { keys_jd[i] = 0; keys_jd_lock[i] = 0; } else if(keys_jd_lock[i]) {} else if(keys_jd[i] /*&& (i != 0x2A && i != 0x36 && i != 0x1D && i != 0x38)*/) { if(++keys_jd[i] > KEY_JUST_DOWN_DURATION) { keys_jd[i] = 0; keys_jd_lock[i] = 1; } } else keys_jd[i] = 1; // key repeat for(i = 0 ; i < 256 ; i++) if(keys[i] >= KEY_REPEAT_INITIAL_DELAY && !(keys[i]%KEY_REPEAT_REPEATING_DELAY)) keys[i] = 0; } break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: memset(keys,0,256); IDirectInputDevice7_Acquire(lpdid); break; } extern uint8 autoHoldOn, autoHoldReset; autoHoldOn = autoHoldKey && keys[autoHoldKey] != 0; autoHoldReset = autoHoldClearKey && keys[autoHoldClearKey] != 0; } unsigned char *GetKeyboard(void) { return(keys); } unsigned char *GetKeyboard_nr(void) { return(keys_nr); } unsigned char *GetKeyboard_jd(void) { return(keys_jd); } int KeyboardInitialize(void) { if(lpdid) return(1); //mbg merge 7/17/06 changed: ddrval=IDirectInput7_CreateDeviceEx(lpDI, GUID_SysKeyboard,IID_IDirectInputDevice7, (LPVOID *)&lpdid,0); //ddrval=IDirectInput7_CreateDeviceEx(lpDI, &GUID_SysKeyboard,&IID_IDirectInputDevice7, (LPVOID *)&lpdid,0); if(ddrval != DI_OK) { FCEUD_PrintError("DirectInput: Error creating keyboard device."); return 0; } ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE); if(ddrval != DI_OK) { FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level."); return 0; } ddrval=IDirectInputDevice7_SetDataFormat(lpdid,&c_dfDIKeyboard); if(ddrval != DI_OK) { FCEUD_PrintError("DirectInput: Error setting keyboard data format."); return 0; } ddrval=IDirectInputDevice7_Acquire(lpdid); /* Not really a fatal error. */ //if(ddrval != DI_OK) //{ // FCEUD_PrintError("DirectInput: Error acquiring keyboard."); // return 0; //} return 1; } int KeyboardSetBackgroundAccess(int on) { if(!lpdid) return(0); ddrval=IDirectInputDevice7_Unacquire(lpdid); if(on) ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE); else ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE); if(ddrval != DI_OK) { FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level."); return 0; } ddrval=IDirectInputDevice7_Acquire(lpdid); return 1; }