// enumerate the dinput devices int __stdcall plDInputMgr::EnumGamepadCallback(const DIDEVICEINSTANCE* device, void* pRef) { HRESULT hr; plDInput* pDI = (plDInput*)pRef; IDirectInputDevice8* fStick = nil; hr = pDI->fDInput->CreateDevice(device->guidInstance, &fStick, NULL); if(!FAILED(hr)) { pDI->fSticks.Append(new plDIDevice(fStick)); // the following code pertaining to the action map shouldn't be here. // in fact this shouldn't work at all according to MS, but this is // currently the only way this works. Whatever - the correct // code is here and commented out in case this ever gets fixed by MS // in a future release of dinput. HRESULT hr = fStick->BuildActionMap(pDI->fActionFormat, NULL, NULL); if (!FAILED(hr)) { hr = fStick->SetActionMap( pDI->fActionFormat, NULL, NULL ); DIPROPDWORD dipW; dipW.diph.dwSize = sizeof(DIPROPDWORD); dipW.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipW.diph.dwHow = DIPH_DEVICE; dipW.diph.dwObj = 0; dipW.dwData = 500; // 5% of axis range for deadzone hr = fStick->SetProperty(DIPROP_DEADZONE , &dipW.diph); } return DIENUM_CONTINUE; } return DIENUM_STOP; }
// Callback that adjusts all found axes to [-stickRange, +stickRange]. static BOOL CALLBACK axisCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPVOID userData) { IDirectInputDevice8* dev = static_cast<IDirectInputDevice8*>(userData); DIPROPRANGE range; range.diph.dwSize = sizeof(DIPROPRANGE); range.diph.dwHeaderSize = sizeof(DIPROPHEADER); range.diph.dwHow = DIPH_BYID; range.diph.dwObj = instance->dwType; range.lMin = -stickRange; range.lMax = +stickRange; dev->SetProperty(DIPROP_RANGE, &range.diph); return DIENUM_CONTINUE; }
Gosu::Input::Input(HWND window) : pimpl(new Impl) { pimpl->window = window; pimpl->mouseFactorX = pimpl->mouseFactorY = 1.0; // Create the main input object (only necessary for setup). IDirectInput8* inputRaw; Impl::check("creating the main DirectInput object", ::DirectInput8Create(Win::instance(), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void**>(&inputRaw), 0)); pimpl->input = Win::shareComPtr(inputRaw); // Prepare property struct for setting the amount of data to buffer. DIPROPDWORD bufferSize; bufferSize.diph.dwSize = sizeof(DIPROPDWORD); bufferSize.diph.dwHeaderSize = sizeof(DIPROPHEADER); bufferSize.diph.dwHow = DIPH_DEVICE; bufferSize.diph.dwObj = 0; bufferSize.dwData = Impl::inputBufferSize; // Set up the system keyboard. IDirectInputDevice8* kbRaw; Impl::check("creating the keyboard device object", pimpl->input->CreateDevice(GUID_SysKeyboard, &kbRaw, 0)); pimpl->keyboard = Win::shareComPtr(kbRaw); Impl::check("setting the keyboard's data format", kbRaw->SetDataFormat(&c_dfDIKeyboard)); Impl::check("setting the keyboard's cooperative level", kbRaw->SetCooperativeLevel(window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)); Impl::check("setting the keyboard's buffer size", kbRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph)); kbRaw->Acquire(); // Set up the system mouse. IDirectInputDevice8* mouseRaw; Impl::check("creating the mouse device object", pimpl->input->CreateDevice(GUID_SysMouse, &mouseRaw, 0)); pimpl->mouse = Win::shareComPtr(mouseRaw); Impl::check("setting the mouse's data format", mouseRaw->SetDataFormat(&c_dfDIMouse)); Impl::check("setting the mouse's cooperative level", mouseRaw->SetCooperativeLevel(window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)); Impl::check("setting the mouse's buffer size", mouseRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph)); mouseRaw->Acquire(); pimpl->swapMouse = ::GetSystemMetrics(SM_SWAPBUTTON) != 0; // Set up all gamepads. pimpl->input->EnumDevices(DI8DEVCLASS_GAMECTRL, Impl::gamepadCallback, pimpl.get(), DIEDFL_ATTACHEDONLY); // Get into a usable default state. pimpl->mouseX = pimpl->mouseY = 0; pimpl->updateMousePos(); buttons.assign(false); }
HRESULT _stdcall SetProperty(REFGUID a,const DIPROPHEADER* b) { return RealDevice->SetProperty(a,b); }