Input plugin: Start to scan keyboard
This commit is contained in:
parent
be939dca65
commit
f78e292796
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include <Common\stdtypes.h>
|
||||
|
||||
enum BtnType
|
||||
{
|
||||
BTNTYPE_UNASSIGNED = 0,
|
||||
|
||||
// Joystick
|
||||
BTNTYPE_JOYBUTTON = 1,
|
||||
BTNTYPE_JOYAXE = 2,
|
||||
BTNTYPE_JOYPOV = 3,
|
||||
BTNTYPE_JOYSLIDER = 4,
|
||||
|
||||
// Keyboard
|
||||
BTNTYPE_KEYBUTTON = 5,
|
||||
|
||||
// Mouse
|
||||
BTNTYPE_MOUSEBUTTON = 6,
|
||||
BTNTYPE_MOUSEAXE = 7,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Offset;
|
||||
uint8_t AxisID;
|
||||
BtnType BtnType;
|
||||
} BUTTON;
|
|
@ -0,0 +1,55 @@
|
|||
#include "CProject64Input.h"
|
||||
|
||||
CProject64Input * g_InputPlugin = nullptr;
|
||||
|
||||
CProject64Input::CProject64Input(HINSTANCE hinst) :
|
||||
m_hinst(hinst),
|
||||
m_Scanning(false),
|
||||
m_DisplayCtrlId(0)
|
||||
{
|
||||
memset(m_Controllers, 0, sizeof(m_Controllers));
|
||||
}
|
||||
|
||||
CProject64Input::~CProject64Input()
|
||||
{
|
||||
}
|
||||
|
||||
void CProject64Input::InitiateControllers(CONTROL_INFO * ControlInfo)
|
||||
{
|
||||
if (m_DirectInput.get() == NULL)
|
||||
{
|
||||
m_DirectInput.reset(new CDirectInput(m_hinst));
|
||||
}
|
||||
m_DirectInput->Initiate(ControlInfo);
|
||||
}
|
||||
|
||||
void CProject64Input::StartScanDevices(int32_t DisplayCtrlId)
|
||||
{
|
||||
m_Scanning = true;
|
||||
m_DisplayCtrlId = DisplayCtrlId;
|
||||
}
|
||||
|
||||
void CProject64Input::EndScanDevices(void)
|
||||
{
|
||||
m_Scanning = false;
|
||||
m_DisplayCtrlId = 0;
|
||||
}
|
||||
|
||||
CDirectInput::ScanResult CProject64Input::ScanDevices(BUTTON & Button)
|
||||
{
|
||||
CDirectInput::ScanResult Result = CDirectInput::SCAN_FAILED;
|
||||
if (m_DirectInput.get() != NULL)
|
||||
{
|
||||
Result = m_DirectInput->ScanDevices(Button);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::wstring CProject64Input::ButtonAssignment(BUTTON & Button)
|
||||
{
|
||||
if (m_DirectInput.get() != NULL)
|
||||
{
|
||||
return m_DirectInput->ButtonAssignment(Button);
|
||||
}
|
||||
return L"Unknown";
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include "ControllerSpec1.1.h"
|
||||
#include "DirectInput.h"
|
||||
#include "N64Controller.h"
|
||||
#include <memory>
|
||||
|
||||
class CProject64Input
|
||||
{
|
||||
public:
|
||||
CProject64Input(HINSTANCE hinst);
|
||||
~CProject64Input();
|
||||
|
||||
void InitiateControllers(CONTROL_INFO * ControlInfo);
|
||||
void StartScanDevices(int32_t DisplayCtrlId);
|
||||
void EndScanDevices(void);
|
||||
CDirectInput::ScanResult ScanDevices(BUTTON & Button);
|
||||
std::wstring ButtonAssignment(BUTTON & Button);
|
||||
|
||||
inline HINSTANCE hInst(void) const { return m_hinst; }
|
||||
inline bool IsScanning(void) const { return m_Scanning; }
|
||||
inline int32_t DisplayCtrlId(void) const { return m_DisplayCtrlId; }
|
||||
inline N64CONTROLLER & Controllers(int32_t Controller) { return m_Controllers[Controller]; }
|
||||
|
||||
private:
|
||||
CProject64Input();
|
||||
CProject64Input(const CProject64Input&);
|
||||
CProject64Input& operator=(const CProject64Input&);
|
||||
|
||||
N64CONTROLLER m_Controllers[4];
|
||||
std::unique_ptr<CDirectInput> m_DirectInput;
|
||||
HINSTANCE m_hinst;
|
||||
bool m_Scanning;
|
||||
int32_t m_DisplayCtrlId;
|
||||
};
|
||||
|
||||
extern CProject64Input * g_InputPlugin;
|
|
@ -0,0 +1,215 @@
|
|||
#include "DirectInput.h"
|
||||
#include <Common\StdString.h>
|
||||
|
||||
CDirectInput::CDirectInput(HINSTANCE hinst) :
|
||||
m_hDirectInputDLL(nullptr),
|
||||
m_pDIHandle(nullptr),
|
||||
m_hinst(hinst),
|
||||
m_hWnd(nullptr)
|
||||
{
|
||||
LoadConfig();
|
||||
if (m_hDirectInputDLL == nullptr)
|
||||
{
|
||||
m_hDirectInputDLL = LoadLibrary(L"dinput8.dll");
|
||||
}
|
||||
if (m_hDirectInputDLL != nullptr)
|
||||
{
|
||||
typedef HRESULT(WINAPI *tylpGetDIHandle)(HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN);
|
||||
tylpGetDIHandle lpGetDIHandle = (tylpGetDIHandle)GetProcAddress(m_hDirectInputDLL, "DirectInput8Create");
|
||||
|
||||
if (lpGetDIHandle != NULL)
|
||||
{
|
||||
HRESULT hr = lpGetDIHandle(m_hinst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&m_pDIHandle, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pDIHandle != nullptr)
|
||||
{
|
||||
m_pDIHandle->EnumDevices(DI8DEVCLASS_ALL, stEnumMakeDeviceList, this, DIEDFL_ATTACHEDONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CDirectInput::~CDirectInput()
|
||||
{
|
||||
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
|
||||
{
|
||||
if (itr->second.didHandle != nullptr)
|
||||
{
|
||||
itr->second.didHandle->Release();
|
||||
itr->second.didHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDirectInput::Initiate(CONTROL_INFO * ControlInfo)
|
||||
{
|
||||
m_hWnd = (HWND)ControlInfo->hwnd;
|
||||
}
|
||||
|
||||
BOOL CDirectInput::stEnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
|
||||
{
|
||||
return ((CDirectInput *)pvRef)->EnumMakeDeviceList(lpddi);
|
||||
}
|
||||
|
||||
BOOL CDirectInput::EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi)
|
||||
{
|
||||
uint32_t DeviceType = GET_DIDEVICE_TYPE(lpddi->dwDevType);
|
||||
if (DeviceType == DI8DEVTYPE_DEVICE)
|
||||
{
|
||||
// ignore generic devices
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
DEVICE Device;
|
||||
Device.didHandle = nullptr;
|
||||
Device.dwDevType = lpddi->dwDevType;
|
||||
Device.ProductName = stdstr().FromUTF16(lpddi->tszProductName);
|
||||
Device.InstanceName = stdstr().FromUTF16(lpddi->tszInstanceName);
|
||||
HRESULT hResult = m_pDIHandle->CreateDevice(lpddi->guidInstance, &Device.didHandle, NULL);
|
||||
if (!SUCCEEDED(hResult))
|
||||
{
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
LPCDIDATAFORMAT ppDiDataFormat = NULL;
|
||||
if (DeviceType == DI8DEVTYPE_KEYBOARD)
|
||||
{
|
||||
ppDiDataFormat = &c_dfDIKeyboard;
|
||||
}
|
||||
else if (DeviceType == DI8DEVTYPE_MOUSE)
|
||||
{
|
||||
ppDiDataFormat = &c_dfDIMouse2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppDiDataFormat = &c_dfDIJoystick;
|
||||
}
|
||||
hResult = Device.didHandle->SetDataFormat(ppDiDataFormat);
|
||||
if (!SUCCEEDED(hResult))
|
||||
{
|
||||
Device.didHandle->Release();
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
hResult = Device.didHandle->SetCooperativeLevel(m_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
|
||||
if (!SUCCEEDED(hResult))
|
||||
{
|
||||
Device.didHandle->Release();
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
std::pair<DEVICE_MAP::iterator, bool> res = m_Devices.insert(DEVICE_MAP::value_type(lpddi->guidInstance, Device));
|
||||
if (!res.second)
|
||||
{
|
||||
Device.didHandle->Release();
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
CDirectInput::ScanResult CDirectInput::ScanDevices(BUTTON & Button)
|
||||
{
|
||||
ScanResult Result = SCAN_FAILED;
|
||||
|
||||
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
|
||||
{
|
||||
DEVICE &device = itr->second;
|
||||
if (device.didHandle == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (FAILED(device.didHandle->Poll()))
|
||||
{
|
||||
device.didHandle->Acquire();
|
||||
}
|
||||
}
|
||||
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
|
||||
{
|
||||
DEVICE &device = itr->second;
|
||||
if (device.didHandle == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint8_t DeviceType = LOBYTE(device.dwDevType);
|
||||
if (DeviceType == DI8DEVTYPE_KEYBOARD)
|
||||
{
|
||||
Result = ScanKeyboard(device.didHandle, Button);
|
||||
}
|
||||
else if (DeviceType == DI8DEVTYPE_MOUSE)
|
||||
{
|
||||
//dwReturn = ScanMouse(&g_devList[i], lpdwCounter, pButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dwReturn = ScanGamePad(&g_devList[i], lpdwCounter, pButton, i);
|
||||
}
|
||||
|
||||
if (Result != SCAN_FAILED)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::wstring CDirectInput::ButtonAssignment(BUTTON & Button)
|
||||
{
|
||||
if (Button.BtnType == BTNTYPE_KEYBUTTON)
|
||||
{
|
||||
DEVICE_MAP::iterator itr = m_Devices.find(GUID_SysKeyboard);
|
||||
if (itr != m_Devices.end())
|
||||
{
|
||||
DIDEVICEOBJECTINSTANCE didoi;
|
||||
didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
|
||||
if (itr->second.didHandle->GetObjectInfo(&didoi, Button.Offset, DIPH_BYOFFSET) == DI_OK)
|
||||
{
|
||||
return didoi.tszName;
|
||||
}
|
||||
return L"Keyboard: ???";
|
||||
}
|
||||
}
|
||||
else if (Button.BtnType == BTNTYPE_UNASSIGNED)
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
return L"Unknown";
|
||||
}
|
||||
|
||||
CDirectInput::ScanResult CDirectInput::ScanKeyboard(LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton)
|
||||
{
|
||||
if (didHandle == nullptr)
|
||||
{
|
||||
return SCAN_FAILED;
|
||||
}
|
||||
uint8_t cKeys[256];
|
||||
HRESULT hr = didHandle->GetDeviceState(sizeof(cKeys), cKeys);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
didHandle->Acquire();
|
||||
return SCAN_FAILED;
|
||||
}
|
||||
|
||||
for (size_t i = 0, n = sizeof(cKeys) / sizeof(cKeys[0]); i < n; i++)
|
||||
{
|
||||
if ((cKeys[i] & 0x80) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i == DIK_ESCAPE)
|
||||
{
|
||||
return SCAN_ESCAPE;
|
||||
}
|
||||
pButton.Offset = (uint8_t)i;
|
||||
pButton.AxisID = 0;
|
||||
pButton.BtnType = BTNTYPE_KEYBUTTON;
|
||||
return SCAN_SUCCEED;
|
||||
}
|
||||
return SCAN_FAILED;
|
||||
}
|
||||
|
||||
void CDirectInput::LoadConfig(void)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
#include "ControllerSpec1.1.h"
|
||||
#include "Button.h"
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <Windows.h>
|
||||
#include <dinput.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class CDirectInput
|
||||
{
|
||||
public:
|
||||
enum ScanResult
|
||||
{
|
||||
SCAN_FAILED = 0x00,
|
||||
SCAN_SUCCEED = 0x01,
|
||||
SCAN_ESCAPE = 0x10,
|
||||
};
|
||||
|
||||
CDirectInput(HINSTANCE hinst);
|
||||
~CDirectInput();
|
||||
|
||||
void Initiate(CONTROL_INFO * ControlInfo);
|
||||
ScanResult ScanDevices(BUTTON & Button);
|
||||
std::wstring ButtonAssignment(BUTTON & Button);
|
||||
|
||||
private:
|
||||
CDirectInput();
|
||||
CDirectInput(const CDirectInput&);
|
||||
CDirectInput& operator=(const CDirectInput&);
|
||||
|
||||
static BOOL CALLBACK stEnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
|
||||
BOOL EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi);
|
||||
ScanResult ScanKeyboard(LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton);
|
||||
void LoadConfig(void);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 didHandle;
|
||||
uint32_t dwDevType;
|
||||
std::string InstanceName;
|
||||
std::string ProductName;
|
||||
} DEVICE;
|
||||
|
||||
struct GUIDComparer
|
||||
{
|
||||
bool operator()(const GUID & Left, const GUID & Right) const
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(Right)) < 0;
|
||||
}
|
||||
};
|
||||
typedef std::map<GUID, DEVICE, GUIDComparer> DEVICE_MAP;
|
||||
|
||||
DEVICE_MAP m_Devices;
|
||||
HMODULE m_hDirectInputDLL;
|
||||
LPDIRECTINPUT8 m_pDIHandle;
|
||||
HINSTANCE m_hinst;
|
||||
HWND m_hWnd;
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
#include "InputConfigUI.h"
|
||||
#include "CProject64Input.h"
|
||||
#include "wtl.h"
|
||||
#include "wtl-BitmapPicture.h"
|
||||
#include "wtl-ScanButton.h"
|
||||
#include <Common\stdtypes.h>
|
||||
#include <Common\StdString.h>
|
||||
#include "resource.h"
|
||||
|
@ -8,43 +10,81 @@
|
|||
class CControllerSettings :
|
||||
public CPropertyPageImpl<CControllerSettings>
|
||||
{
|
||||
enum
|
||||
{
|
||||
DETECT_KEY_TIMER = 1
|
||||
};
|
||||
public:
|
||||
enum { IDD = IDD_Controller };
|
||||
|
||||
BEGIN_MSG_MAP(CDebugSettings)
|
||||
MSG_WM_INITDIALOG(OnInitDialog)
|
||||
MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic)
|
||||
CHAIN_MSG_MAP(CPropertyPageImpl<CControllerSettings>)
|
||||
END_MSG_MAP()
|
||||
|
||||
CControllerSettings();
|
||||
void SetControllerNumber(uint32_t ControllerNumber);
|
||||
CControllerSettings(uint32_t ControllerNumber);
|
||||
BOOL OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/);
|
||||
HBRUSH OnCtlColorStatic(CDCHandle dc, CWindow wndStatic);
|
||||
|
||||
private:
|
||||
std::wstring m_Title;
|
||||
uint32_t m_ControllerNumber;
|
||||
uint32_t m_ScanCount;
|
||||
CBitmapPicture m_ControllerImg;
|
||||
CScanButton ButtonUDPad, ButtonDDPad, ButtonLDPad, ButtonRDPad;
|
||||
CScanButton ButtonCUp, ButtonCDown, ButtonCLeft, ButtonCRight;
|
||||
CScanButton ButtonA, ButtonB;
|
||||
};
|
||||
|
||||
CControllerSettings::CControllerSettings() :
|
||||
m_ControllerNumber((uint32_t)-1)
|
||||
{
|
||||
}
|
||||
|
||||
void CControllerSettings::SetControllerNumber(uint32_t ControllerNumber)
|
||||
CControllerSettings::CControllerSettings(uint32_t ControllerNumber) :
|
||||
m_ControllerNumber(ControllerNumber),
|
||||
m_ScanCount(0),
|
||||
ButtonUDPad(g_InputPlugin->Controllers(ControllerNumber).U_DPAD, IDC_EDIT_DIGITIAL_UP, IDC_BTN_DIGITIAL_UP),
|
||||
ButtonDDPad(g_InputPlugin->Controllers(ControllerNumber).D_DPAD, IDC_EDIT_DIGITIAL_DOWN, IDC_BTN_DIGITIAL_DOWN),
|
||||
ButtonLDPad(g_InputPlugin->Controllers(ControllerNumber).L_DPAD, IDC_EDIT_DIGITIAL_LEFT, IDC_BTN_DIGITIAL_LEFT),
|
||||
ButtonRDPad(g_InputPlugin->Controllers(ControllerNumber).R_DPAD, IDC_EDIT_DIGITIAL_RIGHT, IDC_BTN_DIGITIAL_RIGHT),
|
||||
ButtonA(g_InputPlugin->Controllers(ControllerNumber).A_BUTTON, IDC_EDIT_BUTTON_A, IDC_BTN_BUTTON_A),
|
||||
ButtonB(g_InputPlugin->Controllers(ControllerNumber).B_BUTTON, IDC_EDIT_BUTTON_B, IDC_BTN_BUTTON_B),
|
||||
ButtonCUp(g_InputPlugin->Controllers(ControllerNumber).U_CBUTTON, IDC_EDIT_CBUTTON_UP, IDC_BTN_CBUTTON_UP),
|
||||
ButtonCDown(g_InputPlugin->Controllers(ControllerNumber).D_CBUTTON, IDC_EDIT_CBUTTON_DOWN, IDC_BTN_CBUTTON_DOWN),
|
||||
ButtonCLeft(g_InputPlugin->Controllers(ControllerNumber).L_CBUTTON, IDC_EDIT_CBUTTON_LEFT, IDC_BTN_CBUTTON_LEFT),
|
||||
ButtonCRight(g_InputPlugin->Controllers(ControllerNumber).R_CBUTTON, IDC_EDIT_CBUTTON_RIGHT, IDC_BTN_CBUTTON_RIGHT)
|
||||
{
|
||||
m_Title = stdstr_f("Player %d", ControllerNumber + 1).ToUTF16();
|
||||
SetTitle(m_Title.c_str());
|
||||
m_ControllerNumber = ControllerNumber;
|
||||
}
|
||||
|
||||
BOOL CControllerSettings::OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
|
||||
{
|
||||
m_ControllerImg.SubclassWindow(GetDlgItem(IDC_BMP_CONTROLLER));
|
||||
m_ControllerImg.SetBitmap(MAKEINTRESOURCE(IDB_CONTROLLER));
|
||||
ButtonUDPad.SubclassWindow(m_hWnd);
|
||||
ButtonDDPad.SubclassWindow(m_hWnd);
|
||||
ButtonLDPad.SubclassWindow(m_hWnd);
|
||||
ButtonRDPad.SubclassWindow(m_hWnd);
|
||||
ButtonA.SubclassWindow(m_hWnd);
|
||||
ButtonB.SubclassWindow(m_hWnd);
|
||||
ButtonCUp.SubclassWindow(m_hWnd);
|
||||
ButtonCDown.SubclassWindow(m_hWnd);
|
||||
ButtonCLeft.SubclassWindow(m_hWnd);
|
||||
ButtonCRight.SubclassWindow(m_hWnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HBRUSH CControllerSettings::OnCtlColorStatic(CDCHandle dc, CWindow wndStatic)
|
||||
{
|
||||
if (g_InputPlugin->IsScanning() && wndStatic.GetDlgCtrlID() == g_InputPlugin->DisplayCtrlId())
|
||||
{
|
||||
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
|
||||
return ::GetSysColorBrush(COLOR_HIGHLIGHT);
|
||||
}
|
||||
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
|
||||
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
|
||||
return ::GetSysColorBrush(COLOR_WINDOW);
|
||||
}
|
||||
|
||||
class CInputConfigUI:
|
||||
public CPropertySheetImpl<CInputConfigUI>
|
||||
{
|
||||
|
@ -55,7 +95,7 @@ public:
|
|||
void OnSheetInitialized();
|
||||
|
||||
private:
|
||||
CControllerSettings m_pgController[4];
|
||||
CControllerSettings m_pgController0, m_pgController1, m_pgController2, m_pgController3;
|
||||
};
|
||||
|
||||
void ConfigInput(void * hParent)
|
||||
|
@ -63,14 +103,17 @@ void ConfigInput(void * hParent)
|
|||
CInputConfigUI().DoModal((HWND)hParent);
|
||||
}
|
||||
|
||||
CInputConfigUI::CInputConfigUI()
|
||||
CInputConfigUI::CInputConfigUI() :
|
||||
m_pgController0(0),
|
||||
m_pgController1(1),
|
||||
m_pgController2(2),
|
||||
m_pgController3(3)
|
||||
{
|
||||
m_psh.pszCaption = L"Configure Input";
|
||||
for (size_t i = 0, n = sizeof(m_pgController) / sizeof(m_pgController[0]); i < n; i++)
|
||||
{
|
||||
m_pgController[i].SetControllerNumber(i);
|
||||
AddPage(&m_pgController[i].m_psp);
|
||||
}
|
||||
AddPage(&m_pgController0.m_psp);
|
||||
AddPage(&m_pgController1.m_psp);
|
||||
AddPage(&m_pgController2.m_psp);
|
||||
AddPage(&m_pgController3.m_psp);
|
||||
}
|
||||
|
||||
CInputConfigUI::~CInputConfigUI()
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "ControllerSpec1.1.h"
|
||||
#include "InputConfigUI.h"
|
||||
#include "Version.h"
|
||||
#include "CProject64Input.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/******************************************************************
|
||||
|
@ -121,8 +122,12 @@ EXPORT void CALL GetKeys(int32_t /*Control*/, BUTTONS * /*Keys*/)
|
|||
the emulator to know how to handle each controller.
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL InitiateControllers(CONTROL_INFO * /*ControlInfo*/)
|
||||
EXPORT void CALL InitiateControllers(CONTROL_INFO * ControlInfo)
|
||||
{
|
||||
if (g_InputPlugin != nullptr)
|
||||
{
|
||||
g_InputPlugin->InitiateControllers(ControlInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -185,4 +190,20 @@ EXPORT void CALL WM_KeyUp(uint32_t /*wParam*/, uint32_t /*lParam*/)
|
|||
|
||||
EXPORT void CALL PluginLoaded(void)
|
||||
{
|
||||
}
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
extern "C" int WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
g_InputPlugin = new CProject64Input(hinst);
|
||||
}
|
||||
else if (fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
delete g_InputPlugin;
|
||||
g_InputPlugin = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include "Button.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BUTTON U_DPAD;
|
||||
BUTTON D_DPAD;
|
||||
BUTTON L_DPAD;
|
||||
BUTTON R_DPAD;
|
||||
BUTTON A_BUTTON;
|
||||
BUTTON B_BUTTON;
|
||||
BUTTON U_CBUTTON;
|
||||
BUTTON D_CBUTTON;
|
||||
BUTTON L_CBUTTON;
|
||||
BUTTON R_CBUTTON;
|
||||
BUTTON START_BUTTON;
|
||||
BUTTON Z_TRIG;
|
||||
BUTTON R_TRIG;
|
||||
BUTTON L_TRIG;
|
||||
} N64CONTROLLER;
|
|
@ -45,17 +45,35 @@
|
|||
<PreBuildEvent>
|
||||
<Command>"$(SolutionDir)Source\Script\UpdateVersion.cmd" "$(Configuration)" "$(Platform)" "$(SolutionDir)Source\Project64-input\Version.h.in" "$(SolutionDir)Source\Project64-input\Version.h"</Command>
|
||||
</PreBuildEvent>
|
||||
<Link>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">dinput8.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Root)Source\3rdParty\directx\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<Link>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">dinput8.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Root)Source\3rdParty\directx\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DirectInput.cpp" />
|
||||
<ClCompile Include="InputConfigUI.cpp" />
|
||||
<ClCompile Include="InputMain.cpp" />
|
||||
<ClCompile Include="CProject64Input.cpp" />
|
||||
<ClCompile Include="wtl-BitmapPicture.cpp" />
|
||||
<ClCompile Include="wtl-ScanButton.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Button.h" />
|
||||
<ClInclude Include="N64Controller.h" />
|
||||
<ClInclude Include="DirectInput.h" />
|
||||
<ClInclude Include="InputConfigUI.h" />
|
||||
<ClInclude Include="ControllerSpec1.1.h" />
|
||||
<ClInclude Include="CProject64Input.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="wtl-BitmapPicture.h" />
|
||||
<ClInclude Include="wtl-ScanButton.h" />
|
||||
<ClInclude Include="wtl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -24,6 +24,15 @@
|
|||
<ClCompile Include="wtl-BitmapPicture.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CProject64Input.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectInput.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wtl-ScanButton.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ControllerSpec1.1.h">
|
||||
|
@ -41,6 +50,21 @@
|
|||
<ClInclude Include="wtl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CProject64Input.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DirectInput.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wtl-ScanButton.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Button.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64Controller.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Version.h.in">
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#define STRINGIZE2(s) #s
|
||||
#define STRINGIZE(s) STRINGIZE2(s)
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 0
|
||||
#define VERSION_BUILD 9999
|
||||
#define GIT_VERSION ""
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
#include "wtl-ScanButton.h"
|
||||
#include "CProject64Input.h"
|
||||
#include <Common\StdString.h>
|
||||
#include <time.h>
|
||||
|
||||
CScanButton::CScanButton(BUTTON & Button, int DisplayCtrlId, int ScanBtnId) :
|
||||
m_Button(Button),
|
||||
m_DisplayCtrlId(DisplayCtrlId),
|
||||
m_ScanBtnId(ScanBtnId),
|
||||
m_ScanBtnProc(nullptr),
|
||||
m_ScanCount(0),
|
||||
m_ScanStart(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CScanButton::SubclassWindow(CWindow Wnd)
|
||||
{
|
||||
m_DisplayCtrl = Wnd.GetDlgItem(m_DisplayCtrlId);
|
||||
m_ScanBtn = Wnd.GetDlgItem(m_ScanBtnId);
|
||||
m_ScanBtnThunk.Init((WNDPROC)ScanButtonProc, this);
|
||||
m_ScanBtnProc = (WNDPROC)m_ScanBtn.SetWindowLongPtrW(GWLP_WNDPROC, (LONG_PTR)m_ScanBtnThunk.GetWNDPROC());
|
||||
DisplayButton();
|
||||
}
|
||||
|
||||
void CScanButton::DisplayButton(void)
|
||||
{
|
||||
m_DisplayCtrl.SetWindowText(g_InputPlugin->ButtonAssignment(m_Button).c_str());
|
||||
}
|
||||
|
||||
void CScanButton::OnScan(void)
|
||||
{
|
||||
enum
|
||||
{
|
||||
SACN_INTERVAL = 20
|
||||
};
|
||||
m_ScanCount = 0;
|
||||
time(&m_ScanStart);
|
||||
g_InputPlugin->StartScanDevices(m_DisplayCtrlId);
|
||||
m_DisplayCtrl.Invalidate();
|
||||
m_ScanBtn.SetTimer(DETECT_KEY_TIMER, SACN_INTERVAL, NULL);
|
||||
MakeOverlay();
|
||||
}
|
||||
|
||||
void CScanButton::OnTimer(UINT_PTR nIDEvent)
|
||||
{
|
||||
if (nIDEvent == DETECT_KEY_TIMER)
|
||||
{
|
||||
bool Stop = false;
|
||||
if (g_InputPlugin)
|
||||
{
|
||||
CDirectInput::ScanResult Result = g_InputPlugin->ScanDevices(m_Button);
|
||||
if (Result == CDirectInput::SCAN_SUCCEED)
|
||||
{
|
||||
Stop = true;
|
||||
DisplayButton();
|
||||
}
|
||||
}
|
||||
if ((m_ScanCount % 30) == 0)
|
||||
{
|
||||
CWindow Dialog = m_ScanBtn.GetParent().GetParent();
|
||||
time_t Now = time(nullptr);
|
||||
if (10 - (Now - m_ScanStart) > 0)
|
||||
{
|
||||
Dialog.SetWindowText(stdstr_f("Configure Input: Press Key ... (%d seconds)", 10 - (Now - m_ScanStart)).ToUTF16().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop = true;
|
||||
}
|
||||
}
|
||||
if (m_ScanCount > 500)
|
||||
{
|
||||
Stop = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ScanCount += 1;
|
||||
}
|
||||
|
||||
if (Stop)
|
||||
{
|
||||
m_ScanBtn.KillTimer(DETECT_KEY_TIMER);
|
||||
CWindow Dialog = m_ScanBtn.GetParent().GetParent();
|
||||
Dialog.SetWindowText(L"Configure Input");
|
||||
|
||||
m_Overlay.DestroyWindow();
|
||||
m_Overlay = NULL;
|
||||
|
||||
g_InputPlugin->EndScanDevices();
|
||||
m_DisplayCtrl.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScanButton::MakeOverlay(void)
|
||||
{
|
||||
WNDCLASS wc = { 0 };
|
||||
wc.lpfnWndProc = (WNDPROC)BlockerProc;
|
||||
wc.hInstance = g_InputPlugin->hInst();
|
||||
wc.lpszClassName = L"BlockerClass";
|
||||
RegisterClass(&wc);
|
||||
|
||||
CWindow ControllerDlg = m_ScanBtn.GetParent().GetParent();
|
||||
CRect size;
|
||||
ControllerDlg.GetWindowRect(&size);
|
||||
m_Overlay = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT, L"BlockerClass", L"Blocker", WS_POPUP, size.left, size.top, size.Width(), size.Height(), ControllerDlg, nullptr, g_InputPlugin->hInst(), NULL);
|
||||
if (m_Overlay == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Overlay.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
UINT_PTR CALLBACK CScanButton::ScanButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CScanButton * _this = (CScanButton*)hWnd;
|
||||
UINT_PTR uRet = 0;
|
||||
if (uMsg == WM_LBUTTONUP)
|
||||
{
|
||||
POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
_this->m_ScanBtn.ClientToScreen(&ptCursor);
|
||||
|
||||
RECT rect = { 0 };
|
||||
_this->m_ScanBtn.GetWindowRect(&rect);
|
||||
if (PtInRect(&rect, ptCursor))
|
||||
{
|
||||
_this->OnScan();
|
||||
}
|
||||
}
|
||||
else if (uMsg == WM_TIMER)
|
||||
{
|
||||
_this->OnTimer((UINT_PTR)wParam);
|
||||
}
|
||||
if (_this->m_ScanBtnProc != nullptr)
|
||||
{
|
||||
uRet = _this->m_ScanBtnProc(_this->m_ScanBtn, uMsg, wParam, lParam);
|
||||
}
|
||||
return uRet;
|
||||
}
|
||||
|
||||
|
||||
UINT_PTR CALLBACK CScanButton::BlockerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_CREATE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (msg == WM_PAINT)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd, &ps);
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
#include "wtl.h"
|
||||
#include "Button.h"
|
||||
|
||||
class CScanButton
|
||||
{
|
||||
enum
|
||||
{
|
||||
DETECT_KEY_TIMER = 1
|
||||
};
|
||||
|
||||
public:
|
||||
CScanButton(BUTTON & Button, int DisplayCtrlId, int ScanBtnId);
|
||||
|
||||
void SubclassWindow(CWindow Wnd);
|
||||
|
||||
private:
|
||||
CScanButton(void);
|
||||
CScanButton(const CScanButton&);
|
||||
CScanButton& operator=(const CScanButton&);
|
||||
|
||||
void DisplayButton(void);
|
||||
void OnScan(void);
|
||||
void OnTimer(UINT_PTR nIDEvent);
|
||||
void MakeOverlay(void);
|
||||
static UINT_PTR CALLBACK ScanButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static UINT_PTR CALLBACK BlockerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
BUTTON & m_Button;
|
||||
int32_t m_DisplayCtrlId, m_ScanBtnId;
|
||||
CWindow m_DisplayCtrl, m_ScanBtn;
|
||||
CWndProcThunk m_ScanBtnThunk;
|
||||
WNDPROC m_ScanBtnProc;
|
||||
uint32_t m_ScanCount;
|
||||
time_t m_ScanStart;
|
||||
CWindow m_Overlay;
|
||||
};
|
Loading…
Reference in New Issue