#include "mungal4.h" #pragma hdrstop #include "l4dinput.h" #define DI_TRIGGER 0 #define DI_THUMB1 2 #define DI_THUMB2 1 #define DI_THUMB3 3 DIJoystick::DIJoystick(HINSTANCE hInstance, HWND hWnd) { mDI = NULL; mJoystick = NULL; if (SUCCEEDED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&mDI, NULL))) { mDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, this, DIEDFL_ATTACHEDONLY); if (mJoystick) if (SUCCEEDED(mJoystick->SetDataFormat(&c_dfDIJoystick2))) if (SUCCEEDED(mJoystick->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND))) if (SUCCEEDED(mJoystick->EnumObjects(EnumAxesCallback, this, DIDFT_AXIS))) return; } if (mDI) { mDI->Release(); mDI = NULL; } if (mJoystick) { mJoystick->Release(); mJoystick = NULL; } } DIJoystick::~DIJoystick() { if (mJoystick) { mJoystick->Unacquire(); mJoystick->Release(); mJoystick = NULL; } if (mDI) { mDI->Release(); mDI = NULL; } } BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext) { DIJoystick *joystick = (DIJoystick*)pContext; if (FAILED(joystick->mDI->CreateDevice(pdidInstance->guidInstance, &joystick->mJoystick, NULL))) return DIENUM_CONTINUE; return DIENUM_STOP; } BOOL CALLBACK EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { DIJoystick *joystick = (DIJoystick*)pvRef; DIPROPRANGE diprg; diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYID; diprg.diph.dwObj = lpddoi->dwType; diprg.lMax = diprg.lMax = 0; if (lpddoi->guidType == GUID_XAxis) { if (SUCCEEDED(joystick->mJoystick->GetProperty(DIPROP_RANGE, &diprg.diph))) { joystick->xAxisMin = diprg.lMin; joystick->xAxisMax = diprg.lMax; } } else if (lpddoi->guidType == GUID_YAxis) { if (SUCCEEDED(joystick->mJoystick->GetProperty(DIPROP_RANGE, &diprg.diph))) { joystick->yAxisMin = diprg.lMin; joystick->yAxisMax = diprg.lMax; } } else if (lpddoi->guidType == GUID_ZAxis) { if (SUCCEEDED(joystick->mJoystick->GetProperty(DIPROP_RANGE, &diprg.diph))) { joystick->zAxisMin = diprg.lMin; joystick->zAxisMax = diprg.lMax; } } else if (lpddoi->guidType == GUID_RxAxis) { } else if (lpddoi->guidType == GUID_RyAxis) { } else if (lpddoi->guidType == GUID_RzAxis) { if (SUCCEEDED(joystick->mJoystick->GetProperty(DIPROP_RANGE, &diprg.diph))) { joystick->rzAxisMin = diprg.lMin; joystick->rzAxisMax = diprg.lMax; } } else if (lpddoi->guidType == GUID_Slider) { if (SUCCEEDED(joystick->mJoystick->GetProperty(DIPROP_RANGE, &diprg.diph))) { joystick->zAxisMin = diprg.lMin; joystick->zAxisMax = diprg.lMax; } } return DIENUM_CONTINUE; } bool DIJoystick::Poll() { HRESULT hr; if (mJoystick) { hr = mJoystick->Poll(); if (FAILED(hr)) { DEBUG_STREAM << "Poll failed: HR = " << hr << std::endl << std::flush; hr = mJoystick->Acquire(); while (hr == DIERR_INPUTLOST) { DEBUG_STREAM << "Acquire failed: HR = " << hr << std::endl << std::flush; hr = mJoystick->Acquire(); } return false; } if (FAILED(hr = mJoystick->GetDeviceState(sizeof(DIJOYSTATE2), &mJoystate))) { DEBUG_STREAM << "GetState failed: HR = " << hr << std::endl << std::flush; return false; } } return true; } void DIJoystick::Update() { if (Poll()) { // Handle analog data Value.x = ((Scalar)(mJoystate.lX - xAxisMin) / (Scalar)(xAxisMax - xAxisMin)) * 2.0f - 1.0f; Value.y = ((Scalar)(mJoystate.lY - yAxisMin) / (Scalar)(yAxisMax - yAxisMin)) * 2.0f - 1.0f; LONG z = (mJoystate.lZ == 0 ? mJoystate.rglSlider[0] : mJoystate.lZ); ExtendedValue.y = 1.0f - (Scalar)(z - zAxisMin) / (Scalar)(zAxisMax - zAxisMin); // full left rotation = 0, center rotation = 1/2 range, full right = full range LONG rot = (Scalar)(mJoystate.lRz - rzAxisMin); Scalar half = (Scalar)(rzAxisMax - rzAxisMin) / 2.0f; Rotation.x = (Scalar)0; Rotation.y = (Scalar)0; if (rot <= half) Rotation.x = ((half - rot) / half) * 470.0; else Rotation.y = ((rot - half) / half) * 470.0; // Handle button changes int newButtons = 0; if (mJoystate.rgbButtons[DI_TRIGGER]) newButtons |= Joystick::Trigger; if (mJoystate.rgbButtons[DI_THUMB1]) newButtons |= Joystick::Thumb1; if (mJoystate.rgbButtons[DI_THUMB2]) newButtons |= Joystick::Thumb2; if (mJoystate.rgbButtons[DI_THUMB3]) newButtons |= Joystick::Thumb3; if (mJoystate.rgdwPOV[0] == 0) newButtons |= Joystick::HatUp; if (mJoystate.rgdwPOV[0] == 9000) newButtons |= Joystick::HatRight; if (mJoystate.rgdwPOV[0] == 18000) newButtons |= Joystick::HatDown; if (mJoystate.rgdwPOV[0] == 27000) newButtons |= Joystick::HatLeft; ButtonPressed = (oldButtons ^ newButtons) & newButtons; ButtonReleased = (oldButtons ^ newButtons) & oldButtons; oldButtons = newButtons; } }