| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- #ifndef _XBOX
- #include "JoystickDevice.h"
- #include "..\..\common_h\Render.h"
- #include "..\..\common_h\controls.h"
- const long AxisMaxValue = 10000;
- JoystickDevice::JoystickDevice(IDirectInput8A* di, const DIDEVICEINSTANCEA& deviceInst, const ControlsIniParser& parser) :
- m_Device(NULL),
- m_Controls(__FILE__, __LINE__)
- {
- Assert(di);
- di->CreateDevice(deviceInst.guidInstance, &m_Device, NULL);
- Assert(m_Device);
- HWND hWnd = (HWND)api->Storage().GetLong("system.hWnd");
- // m_Device->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
- m_Device->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE);
- DIDEVCAPS deviceCaps = {0};
- deviceCaps.dwSize = sizeof(deviceCaps);
- m_Device->GetCapabilities(&deviceCaps);
- // ставим предельное число, т.к. трактуем оси иначе чем DirectInput
- // (24 обычных оси + 8 осей для слайдеров)
- m_NumAxes = 24+8;
- m_NumButtons = deviceCaps.dwButtons;
- m_NumPOVs = deviceCaps.dwPOVs;
- // Установить мин/макс значения для осей
- DIPROPRANGE diprg;
- diprg.diph.dwSize = sizeof(DIPROPRANGE);
- diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- diprg.diph.dwHow = DIPH_BYID;
- for (unsigned int i = 0; i < m_NumAxes; ++i)
- {
- diprg.diph.dwObj = DIDFT_ABSAXIS | (i << 8);
- diprg.lMin = -AxisMaxValue;
- diprg.lMax = AxisMaxValue;
- m_Device->SetProperty( DIPROP_RANGE, &diprg.diph );
- }
- HRESULT hr = m_Device->SetDataFormat(&c_dfDIJoystick2);
- hr=m_Device->Acquire();
- if (parser.GetMappingTable(deviceInst.tszProductName).items.Size() > 0)
- InitControls(parser.GetMappingTable(deviceInst.tszProductName));
- else
- InitControls(parser.GetMappingTable("Default"));
- DIPROPDWORD dip;
- dip.diph.dwSize = sizeof(DIPROPDWORD);
- dip.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- dip.diph.dwObj = 0;
- dip.diph.dwHow = DIPH_DEVICE;
- dip.dwData = FALSE;
- m_Device->SetProperty(DIPROP_AUTOCENTER,&dip.diph);
- lef = NULL;
- ref = NULL;
- DWORD rgdwAxes [2] = {DIJOFS_X,DIJOFS_Y};
- LONG rglDirection[2] = {0,0};
- DIRAMPFORCE cf = {0,0};
- DIEFFECT eff; ZeroMemory(&eff,sizeof(eff));
- eff.dwSize = sizeof(DIEFFECT);
- eff.dwFlags = DIEFF_CARTESIAN|DIEFF_OBJECTOFFSETS;
- eff.dwDuration = INFINITE;
- eff.dwSamplePeriod = 0;
- eff.dwGain = DI_FFNOMINALMAX;
- eff.dwTriggerButton = DIEB_NOTRIGGER;
- eff.dwTriggerRepeatInterval = 0;
- // eff.cAxes = axesN;
- eff.cAxes = 2;
- eff.rgdwAxes = rgdwAxes;
- eff.rglDirection = rglDirection;
- eff.lpEnvelope = 0;
- eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
- eff.lpvTypeSpecificParams = &cf;
- eff.dwStartDelay = 0;
- eff.dwDuration = INFINITE;
- m_Device->CreateEffect(GUID_RampForce,&eff,&lef,NULL);
- m_Device->CreateEffect(GUID_RampForce,&eff,&ref,NULL);
- if( lef ) lef->Start(1,0);
- if( ref ) ref->Start(1,0);
- }
- JoystickDevice::~JoystickDevice()
- {
- if (m_Device)
- {
- m_Device->Unacquire();
- m_Device->Release();
- m_Device = NULL;
- }
- // if( lef ) lef->Release();
- // if( ref ) ref->Release();
- }
- unsigned int JoystickDevice::GetAxisDataOffset(unsigned int index)
- {
- DIJOYSTATE2 state;
-
- unsigned int Offsets[] =
- {
- (char*)&(state.lX) - (char*)&state,
- (char*)&(state.lY) - (char*)&state,
- (char*)&(state.lZ) - (char*)&state,
- (char*)&(state.lRx) - (char*)&state,
- (char*)&(state.lRy) - (char*)&state,
- (char*)&(state.lRz) - (char*)&state,
- (char*)&(state.rglSlider[0]) - (char*)&state,
- (char*)&(state.rglSlider[1]) - (char*)&state,
-
- (char*)&(state.lVX) - (char*)&state,
- (char*)&(state.lVY) - (char*)&state,
- (char*)&(state.lVZ) - (char*)&state,
- (char*)&(state.lVRx) - (char*)&state,
- (char*)&(state.lVRy) - (char*)&state,
- (char*)&(state.lVRz) - (char*)&state,
- (char*)&(state.rglVSlider[0]) - (char*)&state,
- (char*)&(state.rglVSlider[1]) - (char*)&state,
-
- (char*)&(state.lAX) - (char*)&state,
- (char*)&(state.lAY) - (char*)&state,
- (char*)&(state.lAZ) - (char*)&state,
- (char*)&(state.lARx) - (char*)&state,
- (char*)&(state.lARy) - (char*)&state,
- (char*)&(state.lARz) - (char*)&state,
- (char*)&(state.rglASlider[0]) - (char*)&state,
- (char*)&(state.rglASlider[1]) - (char*)&state,
- (char*)&(state.lFX) - (char*)&state,
- (char*)&(state.lFY) - (char*)&state,
- (char*)&(state.lFZ) - (char*)&state,
- (char*)&(state.lFRx) - (char*)&state,
- (char*)&(state.lFRy) - (char*)&state,
- (char*)&(state.lFRz) - (char*)&state,
- (char*)&(state.rglFSlider[0]) - (char*)&state,
- (char*)&(state.rglFSlider[1]) - (char*)&state,
- };
- return Offsets[index];
- }
- float JoystickDevice::GetButtonData(unsigned int dataOffset)
- {
- unsigned char value = *(unsigned char*)(((char*)&m_Data) + dataOffset);
- return (float)((value & 0x80) >> 7);
- }
- float JoystickDevice::GetAxisData(JoystickDevice::Control::Type axisType, unsigned int dataOffset)
- {
- long value = *(long*)(((char*)&m_Data) + dataOffset);
- if (abs(value) < AxisMaxValue/10)
- return 0.0f;
- return value / (float)AxisMaxValue;
- }
- float JoystickDevice::GetPOVData(unsigned int dataOffset, bool isPovH)
- {
- long value = *(long*)(((char*)&m_Data) + dataOffset);
- if ( (LOWORD(value) == 0xFFFF) ) return 0.0f;
- if (isPovH)
- {
- float ret[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f };
- return ret[value / 4500];
- }
- else
- {
- float ret[] = { 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, 1.0f };
- return ret[value / 4500];
- }
- }
- static const char* GetMappedName(const char* hwName, const ControlsIniParser::Table& table, bool& inverted)
- {
- string s1, s2;
- for (unsigned int i = 0; i < table.items.Size(); ++i)
- {
- s1 = table.items[i].hwName;
- s2 = hwName;
- s1.Upper();
- s2.Upper();
- if (s1.FindSubStr(s2) != -1)
- {
- inverted = s1[0] == '-';
- return table.items[i].logName.c_str();
- }
- }
- inverted = false;
- return hwName;
- }
- void JoystickDevice::InitControls( const ControlsIniParser::Table& table )
- {
- Control ctrl;
- ctrl.value = 0.0f;
- ctrl.type = Control::Button;
- DIJOYSTATE2 state;
- for (unsigned int i = 0; i < m_NumButtons; ++i)
- {
- ctrl.name.Format("hw_b%d", i+1);
- ctrl.name = GetMappedName(ctrl.name, table, ctrl.inverted);
- ctrl.dataOffset = (char*)&(state.rgbButtons[i]) - (char*)&state;
- m_Controls.Add(ctrl);
- }
- for (unsigned int i = 0; i < m_NumAxes; ++i)
- {
- ctrl.name.Format("hw_Axis%d", i+1);
- ctrl.name = GetMappedName(ctrl.name, table, ctrl.inverted);
- ctrl.dataOffset = GetAxisDataOffset(i);
- ctrl.type = Control::Axis;
- m_Controls.Add(ctrl);
- }
- for (unsigned int i = 0; i < m_NumPOVs; ++i)
- {
- ctrl.type = Control::POV_H;
- ctrl.name.Format("hw_PovH%d", i+1);
- ctrl.name = GetMappedName(ctrl.name, table, ctrl.inverted);
- ctrl.dataOffset = (char*)&(state.rgdwPOV[i]) - (char*)&state;
- m_Controls.Add(ctrl);
- ctrl.type = Control::POV_V;
- ctrl.name.Format("hw_PovV%d", i+1);
- ctrl.name = GetMappedName(ctrl.name, table, ctrl.inverted);
- ctrl.dataOffset = (char*)&(state.rgdwPOV[i]) - (char*)&state;
- m_Controls.Add(ctrl);
- }
- ///////////////////////////////
- indexStart = GetIndex("gp_B7");
- }
- void JoystickDevice::Update(float DeltaTime)
- {
- if (!m_Device) return;
- HRESULT hr = m_Device->Poll();
- hr=m_Device->GetDeviceState( sizeof(m_Data), &m_Data);
- if (SUCCEEDED(hr))
- {
- for (unsigned int i = 0; i < m_Controls.Size(); ++i)
- {
- if (m_Controls[i].type == Control::Button)
- {
- m_Controls[i].value = GetButtonData(m_Controls[i].dataOffset);
- }
- else
- if (m_Controls[i].type == Control::Axis)
- {
- m_Controls[i].value = GetAxisData(m_Controls[i].type, m_Controls[i].dataOffset);
- }
- else
- if (m_Controls[i].type == Control::POV_H)
- {
- m_Controls[i].value = GetPOVData(m_Controls[i].dataOffset, true);
- }
- else
- if (m_Controls[i].type == Control::POV_V)
- {
- m_Controls[i].value = GetPOVData(m_Controls[i].dataOffset, false);
- }
- }
- }
- else
- for (unsigned int i = 0; i < m_Controls.Size(); ++i)
- m_Controls[i].value = 0.0f;
- if (FAILED(hr))
- m_Device->Acquire();
- }
- void JoystickDevice::EndFrame()
- {
- // if (GetAsyncKeyState(VK_NUMPAD0) & 0x8000)
- if( api->DebugKeyState(VK_NUMPAD0))
- {
- IRender* render = (IRender*)api->GetService("DX9Render");
- for (unsigned int i = 0; i < m_Controls.Size(); ++i)
- render->GetSystemFont()->Print(0.0f, i*15.0f, "%s : %0.2f", m_Controls[i].name.GetBuffer(), m_Controls[i].value);
- }
- }
- long JoystickDevice::GetIndex(const char* deviceControl)
- {
- for (unsigned int i = 0; i < m_Controls.Size(); ++i)
- if ( m_Controls[i].name == deviceControl )
- return i;
- return INVALID_CODE;
- }
- float JoystickDevice::GetRawValue(long controlIndex) const
- {
- if ( (unsigned long)controlIndex >= m_Controls.Size() )
- return 0.0f;
- return m_Controls[controlIndex].inverted ? -m_Controls[controlIndex].value : m_Controls[controlIndex].value;
- }
- bool JoystickDevice::IsStartPressed() const
- {
- return fabsf(GetRawValue(indexStart)) > 0.001f;
- }
- bool JoystickDevice::IsDisconnected() const
- {
- HRESULT hr = m_Device->Poll();
- if (SUCCEEDED(hr) || hr == DIERR_NOTACQUIRED)
- return false;
- return true;
- }
- bool JoystickDevice::SetValues(ValueType type, const void *values, long nBytes)
- {
- if( type == FFRotorSpeed )
- {
- long n = nBytes/sizeof(float);
- Assert(n >= 2)
- float ls = ((float *)values)[0];
- float rs = ((float *)values)[1];
- LONG rglDirection[2] = {0,0};
- ls *= -10000.0f; if( ls < -10000.0f ) ls = -10000.0f;
- rs *= 10000.0f; if( rs > 10000.0f ) rs = 10000.0f;
- DIRAMPFORCE cf;
- DIEFFECT eff; ZeroMemory(&eff,sizeof(eff));
- eff.dwSize = sizeof(DIEFFECT);
- eff.dwFlags = DIEFF_CARTESIAN|DIEFF_OBJECTOFFSETS;
- // eff.cAxes = axesN;
- eff.cAxes = 2;
- eff.rglDirection = rglDirection;
- eff.lpEnvelope = 0;
- eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
- eff.lpvTypeSpecificParams = &cf;
- eff.dwStartDelay = 0;
- eff.dwDuration = INFINITE;
- cf.lStart = (LONG)ls;
- cf.lEnd = (LONG)ls;
- if( lef )
- lef->SetParameters(&eff,DIEP_TYPESPECIFICPARAMS|DIEP_START);
- cf.lStart = (LONG)rs;
- cf.lEnd = (LONG)rs;
- if( ref )
- ref->SetParameters(&eff,DIEP_TYPESPECIFICPARAMS|DIEP_START);
- return true;
- }
- else
- return false;
- }
- #endif
|