⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.c

📁 DC的SEGA_GG模拟器源代码
💻 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 + -