2006-07-18 02:53:36 +00:00
|
|
|
/* 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 <dinput.h>
|
|
|
|
|
|
|
|
#include "input.h"
|
|
|
|
#include "keyboard.h"
|
|
|
|
|
2006-07-19 02:22:26 +00:00
|
|
|
static HRESULT ddrval; //mbg merge 7/17/06 made static
|
2006-07-18 02:53:36 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2006-07-18 06:35:48 +00:00
|
|
|
//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);
|
2006-07-18 02:53:36 +00:00
|
|
|
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;
|
|
|
|
}
|