📄 input.c
字号:
#define INITGUID
#include "windows.h"
#include "shared.h"
#include "dinput.h"
#include "main.h"
#include "input.h"
#include "registry.h"
#include "screenshot.h"
static LPDIRECTINPUT pDirectInput = NULL;
static LPDIRECTINPUTDEVICE pKeyboard = NULL;
static DIJOYSTATE JoyState;
static BOOL KeyboardAcquired = FALSE;
static BOOL JoystickAcquired = FALSE;
static unsigned char KeyMap[256];
static BOOL JoystickAllowed;
static int NoOfJoysticks;
static JOYSTICK_INFO JoystickInfo[MAX_JOYSTICKS];
static int SelectedJoystick[MAX_PLAYERS] = {0, 0};
static char ButtonString[256][16] = {"", "Esc", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "0", "-", "=", "Backspace", "Tab", "Q", "W", "E", "R",
"T", "Y", "U", "I", "O", "P", "(", ")", "Return", "L Control",
"A", "S", "D", "F", "G", "H", "J", "K", "L", ";",
"'", "#", "L Shift", "\\", "Z", "X", "C", "V", "B", "N",
"M", ",", ".", "/", "R Shift", "*", "L Menu", "Space", "Caps", "F1",
"F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "Num Lock",
"Scroll Lock", "Num 7", "Num 8", "Num 9", "Num -", "Num 4", "Num 5", "Num 6", "Num +", "Num 1",
"Num 2", "Num 3", "Num 0", "Num .", "", "", "OEM 102", "F11", "F12", "", "", "",
"", "", "", "", "", "", "", "", "F13", "F14",
"F15", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"","", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "Num =", "", "", "", "", ":",
"_", "", "", "", "", "", "", "", "", "Enter", "R Control", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "Num ,", "", "Num /", "", "Prt Sc", "R Menu", "", "", "",
"", "", "", "", "", "", "", "", "", "Pause", "",
"Home", "Up", "Page Up", "", "Left", "", "Right", "", "End", "Down", "Page Down", "Insert", "Delete",
"", "", "", "", "", "", "", "L Win", "R Win"};
BOOL InitInput(HWND hwnd, HINSTANCE hInstance)
{
GUID guid = GUID_SysKeyboard;
if (DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &pDirectInput, NULL) != DI_OK)
{
if (DirectInputCreate(hInstance, 0x0300, &pDirectInput, NULL) != DI_OK)
{
TidyInput();
return FALSE;
}
else
{
JoystickAllowed = FALSE;
}
}
else
{
JoystickAllowed = TRUE;
}
// Setup Keyboard Stuff
if (IDirectInput_CreateDevice(pDirectInput, &guid, &pKeyboard, NULL) != DI_OK)
{
TidyInput();
return FALSE;
}
if (IDirectInputDevice_SetDataFormat(pKeyboard, &c_dfDIKeyboard) != DI_OK)
{
TidyInput();
return FALSE;
}
if (IDirectInputDevice_SetCooperativeLevel(pKeyboard, hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK)
{
TidyInput();
return FALSE;
}
AcquireKeyboard();
// Setup Joystick Stuff
NoOfJoysticks = 0;
memset(&JoyState, 0, sizeof(DIJOYSTATE));
memset(JoystickInfo, 0, sizeof(JOYSTICK_INFO) * MAX_JOYSTICKS);
if (JoystickAllowed)
{
IDirectInput_EnumDevices(pDirectInput, DIDEVTYPE_JOYSTICK, EnumJoysticks, hwnd, DIEDFL_ATTACHEDONLY);
SetSelectedJoystick(PLAYER_1, FindJoystick(PLAYER_1));
SetSelectedJoystick(PLAYER_2, FindJoystick(PLAYER_2));
AcquireJoystick(PLAYER_1);
AcquireJoystick(PLAYER_2);
}
return TRUE;
}
void TidyInput(void)
{
int i;
UnacquireJoystick(PLAYER_1);
UnacquireJoystick(PLAYER_2);
for (i = 0 ; i < MAX_JOYSTICKS ; i++)
{
if (JoystickInfo[i].pDevice)
{
IDirectInputDevice7_Release(JoystickInfo[i].pDevice);
JoystickInfo[i].pDevice = NULL;
}
}
if (pKeyboard)
{
UnacquireKeyboard();
IDirectInputDevice_Release(pKeyboard);
pKeyboard = NULL;
}
if (pDirectInput)
{
if (JoystickAllowed)
{
IDirectInput7_Release((LPDIRECTINPUT7)pDirectInput);
}
else
{
IDirectInput_Release(pDirectInput);
}
pDirectInput = NULL;
}
}
void AcquireKeyboard(void)
{
if (pKeyboard)
{
KeyboardAcquired = FALSE;
if(IDirectInputDevice_Acquire(pKeyboard) == DI_OK)
{
KeyboardAcquired = TRUE;
}
memset(KeyMap, 0, sizeof(char) * 256);
}
}
void UnacquireKeyboard(void)
{
if (pKeyboard)
{
if (KeyboardAcquired)
{
if (IDirectInputDevice_Unacquire(pKeyboard) == DI_OK)
{
KeyboardAcquired = FALSE;
}
}
}
}
void UpdateKeyboard(void)
{
HRESULT Result;
if (pKeyboard)
{
Result = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(KeyMap), KeyMap);
if ((Result == DIERR_INPUTLOST) || (Result == DIERR_NOTACQUIRED))
{
AcquireKeyboard();
}
}
memset(&input, 0, sizeof(t_input));
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_LEFT]]) input.pad[PLAYER_1] |= INPUT_LEFT;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_RIGHT]]) input.pad[PLAYER_1] |= INPUT_RIGHT;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_UP]]) input.pad[PLAYER_1] |= INPUT_UP;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_DOWN]]) input.pad[PLAYER_1] |= INPUT_DOWN;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_BUTTON1]]) input.pad[PLAYER_1] |= INPUT_BUTTON1;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_BUTTON2]]) input.pad[PLAYER_1] |= INPUT_BUTTON2;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_1][PAD_START]]) input.system |= (cart.type)? INPUT_START : INPUT_PAUSE;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_LEFT]]) input.pad[PLAYER_2] |= INPUT_LEFT;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_RIGHT]]) input.pad[PLAYER_2] |= INPUT_RIGHT;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_UP]]) input.pad[PLAYER_2] |= INPUT_UP;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_DOWN]]) input.pad[PLAYER_2] |= INPUT_DOWN;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_BUTTON1]]) input.pad[PLAYER_2] |= INPUT_BUTTON1;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_BUTTON2]]) input.pad[PLAYER_2] |= INPUT_BUTTON2;
if (KeyMap[RegistryInfo.ButtonMap[PLAYER_2][PAD_START]]) input.system |= (cart.type)? INPUT_START : INPUT_PAUSE;
}
void SetControlKey(int Player, int Button, int Key)
{
if (Key >= 256)
{
RegistryInfo.JoystickMap[Player][Button - PAD_BUTTON1] = Key - 256;
}
else
{
RegistryInfo.ButtonMap[Player][Button] = Key;
}
}
char *ButtonToString(int Player, int Button)
{
return ButtonString[RegistryInfo.ButtonMap[Player][Button]];
}
int GetKeyPressed(BOOL Update)
{
int i;
if (Update) UpdateKeyboard();
for (i = 0 ; i < 256 ; i++)
{
if (KeyMap[i]) return i;
}
return -1;
}
void UpdateSpecialKeys(void)
{
static BOOL Debounce = FALSE;
if (KeyMap[SCREENSHOT_KEY])
{
if (!Debounce) Screenshot();
Debounce = TRUE;
}
else if (KeyMap[LOAD_STATE_KEY])
{
if (!Debounce) LoadState();
Debounce = TRUE;
}
else if (KeyMap[SAVE_STATE_KEY])
{
if (!Debounce) SaveState();
Debounce = TRUE;
}
else if (KeyMap[RESET_KEY])
{
if (!Debounce) input.system = INPUT_HARD_RESET;
Debounce = TRUE;
}
else
{
Debounce = FALSE;
}
}
BOOL FAR PASCAL EnumJoysticks(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID *hwnd)
{
LPDIRECTINPUTDEVICE7 pDevice;
DIPROPRANGE Range;
if (IDirectInput7_CreateDeviceEx((LPDIRECTINPUT7)pDirectInput, &pDeviceInstance->guidInstance, &IID_IDirectInputDevice7, (void **)&pDevice, NULL) != DI_OK)
{
return DIENUM_CONTINUE;
}
if (IDirectInputDevice7_SetDataFormat(pDevice, &c_dfDIJoystick) != DI_OK)
{
IDirectInputDevice7_Release(pDevice);
return DIENUM_CONTINUE;
}
if (IDirectInputDevice7_SetCooperativeLevel(pDevice, (HWND)hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK)
{
IDirectInputDevice7_Release(pDevice);
return DIENUM_CONTINUE;
}
Range.diph.dwSize = sizeof(DIPROPRANGE);
Range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
Range.diph.dwHow = DIPH_BYOFFSET;
Range.diph.dwObj = DIJOFS_X;
Range.lMin = -JOYSTICK_RANGE;
Range.lMax = JOYSTICK_RANGE;
IDirectInputDevice7_SetProperty(pDevice, DIPROP_RANGE, &Range.diph);
Range.diph.dwObj = DIJOFS_Y;
Range.lMin = -JOYSTICK_RANGE;
Range.lMax = JOYSTICK_RANGE;
IDirectInputDevice7_SetProperty(pDevice, DIPROP_RANGE, &Range.diph);
JoystickInfo[NoOfJoysticks].pDevice = pDevice;
strcpy(JoystickInfo[NoOfJoysticks].Name, pDeviceInstance->tszInstanceName);
NoOfJoysticks++;
if (NoOfJoysticks == MAX_JOYSTICKS)
{
return DIENUM_STOP;
}
else
{
return DIENUM_CONTINUE;
}
}
BOOL JoystickPresent(void)
{
return NoOfJoysticks? TRUE : FALSE;
}
void AcquireJoystick(int Player)
{
int Joystick = GetSelectedJoystick(Player);
if (Joystick)
{
Joystick--;
if (JoystickInfo[Joystick].pDevice)
{
JoystickInfo[Joystick].Acquired = FALSE;
if (IDirectInputDevice7_Acquire(JoystickInfo[Joystick].pDevice) == DI_OK)
{
JoystickInfo[Joystick].Acquired = TRUE;
}
}
}
}
void UnacquireJoystick(int Player)
{
int Joystick = GetSelectedJoystick(Player);
if (Joystick)
{
Joystick--;
if (JoystickInfo[Joystick].pDevice)
{
if (JoystickInfo[Joystick].Acquired)
{
if (IDirectInputDevice7_Unacquire(JoystickInfo[Joystick].pDevice) == DI_OK)
{
JoystickInfo[Joystick].Acquired = FALSE;
}
}
}
}
}
void UpdateJoysticks(void)
{
int i;
if (RegistryInfo.DisableKeys[PLAYER_1] && GetSelectedJoystick(PLAYER_1))
{
input.pad[PLAYER_1] &= ~(INPUT_LEFT | INPUT_RIGHT | INPUT_UP | INPUT_DOWN | INPUT_BUTTON1 | INPUT_BUTTON2);
}
if (RegistryInfo.DisableKeys[PLAYER_2] && GetSelectedJoystick(PLAYER_2))
{
input.pad[PLAYER_2] &= ~(INPUT_LEFT | INPUT_RIGHT | INPUT_UP | INPUT_DOWN | INPUT_BUTTON1 | INPUT_BUTTON2);
}
for (i = 0 ; i < MAX_PLAYERS ; i++)
{
int Joystick = GetSelectedJoystick(i);
if (Joystick)
{
HRESULT hResult;
Joystick--;
IDirectInputDevice7_Poll(JoystickInfo[Joystick].pDevice);
hResult = IDirectInputDevice7_GetDeviceState(JoystickInfo[Joystick].pDevice, sizeof(DIJOYSTATE), &JoyState);
if (hResult != DI_OK)
{
AcquireJoystick(i);
break;
}
switch (i)
{
case PLAYER_1:
if (JoyState.lX < -(JOYSTICK_RANGE >> 3)) input.pad[PLAYER_1] |= INPUT_LEFT;
if (JoyState.lX > (JOYSTICK_RANGE >> 3)) input.pad[PLAYER_1] |= INPUT_RIGHT;
if (JoyState.lY < -(JOYSTICK_RANGE >> 3)) input.pad[PLAYER_1] |= INPUT_UP;
if (JoyState.lY > (JOYSTICK_RANGE >> 3)) input.pad[PLAYER_1] |= INPUT_DOWN;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_1][PAD_BUTTON1 - PAD_BUTTON1]]) input.pad[PLAYER_1] |= INPUT_BUTTON1;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_1][PAD_BUTTON2 - PAD_BUTTON1]]) input.pad[PLAYER_1] |= INPUT_BUTTON2;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_1][PAD_START - PAD_BUTTON1]]) input.system |= (cart.type)? INPUT_START : INPUT_PAUSE;
break;
case PLAYER_2:
if (JoyState.lX < -(JOYSTICK_RANGE >> 3)) input.pad[PLAYER_2] |= INPUT_LEFT;
if (JoyState.lX > (JOYSTICK_RANGE >> 3)) input.pad[PLAYER_2] |= INPUT_RIGHT;
if (JoyState.lY < -(JOYSTICK_RANGE >> 3)) input.pad[PLAYER_2] |= INPUT_UP;
if (JoyState.lY > (JOYSTICK_RANGE >> 3)) input.pad[PLAYER_2] |= INPUT_DOWN;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_2][PAD_BUTTON1 - PAD_BUTTON1]]) input.pad[PLAYER_2] |= INPUT_BUTTON1;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_2][PAD_BUTTON2 - PAD_BUTTON1]]) input.pad[PLAYER_2] |= INPUT_BUTTON2;
if (JoyState.rgbButtons[RegistryInfo.JoystickMap[PLAYER_2][PAD_START - PAD_BUTTON1]]) input.pad[PLAYER_2] |= (cart.type)? INPUT_START : INPUT_PAUSE;
break;
}
}
}
}
int GetJoystickButtonPressed(void)
{
int i;
for (i = 0 ; i < MAX_JOYSTICK_BUTTONS ; i++)
{
if (JoyState.rgbButtons[i]) return 256 + i;
}
return -1;
}
BOOL GetJoystickName(int Joystick, char *pName)
{
if (strlen(JoystickInfo[Joystick].Name))
{
strcpy(pName, JoystickInfo[Joystick].Name);
return TRUE;
}
return FALSE;
}
int GetSelectedJoystick(int Player)
{
return SelectedJoystick[Player];
}
void SetSelectedJoystick(int Player, int Joystick)
{
if (Joystick)
{
strcpy(RegistryInfo.Joystick[Player], JoystickInfo[Joystick - 1].Name);
}
else
{
strcpy(RegistryInfo.Joystick[Player], "");
}
SelectedJoystick[Player] = Joystick;
}
int FindJoystick(int Player)
{
int Found = 0;
int i;
for (i = 0 ; i < NoOfJoysticks ; i++)
{
if (!stricmp(JoystickInfo[i].Name, RegistryInfo.Joystick[Player]))
{
Found = i + 1;
break;
}
}
return Found;
}
void UpdateRapidFire(unsigned int Frame)
{
int i;
for (i = 0 ; i < MAX_PLAYERS ; i++)
{
BOOL Clear = (Frame % RegistryInfo.RapidFireRate[i])? TRUE : FALSE;
if (RegistryInfo.RapidFire[i][PAD_BUTTON1 - PAD_BUTTON1])
{
if (Clear) input.pad[i] &= ~INPUT_BUTTON1;
}
if (RegistryInfo.RapidFire[i][PAD_BUTTON2 - PAD_BUTTON1])
{
if (Clear) input.pad[i] &= ~INPUT_BUTTON2;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -