diff --git a/Source/Project64-input/CProject64Input.cpp b/Source/Project64-input/CProject64Input.cpp index 67acfde76..0b193d71d 100644 --- a/Source/Project64-input/CProject64Input.cpp +++ b/Source/Project64-input/CProject64Input.cpp @@ -6,7 +6,8 @@ CProject64Input * g_InputPlugin = nullptr; CProject64Input::CProject64Input(HINSTANCE hinst) : m_hinst(hinst), m_Scanning(false), - m_DisplayCtrlId(0) + m_DisplayCtrlId(0), + m_iFirstController(0) { memset(m_Controllers, 0, sizeof(m_Controllers)); } @@ -30,6 +31,34 @@ void CProject64Input::InitiateControllers(CONTROL_INFO * ControlInfo) } } +void CProject64Input::GetKeys(int32_t Control, BUTTONS * Keys) +{ + if (Control >= sizeof(m_Controllers) / sizeof(m_Controllers[0])) + { + return; + } + CGuard guard(m_CS); + if (Control == m_iFirstController) + { + m_DirectInput->UpdateDeviceData(); + } + N64CONTROLLER & Controller = m_Controllers[Control]; + Keys->R_DPAD = m_DirectInput->IsButtonPressed(Controller.R_DPAD); + Keys->L_DPAD = m_DirectInput->IsButtonPressed(Controller.L_DPAD); + Keys->D_DPAD = m_DirectInput->IsButtonPressed(Controller.D_DPAD); + Keys->U_DPAD = m_DirectInput->IsButtonPressed(Controller.U_DPAD); + Keys->START_BUTTON = m_DirectInput->IsButtonPressed(Controller.START_BUTTON); + Keys->Z_TRIG = m_DirectInput->IsButtonPressed(Controller.Z_TRIG); + Keys->B_BUTTON = m_DirectInput->IsButtonPressed(Controller.B_BUTTON); + Keys->A_BUTTON = m_DirectInput->IsButtonPressed(Controller.A_BUTTON); + Keys->R_CBUTTON = m_DirectInput->IsButtonPressed(Controller.R_CBUTTON); + Keys->L_CBUTTON = m_DirectInput->IsButtonPressed(Controller.L_CBUTTON); + Keys->D_CBUTTON = m_DirectInput->IsButtonPressed(Controller.D_CBUTTON); + Keys->U_CBUTTON = m_DirectInput->IsButtonPressed(Controller.U_CBUTTON); + Keys->R_TRIG = m_DirectInput->IsButtonPressed(Controller.R_TRIG); + Keys->L_TRIG = m_DirectInput->IsButtonPressed(Controller.L_TRIG); +} + void CProject64Input::StartScanDevices(int32_t DisplayCtrlId) { m_Scanning = true; diff --git a/Source/Project64-input/CProject64Input.h b/Source/Project64-input/CProject64Input.h index d88317826..b7183d8d8 100644 --- a/Source/Project64-input/CProject64Input.h +++ b/Source/Project64-input/CProject64Input.h @@ -12,6 +12,7 @@ public: ~CProject64Input(); void InitiateControllers(CONTROL_INFO * ControlInfo); + void GetKeys(int32_t Control, BUTTONS * Keys); void StartScanDevices(int32_t DisplayCtrlId); void EndScanDevices(void); CDirectInput::ScanResult ScanDevices(BUTTON & Button); @@ -34,6 +35,7 @@ private: HINSTANCE m_hinst; bool m_Scanning; int32_t m_DisplayCtrlId; + int32_t m_iFirstController; }; extern CProject64Input * g_InputPlugin; \ No newline at end of file diff --git a/Source/Project64-input/DirectInput.cpp b/Source/Project64-input/DirectInput.cpp index 542ce81e6..743e804d9 100644 --- a/Source/Project64-input/DirectInput.cpp +++ b/Source/Project64-input/DirectInput.cpp @@ -102,7 +102,7 @@ BOOL CDirectInput::EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi) return DIENUM_CONTINUE; } - DEVICE Device; + DEVICE Device = { 0 }; Device.didHandle = nullptr; Device.dwDevType = lpddi->dwDevType; Device.ProductName = stdstr().FromUTF16(lpddi->tszProductName); @@ -173,7 +173,7 @@ CDirectInput::ScanResult CDirectInput::ScanDevices(BUTTON & Button) uint8_t DeviceType = LOBYTE(device.dwDevType); if (DeviceType == DI8DEVTYPE_KEYBOARD) { - Result = ScanKeyboard(device.didHandle, Button); + Result = ScanKeyboard(itr->first, device.didHandle, Button); } else if (DeviceType == DI8DEVTYPE_MOUSE) { @@ -215,7 +215,51 @@ std::wstring CDirectInput::ButtonAssignment(BUTTON & Button) return L"Unknown"; } -CDirectInput::ScanResult CDirectInput::ScanKeyboard(LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton) +bool CDirectInput::IsButtonPressed(BUTTON & Button) +{ + if (Button.Device == nullptr) + { + return false; + } + DEVICE & Device = *(DEVICE *)Button.Device; + switch (Button.BtnType) + { + case BTNTYPE_KEYBUTTON: + return (Device.State.Keyboard[Button.Offset] & 0x80) != 0; + } + return false; +} + +void CDirectInput::UpdateDeviceData(void) +{ + for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++) + { + DEVICE & device = itr->second; + LPDIRECTINPUTDEVICE8 & didHandle = device.didHandle; + if (didHandle == nullptr) + { + continue; + } + if (FAILED(didHandle->Poll()) && !AcquireDevice(didHandle)) + { + continue; + } + + switch (LOBYTE(device.dwDevType)) + { + case DI8DEVTYPE_KEYBOARD: + didHandle->GetDeviceState(sizeof(device.State.Keyboard), &device.State.Keyboard); + break; + case DI8DEVTYPE_MOUSE: + didHandle->GetDeviceState(sizeof(device.State.Mouse), &device.State.Mouse); + break; + default: + didHandle->GetDeviceState(sizeof(device.State.Joy), &device.State.Joy); + } + } +} + +CDirectInput::ScanResult CDirectInput::ScanKeyboard(const GUID & DeviceGuid, LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton) { if (didHandle == nullptr) { @@ -242,11 +286,35 @@ CDirectInput::ScanResult CDirectInput::ScanKeyboard(LPDIRECTINPUTDEVICE8 didHand pButton.Offset = (uint8_t)i; pButton.AxisID = 0; pButton.BtnType = BTNTYPE_KEYBUTTON; + pButton.DeviceGuid = DeviceGuid; + pButton.Device = nullptr; return SCAN_SUCCEED; } return SCAN_FAILED; } +bool CDirectInput::AcquireDevice(LPDIRECTINPUTDEVICE8 lpDirectInputDevice) +{ + HRESULT hResult = lpDirectInputDevice->Acquire(); + if (hResult == DIERR_INPUTLOST) + { + for (uint32_t i = 0; i < 10; i++) + { + hResult = lpDirectInputDevice->Acquire(); + if (hResult != DIERR_INPUTLOST) + { + break; + } + } + } + if (SUCCEEDED(hResult)) + { + lpDirectInputDevice->Poll(); + return true; + } + return false; +} + void CDirectInput::LoadConfig(void) { diff --git a/Source/Project64-input/DirectInput.h b/Source/Project64-input/DirectInput.h index 8a03a8b9a..b33178a73 100644 --- a/Source/Project64-input/DirectInput.h +++ b/Source/Project64-input/DirectInput.h @@ -25,6 +25,8 @@ public: void MapControllerDevice(N64CONTROLLER & Controller); ScanResult ScanDevices(BUTTON & Button); std::wstring ButtonAssignment(BUTTON & Button); + bool IsButtonPressed(BUTTON & Button); + void UpdateDeviceData(void); private: CDirectInput(); @@ -33,7 +35,8 @@ private: static BOOL CALLBACK stEnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); BOOL EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi); - ScanResult ScanKeyboard(LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton); + ScanResult ScanKeyboard(const GUID & DeviceGuid, LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton); + bool AcquireDevice(LPDIRECTINPUTDEVICE8 lpDirectInputDevice); void LoadConfig(void); typedef struct @@ -42,6 +45,12 @@ private: uint32_t dwDevType; std::string InstanceName; std::string ProductName; + union INPUTSTATE + { + DIJOYSTATE Joy; + DIMOUSESTATE2 Mouse; + uint8_t Keyboard[256]; + } State; } DEVICE; struct GUIDComparer diff --git a/Source/Project64-input/InputMain.cpp b/Source/Project64-input/InputMain.cpp index 7472783c5..8a3b4bcdd 100644 --- a/Source/Project64-input/InputMain.cpp +++ b/Source/Project64-input/InputMain.cpp @@ -112,8 +112,9 @@ input: - Controller Number (0 to 3) the controller state. output: none *******************************************************************/ -EXPORT void CALL GetKeys(int32_t /*Control*/, BUTTONS * /*Keys*/) +EXPORT void CALL GetKeys(int32_t Control, BUTTONS * Keys) { + g_InputPlugin->GetKeys(Control, Keys); } /******************************************************************