void Input::Exit (bool fReInit_/*=false*/) { TRACE("Input::Exit(%d)\n", fReInit_); if (pdiKeyboard) { pdiKeyboard->Unacquire(); pdiKeyboard->Release(); pdiKeyboard = NULL; } if (pdidJoystick1) { pdidJoystick1->Unacquire(); pdidJoystick1->Release(); pdidJoystick1 = NULL; } if (pdidJoystick2) { pdidJoystick2->Unacquire(); pdidJoystick2->Release(); pdidJoystick2 = NULL; } if (pdi) { pdi->Release(); pdi = NULL; } Keyboard::Exit(fReInit_); }
void Joystick_DX5::RequestExclusive(bool value) { if(value != have_exclusive_access) { if(value && SUCCEEDED(dev->SetCooperativeLevel(GetDesktopWindow(), DISCL_BACKGROUND | DISCL_EXCLUSIVE)) && SUCCEEDED(dev->Acquire())) have_exclusive_access = true; else { have_exclusive_access = false; dev->SetCooperativeLevel(GetDesktopWindow(), DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); dev->Acquire(); } } }
void ReadJoystick (int nJoystick_, LPDIRECTINPUTDEVICE2 pDevice_) { HRESULT hr; int i; DIJOYSTATE dijs = { 0 }; if (pDevice_ && (FAILED(hr = pDevice_->Poll()) || FAILED(hr = pDevice_->GetDeviceState(sizeof(dijs), &dijs)))) { if (FAILED(hr = pDevice_->Acquire())) return; if (FAILED(hr = pDevice_->Poll()) || FAILED(hr = pDevice_->GetDeviceState(sizeof(dijs), &dijs))) TRACE("!!! Failed to read joystick %d state (%#08lx)\n", nJoystick_, hr); } DWORD dwButtons = 0; int nPosition = HJ_CENTRE; // Combine the states of all buttons so any button works as fire for (i = 0 ; i < _countof(dijs.rgbButtons) ; i++) { if (dijs.rgbButtons[i] & 0x80) dwButtons |= (1 << i); } // Set the position from the main axes if (dijs.lX < 0 || dijs.lRx < 0) nPosition |= HJ_LEFT; if (dijs.lX > 0 || dijs.lRx > 0) nPosition |= HJ_RIGHT; if (dijs.lY < 0 || dijs.lRy < 0) nPosition |= HJ_UP; if (dijs.lY > 0 || dijs.lRy > 0) nPosition |= HJ_DOWN; // Consider all hat positions too for (i = 0 ; i < _countof(dijs.rgdwPOV) ; i++) { static int an[] = { HJ_UP, HJ_UP|HJ_RIGHT, HJ_RIGHT, HJ_DOWN|HJ_RIGHT, HJ_DOWN, HJ_DOWN|HJ_LEFT, HJ_LEFT, HJ_UP|HJ_LEFT }; // For best driver compatibility, only check the low WORD for the centre position if (LOWORD(dijs.rgdwPOV[i]) == 0xffff) continue; // Round the position and determine which of the 8 directions it's pointing int nPos = ((dijs.rgdwPOV[i] + 4500/2) / 4500) & 7; nPosition |= an[nPos]; } Joystick::SetPosition(nJoystick_, nPosition); Joystick::SetButtons(nJoystick_, dwButtons); }
//=========================================================================== // DIUtilPollJoystick // // Polls the joystick device and returns the device state. // // Parameters: // LPDIRECTINPUTDEVICE2 pdiDevice2 - ptr to device object // DIJOYSTATE *pdijs - ptr to store joystick state // // Returns: HRESULT // //=========================================================================== HRESULT DIUtilPollJoystick(LPDIRECTINPUTDEVICE2 pdiDevice2, DIJOYSTATE *pdijs) { HRESULT hRes = E_NOTIMPL; // validate pointers if( (IsBadReadPtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) || (IsBadWritePtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) ) { ERROUT(TEXT("DIUtilPollJoystick() - invalid pdiDevice2\n")); return E_POINTER; } if( (IsBadReadPtr((void*)pdijs, sizeof(DIJOYSTATE))) || (IsBadWritePtr((void*)pdijs, sizeof(DIJOYSTATE))) ) { ERROUT(TEXT("DIUtilPollJoystick() - invalid pdijs\n")); return E_POINTER; } // clear the pdijs memory // // this way, if we fail, we return no data ZeroMemory(pdijs, sizeof(DIJOYSTATE)); // poll the joystick // // don't worry if it fails, not all devices require polling hRes = pdiDevice2->Poll(); // query the device state hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs); if(FAILED(hRes)) { ERROUT(TEXT("DIUtilPollJoystick() - GetDeviceState() failed\n")); return hRes; } // done return hRes; } //*** end DIUtilPollJoystick()
bool InitJoystick (LPDIRECTINPUTDEVICE2 &pJoystick_) { HRESULT hr; // Set the joystick device to use the joystick format if (FAILED(hr = pJoystick_->SetDataFormat(&c_dfDIJoystick))) TRACE("!!! Failed to set data format of joystick device (%#08lx)\n", hr); else if (FAILED(hr = pJoystick_->SetCooperativeLevel(g_hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND))) TRACE("!!! Failed to set cooperative level of joystick device (%#08lx)\n", hr); else { // Deadzone tolerance percentage and range of each axis (-100 to +100) DIPROPDWORD diPdw = { { sizeof(diPdw), sizeof(diPdw.diph), 0, DIPH_BYOFFSET }, 10000UL * JOYSTICK_DEADZONE / 100UL }; DIPROPRANGE diPrg = { { sizeof(diPrg), sizeof(diPrg.diph), 0, DIPH_BYOFFSET }, -100, +100 }; int anAxes[] = { DIJOFS_X, DIJOFS_Y, DIJOFS_RX, DIJOFS_RY }; for (int i = 0 ; i < _countof(anAxes) ; i++) { diPdw.diph.dwObj = diPrg.diph.dwObj = anAxes[i]; if (FAILED(hr = pJoystick_->SetProperty(DIPROP_DEADZONE, &diPdw.diph))) TRACE("!!! Failed to set joystick deadzone (%#08lx)\n", hr); else if (FAILED(hr = pJoystick_->SetProperty(DIPROP_RANGE, &diPrg.diph))) TRACE("!!! Failed to set joystick range (%#08lx)\n", hr); } return true; } // Clean up pJoystick_->Release(); pJoystick_ = NULL; return false; }
//=========================================================================== // DIUtilGetHIDDevice // // Helper function to get the file handle of the related HID device // LPDIRECTINPUTDEVICE2 pdiDevice2 - ptr to device object // PHANDLE hDriver - ptr to recieve device handle // Returns: HRESULT // //=========================================================================== HRESULT DIUtilGetHIDDevice(LPDIRECTINPUTDEVICE2 pdiDevice2, HANDLE *hDriver) { HRESULT hRes = E_NOTIMPL; DIPROPGUIDANDPATH dipgp; // validate pointers if( (IsBadReadPtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) || (IsBadWritePtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) ) { ERROUT(TEXT("DIUtilGetHIDDevice() - invalid pdiDevice2\n")); return E_POINTER; } // Initialize structure dipgp.diph.dwSize = sizeof(DIPROPGUIDANDPATH); dipgp.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipgp.diph.dwObj = 0; dipgp.diph.dwHow = DIPH_DEVICE; // Get the path hRes = pdiDevice2->GetProperty(DIPROP_GUIDANDPATH, &dipgp.diph); if(FAILED(hRes)) { ERROUT(TEXT("DIUtilGetHIDDevice() - GetProperty() failed\n")); return hRes; } *hDriver = CreateFile(dipgp.wszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(!hDriver) { ERROUT(TEXT("DIUtilGetHIDDevice() - Can't open device\n")); return E_FAIL; } return hRes; } //*** end DIUtilGetHIDDevice()
// TODO: RequestExclusive(false) when SetRumble() hasn't been called for several seconds. void Joystick_DX5::UpdateInternal(void) { DIJOYSTATE2 js; HRESULT hres; if(DevCaps.dwFlags & (DIDC_POLLEDDEVICE | DIDC_POLLEDDATAFORMAT)) { do { /* */ hres = dev->Poll(); /* */ } while((hres == DIERR_INPUTLOST) && ((hres = dev->Acquire()) == DI_OK)); if(hres != DI_OK) return; } do { /* */ hres = dev->GetDeviceState(sizeof(js), &js); /* */ } while((hres == DIERR_INPUTLOST) && ((hres = dev->Acquire()) == DI_OK)); if(hres != DI_OK) return; for(unsigned button = 0; button < DevCaps.dwButtons; button++) { button_state[button] = (bool)(js.rgbButtons[button] & 0x80); } for(unsigned axis = 0; axis < DIAxisInfo.size(); axis++) { int64 rv = (&js.lX)[DIAxisInfo[axis].jd_logical_offset]; rv = (((rv - DIAxisInfo[axis].minimum) * 32767 * 2) / (DIAxisInfo[axis].maximum - DIAxisInfo[axis].minimum)) - 32767; if(rv < -32767) rv = -32767; if(rv > 32767) rv = 32767; axis_state[axis] = rv; } for(unsigned hat = 0; hat < DevCaps.dwPOVs; hat++) { DWORD hat_val = js.rgdwPOV[hat]; //if((uint16)hat_val == 0xFFFF) // Reportedly some drivers report 0xFFFF instead of 0xFFFFFFFF? (comment from byuu) if(hat_val >= 36000) { axis_state[(DIAxisInfo.size() + hat * 2) + 0] = 0; axis_state[(DIAxisInfo.size() + hat * 2) + 1] = 0; } else { int32 x, y; //axis_state[(DIAxisInfo.size() + hat * 2) + 0] = 32767 * sin((double)M_PI * 2 * hat_val / 36000); // x //axis_state[(DIAxisInfo.size() + hat * 2) + 1] = 32767 * -cos((double)M_PI * 2 * hat_val / 36000); // y unsigned octant = (hat_val / 4500) & 0x7; signed octant_doff = hat_val % 4500; switch(octant) { case 0: x = octant_doff * 32767 / 4500; y = -32767; break; case 1: x = 32767; y = (-4500 + octant_doff) * 32767 / 4500; break; case 2: x = 32767; y = octant_doff * 32767 / 4500; break; case 3: x = (4500 - octant_doff) * 32767 / 4500; y = 32767; break; case 4: x = (-octant_doff) * 32767 / 4500; y = 32767; break; case 5: x = -32767; y = (4500 - octant_doff) * 32767 / 4500; break; case 6: x = -32767; y = (-octant_doff) * 32767 / 4500; break; case 7: x = (-4500 + octant_doff) * 32767 / 4500; y = -32767; break; } axis_state[(DIAxisInfo.size() + hat * 2) + 0] = x; axis_state[(DIAxisInfo.size() + hat * 2) + 1] = y; } } }