6 #pragma comment(lib, "dinput8.lib") 7 #pragma comment(lib, "dxguid.lib") 24 IDirectInput8 *ptmpDi;
26 reinterpret_cast<void **>(&ptmpDi), NULL);
27 checkDXResult<DIError>(hr,
"DirectInput8Create() failed");
32 IDirectInputDevice8 *ptmpKeyDevice;
33 hr = m_pDi->CreateDevice(GUID_SysKeyboard, &ptmpKeyDevice, NULL);
34 checkDXResult<DIError>(hr,
"IDirectInput8::CreateDevice() failed");
35 m_pKeyDevice.reset(ptmpKeyDevice);
37 hr = m_pKeyDevice->SetDataFormat(&c_dfDIKeyboard);
38 checkDXResult<DIError>(hr,
"IDirectInputDevice8::SetDataFormat() failed");
39 DWORD coopLevel = DISCL_NOWINKEY;
40 coopLevel |= (foreground ? DISCL_FOREGROUND : DISCL_BACKGROUND);
41 coopLevel |= (exclusive ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE);
42 hr = m_pKeyDevice->SetCooperativeLevel(hWnd, coopLevel);
43 checkDXResult<DIError>(hr,
"IDirectInputDevice8::SetCooperativeLevel() failed");
55 m_pKeyDevice->Unacquire();
56 for (
auto &dev : m_pPadDevs) {
65 BOOL CALLBACK enumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
67 std::vector<DIDEVICEINSTANCE> *devs =
reinterpret_cast<decltype(devs)
>(pvRef);
68 devs->emplace_back(*lpddi);
69 return DIENUM_CONTINUE;
72 BOOL CALLBACK enumAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
74 DIPROPRANGE range = { 0 };
75 range.diph.dwSize =
sizeof(range);
76 range.diph.dwHeaderSize =
sizeof(range.diph);
77 range.diph.dwHow = DIPH_BYID;
78 range.diph.dwObj = lpddoi->dwType;
81 IDirectInputDevice8 *pdev =
reinterpret_cast<decltype(pdev)
>(pvRef);
82 pdev->SetProperty(DIPROP_RANGE, &range.diph);
83 return DIENUM_CONTINUE;
94 m_padInstList.clear();
97 hr = m_pDi->EnumDevices(DI8DEVCLASS_GAMECTRL, enumDevicesCallback,
98 &m_padInstList, DIEDFL_ATTACHEDONLY);
99 checkDXResult<DIError>(hr,
"IDirectInput8::EnumDevices() failed");
101 for (
const auto &padInst : m_padInstList) {
102 IDirectInputDevice8 *ptmpDevice;
103 hr = m_pDi->CreateDevice(padInst.guidInstance, &ptmpDevice,
nullptr);
104 checkDXResult<DIError>(hr,
"IDirectInput8::CreateDevice() failed");
107 hr = pDevice->SetDataFormat(&c_dfDIJoystick);
108 checkDXResult<DIError>(hr,
"IDirectInputDevice8::SetDataFormat() failed");
110 coopLevel |= (foreground ? DISCL_FOREGROUND : DISCL_BACKGROUND);
111 coopLevel |= (exclusive ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE);
112 hr = pDevice->SetCooperativeLevel(hwnd, coopLevel);
113 checkDXResult<DIError>(hr,
"IDirectInputDevice8::SetCooperativeLevel() failed");
114 hr = pDevice->EnumObjects(enumAxesCallback, pDevice.get(), DIDFT_AXIS);
115 checkDXResult<DIError>(hr,
"IDirectInputDevice8::EnumObjects() failed");
117 m_pPadDevs.emplace_back(std::move(pDevice));
118 DIJOYSTATE js = { 0 };
119 m_pad.emplace_back(js);
124 for (
const auto &padInst : m_padInstList) {
126 debug::writef(L
"tszInstanceName = %s", padInst.tszInstanceName);
127 debug::writef(L
"tszProductName = %s", padInst.tszProductName);
130 debug::writef(L
"%zu controller(s) found", m_pPadDevs.size());
141 hr = m_pKeyDevice->Acquire();
142 }
while (hr == DIERR_INPUTLOST);
143 if (hr != DIERR_OTHERAPPHASPRIO) {
145 hr = m_pKeyDevice->GetDeviceState(
sizeof(tmp), &tmp);
147 for (
int i = 0; i < 256; i++) {
148 m_key[i] = ((tmp[i] & 0x80) != 0);
160 for (
size_t i = 0; i < m_pPadDevs.size(); i++) {
161 ZeroMemory(&m_pad[i],
sizeof(m_pad[i]));
162 memset(m_pad[i].rgdwPOV, -1,
sizeof(m_pad[i].rgdwPOV));
165 hr = m_pPadDevs[i]->Acquire();
166 }
while (hr == DIERR_INPUTLOST);
167 if (hr == DIERR_OTHERAPPHASPRIO) {
171 hr = m_pPadDevs[i]->Poll();
172 hr = m_pPadDevs[i]->GetDeviceState(
sizeof(m_pad[i]), &m_pad[i]);
184 ASSERT(m_pad.size() == m_pPadDevs.size());
185 return static_cast<int>(m_pPadDevs.size());
190 *state = m_pad.at(index);
196 struct DikConvEntry {
201 #define ENT(s) {s, L##s} 216 ENT(
"APOST"),
ENT(
"GRAVE"),
ENT(
"LSHIFT"),
ENT(
"BSLASH"),
220 ENT(
"PERIOD"),
ENT(
"SLASH"),
ENT(
"RSHIFT"),
ENT(
"MULT"),
225 ENT(
"F10"),
ENT(
"NUMLOCK"),
ENT(
"SCROLL"),
ENT(
"NUMPAD7"),
226 ENT(
"NUMPAD8"),
ENT(
"NUMPAD9"),
ENT(
"SUB"),
ENT(
"NUMPAD4"),
227 ENT(
"NUMPAD5"),
ENT(
"NUMPAD6"),
ENT(
"ADD"),
ENT(
"NUMPAD1"),
229 ENT(
"NUMPAD2"),
ENT(
"NUMPAD3"),
ENT(
"NUMPAD0"),
ENT(
"DECIMAL"),
259 ENT(
"VOLUP"),
ENT(
"?"),
ENT(
"WEBHOME"),
ENT(
"NUMPADCM"),
276 ENT(
"WEBSTOP"),
ENT(
"WEBFWD"),
ENT(
"WEBBACK"),
ENT(
"MYCOM"),
290 if (dik < 0 || dik >= 256) {
291 throw std::logic_error(
"invalid DIK");
293 return DikConvTable[dik].str;
298 if (dik < 0 || dik >= 256) {
299 throw std::logic_error(
"invalid DIK");
301 return DikConvTable[dik].wstr;
void writef(const wchar_t *fmt,...) noexcept
Write debug message using format string like printf.
#define ASSERT(x)
Assertion which uses debug framework.
void checkDXResult(HRESULT hr, const std::string &msg)
void writeLine(const wchar_t *str=L"") noexcept
Write debug string and new line.
std::unique_ptr< T, ComDeleter > ComPtr
unique_ptr of IUnknown with ComDeleter.