diff --git a/BeefLibs/Beefy2D/src/input/InputManager.bf b/BeefLibs/Beefy2D/src/input/InputManager.bf new file mode 100644 index 00000000..37fad069 --- /dev/null +++ b/BeefLibs/Beefy2D/src/input/InputManager.bf @@ -0,0 +1,49 @@ +using System; + +namespace Beefy.input +{ + class InputDevice + { + [CallingConvention(.Stdcall), CLink] + public static extern void BFInput_Destroy(void* nativeInputDevice); + + [CallingConvention(.Stdcall), CLink] + public static extern char8* BFInput_GetState(void* nativeInputDevice); + + void* mNativeInputDevice; + + public ~this() + { + BFInput_Destroy(mNativeInputDevice); + } + + public void GetState(String outStr) + { + outStr.Append(BFInput_GetState(mNativeInputDevice)); + } + } + + class InputManager + { + [CallingConvention(.Stdcall), CLink] + public static extern char8* BFApp_EnumerateInputDevices(); + + [CallingConvention(.Stdcall), CLink] + public static extern void* BFApp_CreateInputDevice(char8* guid); + + public void EnumerateInputDevices(String outData) + { + outData.Append(BFApp_EnumerateInputDevices()); + } + + public InputDevice CreateInputDevice(StringView guid) + { + void* nativeInputDevice = BFApp_CreateInputDevice(guid.ToScopeCStr!()); + if (nativeInputDevice == null) + return null; + InputDevice inputDevice = new .(); + inputDevice.[Friend]mNativeInputDevice = nativeInputDevice; + return inputDevice; + } + } +} diff --git a/BeefySysLib/platform/win/DInputManager.cpp b/BeefySysLib/platform/win/DInputManager.cpp new file mode 100644 index 00000000..18aed566 --- /dev/null +++ b/BeefySysLib/platform/win/DInputManager.cpp @@ -0,0 +1,128 @@ +#include "DInputManager.h" +#include "WinBFApp.h" + +#pragma comment (lib, "dinput8.lib") +#pragma comment (lib, "dxguid.lib") + +USING_NS_BF; + +static BOOL DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + DInputManager* _this = (DInputManager*)pvRef; + + _this->mEnumData += StrFormat("%s\t%s", UTF8Encode(lpddi->tszInstanceName).c_str(), UTF8Encode(lpddi->tszProductName).c_str()); + + auto guid = lpddi->guidInstance; + _this->mEnumData += StrFormat("\t%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + + //OutputDebugStrF("Device: %s %s\n", lpddi->tszInstanceName, lpddi->tszProductName); + + _this->mEnumData += "\n"; + + return TRUE; +} + +DInputManager::DInputManager() +{ + mDirectInput = NULL; + //TODO: This doesn't work for DLLs + DirectInput8Create(::GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&mDirectInput, NULL); + + if (mDirectInput == NULL) + return; +} + +DInputManager::~DInputManager() +{ + mDirectInput->Release(); +} + +DInputDevice* DInputManager::CreateInputDevice(const StringImpl& guidStr) +{ + UUID guid = { 0 }; + UuidFromStringA((RPC_CSTR)guidStr.c_str(), &guid); + + LPDIRECTINPUTDEVICE8 device = NULL; + mDirectInput->CreateDevice(guid, &device, NULL); + + if (device == NULL) + return NULL; + + HRESULT result = 0; + + DInputDevice* inputDevice = new DInputDevice(); + inputDevice->mDirectInputDevice = device; + + WinBFWindow* window = NULL; + for (auto checkWindow : gBFApp->mWindowList) + { + window = (WinBFWindow*)checkWindow; + break; + } + + if (window != NULL) + { + result = device->SetCooperativeLevel(window->mHWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); + } + + result = device->SetDataFormat(&c_dfDIJoystick2); + + return inputDevice; +} + +String DInputManager::EnumerateDevices() +{ + mEnumData.Clear(); + if (mDirectInput != NULL) + mDirectInput->EnumDevices(DI8DEVCLASS_ALL, DIEnumDevicesCallback, this, DIEDFL_ATTACHEDONLY); + return mEnumData; +} + +DInputDevice::~DInputDevice() +{ + mDirectInputDevice->Release(); +} + +String DInputDevice::GetState() +{ + DIJOYSTATE2 joyState = { 0 }; + HRESULT result = mDirectInputDevice->Poll(); + if (FAILED(result)) + { + result = mDirectInputDevice->Acquire(); + while (result == DIERR_INPUTLOST) + result = mDirectInputDevice->Acquire(); + } + + result = mDirectInputDevice->GetDeviceState(sizeof(joyState), &joyState); + + String str; + if (!FAILED(result)) + { + if (joyState.lX != 0) + str += StrFormat("X\t%d\n", joyState.lX); + if (joyState.lY != 0) + str += StrFormat("Y\t%d\n", joyState.lY); + if (joyState.lZ != 0) + str += StrFormat("Z\t%d\n", joyState.lZ); + + //str += StrFormat("X\t%d\nY\t%d\nZ\t%d\n", joyState.lX, joyState.lY, joyState.lZ); + + for (int i = 0; i < 128; i++) + { + if (joyState.rgbButtons[i] != 0) + { + str += StrFormat("Btn\t%d\n", i); + } + } + } + else + { + str += "!FAILED"; + } + + return str; +} diff --git a/BeefySysLib/platform/win/DInputManager.h b/BeefySysLib/platform/win/DInputManager.h new file mode 100644 index 00000000..c503f2a3 --- /dev/null +++ b/BeefySysLib/platform/win/DInputManager.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../BeefySysLib/Common.h" +#include "../../BeefySysLib/BFApp.h" + +#define DIRECTINPUT_VERSION 0x0800 +#include + +NS_BF_BEGIN + +class DInputDevice : public BFInputDevice +{ +public: + LPDIRECTINPUTDEVICE8 mDirectInputDevice; + +public: + ~DInputDevice(); + virtual String GetState() override; +}; + +class DInputManager +{ +public: + LPDIRECTINPUT8 mDirectInput; + String mEnumData; + +public: + DInputManager(); + ~DInputManager(); + + String EnumerateDevices(); + DInputDevice* CreateInputDevice(const StringImpl& guid); +}; + +NS_BF_END \ No newline at end of file