From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/di__game__device_8cpp-source.html | 581 +++++++++++++++++++++ 1 file changed, 581 insertions(+) create mode 100644 docs/doxygen/nel/di__game__device_8cpp-source.html (limited to 'docs/doxygen/nel/di__game__device_8cpp-source.html') diff --git a/docs/doxygen/nel/di__game__device_8cpp-source.html b/docs/doxygen/nel/di__game__device_8cpp-source.html new file mode 100644 index 00000000..0df70893 --- /dev/null +++ b/docs/doxygen/nel/di__game__device_8cpp-source.html @@ -0,0 +1,581 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

di_game_device.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 #include "stdmisc.h"
+00028 #include "misc/di_game_device.h"
+00029 #include "nel/misc/game_device_events.h"
+00030 #include <stddef.h>
+00031 #include <memory>
+00032 #include <algorithm>
+00033 
+00034 #ifdef NL_OS_WINDOWS
+00035 
+00036 namespace NLMISC 
+00037 {
+00038 
+00039 //============================================================================
+00040 CDIGameDevice::CDIGameDevice() : _Device(NULL)                                                           
+00041 {       
+00042         ::memset(&_CurrentState, 0, sizeof(_CurrentState));
+00043 }
+00044 
+00045 //============================================================================
+00046 CDIGameDevice::~CDIGameDevice()
+00047 {
+00048         if (_Device)
+00049         {
+00050                 _Device->Unacquire();
+00051                 _Device->Release();
+00052         }
+00053 }
+00054 
+00055 //============================================================================
+00056 CDIGameDevice *CDIGameDevice::createGameDevice(IDirectInput8 *di8,
+00057                                                                                            HWND hwnd,
+00058                                                                                            CDIEventEmitter *diEventEmitter,
+00059                                                                                            const CGameDeviceDesc &desc,
+00060                                                                                            REFGUID rguid) throw(EDirectInput)
+00061 {
+00062         nlassert(diEventEmitter);       
+00063         nlassert(di8);
+00064         std::auto_ptr<CDIGameDevice> dev(new CDIGameDevice);
+00065         //
+00066 
+00067         HRESULT r = di8->CreateDevice(rguid, &dev->_Device, NULL);
+00068         if (r != DI_OK) throw EDirectInputGameDeviceNotCreated();       
+00069 
+00070         r = dev->_Device->SetDataFormat(pJoyDataFormat);
+00071         nlassert(r == DI_OK);
+00072         //
+00073         r = dev->_Device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
+00074         if (r != DI_OK) throw EDirectInputCooperativeLevelFailed();
+00075         //      
+00076         //                      
+00077         dev->_Desc = desc;
+00078         dev->_EventEmitter = diEventEmitter;
+00079         dev->querryControls();  
+00080         return dev.release();
+00081 }
+00082 
+00083 //============================================================================
+00084 void CDIGameDevice::begin(CEventServer *server)
+00085 {
+00086         nlassert(_Device);
+00087         HRESULT r;
+00088         r = _Device->Poll();
+00089         if (r == DIERR_INPUTLOST  || r == DIERR_NOTACQUIRED)
+00090         {                               
+00091         r = _Device->Acquire();
+00092                 if (r != DI_OK) return;
+00093                 r = _Device->Poll();
+00094                 if (r != DI_OK) return;
+00095         }
+00096 
+00097         CDIJoyState     newState;       
+00098         r = _Device->GetDeviceState(sizeof(CDIJoyState), &newState);
+00099         if (r != DI_OK) return;
+00100 
+00101         uint k;
+00103         // Axis //
+00105         for (k = 0; k < MaxNumAxis; ++k)
+00106         {
+00107                 CAxis &axis = _Axis[k];
+00108                 if (axis.Present)
+00109                 {                       
+00110                         
+00111                         if (((LONG *) &newState)[k] != ((LONG *) &_CurrentState)[k]) // state changed ?
+00112                         {                               
+00113                                 // update position
+00114                                 axis.Value              = 2.f * (((LONG *) &newState)[k] - axis.Min) / (float) (axis.Max - axis.Min) - 1.f;
+00115                                 // create event
+00116                                 CGDAxisMoved    *event = new CGDAxisMoved((IGameDevice::TAxis) k, axis.Value, this, _EventEmitter);
+00117                                 // update state
+00118                                 ((LONG *) &_CurrentState)[k] = ((LONG *) &newState)[k];
+00119                                 //
+00120                                 server->postEvent(event);
+00121                                 //
+00122                         }                                                       
+00123                 }
+00124         }
+00125 
+00126 
+00128         // Buttons //
+00130         for (k = 0; k < _Buttons.size(); ++k)
+00131         {               
+00132                 CButton &bt = _Buttons[k];              
+00133                 if ((newState.rgbButtons[k] & 0x80) != (_CurrentState.rgbButtons[k] & 0x80))
+00134                 {
+00135                         bool pushed = (newState.rgbButtons[k] & 0x80) != 0;                     
+00136                         // update the state of the button
+00137                         bt.Pushed = pushed;
+00138                         CGDButton *event;
+00139                         if (pushed) event = new CGDButtonDown(k, this, _EventEmitter);
+00140                         else event = new CGDButtonUp(k, this, _EventEmitter);                                   
+00141                         // update state                 
+00142                         _CurrentState.rgbButtons[k] = newState.rgbButtons[k];
+00143                         server->postEvent(event);
+00144                 }
+00145         }
+00146 
+00148         // Sliders //
+00150         for (k = 0; k < _Sliders.size(); ++k)
+00151         {               
+00152                 CSlider &sl = _Sliders[k];
+00153                 if (newState.rglSlider[k] != _CurrentState.rglSlider[k]) // state changed ?
+00154                 {                                                               
+00155                         // update position
+00156                         sl.Pos          = ( newState.rglSlider[k] - sl.Min) / (float) (sl.Max - sl.Min);
+00157                         // create event
+00158                         CGDSliderMoved  *event = new CGDSliderMoved(sl.Pos, k, this, _EventEmitter);
+00159                         // update state
+00160                         _CurrentState.rglSlider[k] = newState.rglSlider[k];
+00161                         //
+00162                         server->postEvent(event);
+00163                 }
+00164         }
+00165 
+00167         // POVs //
+00169         for (k = 0; k < _POVs.size(); ++k)
+00170         {
+00171                 CPOV &pov = _POVs[k];           
+00172                 if (newState.rgdwPOV[k] != _CurrentState.rgdwPOV[k]) // state changed ?
+00173                 {                                                       
+00174                         DWORD value = newState.rgdwPOV[k];
+00175 
+00176                         pov.Centered = (LOWORD(value) == 0xFFFF);
+00177                         if (!pov.Centered)
+00178                         {
+00179                                 // update position
+00180                                 pov.Angle               = value / 100.f;
+00181                         }
+00182                         // create event
+00183                         CGDPOVChanged   *event = new CGDPOVChanged(pov.Centered, pov.Angle, k, this, _EventEmitter);
+00184                         // update state
+00185                         _CurrentState.rgdwPOV[k] = newState.rgdwPOV[k];
+00186                         //
+00187                         server->postEvent(event);
+00188                 }
+00189         }
+00190 
+00191 }
+00192 
+00193 //============================================================================
+00194 void CDIGameDevice::poll(CInputDeviceServer *dev)
+00195 {
+00196         // buffered datas not supported
+00197 }
+00198 
+00199 //============================================================================
+00200 void CDIGameDevice::submit(IInputDeviceEvent *deviceEvent, CEventServer *server)
+00201 {
+00202         // should never be called, buffered datas not supported
+00203         nlassert(0);
+00204 }
+00205 
+00206 
+00207 //============================================================================
+00211 static void BuildCtrlName(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+00212                                                   std::string &destName,
+00213                                                   const char *defaultName)
+00214 {
+00215         if (lpddoi->dwSize >= offsetof(DIDEVICEOBJECTINSTANCE, tszName) + sizeof(TCHAR[MAX_PATH]))
+00216         {
+00217                 destName = (::strcmp("N/A", lpddoi->tszName) == 0) ? defaultName
+00218                                                                                                                   : lpddoi->tszName;            
+00219         }
+00220         else
+00221         {
+00222                 destName = defaultName; 
+00223         }
+00224 }
+00225 
+00226 //============================================================================
+00227 // A callback to enumerate the controls of a device
+00228 static BOOL CALLBACK DIEnumDeviceObjectsCallback
+00229 (
+00230   LPCDIDEVICEOBJECTINSTANCE lpddoi,
+00231   LPVOID pvRef 
+00232 )
+00233 {
+00234 
+00235         CDIGameDevice *gd = (CDIGameDevice *) pvRef;
+00236         return gd->processEnumObject(lpddoi);
+00237 }
+00238 
+00239 
+00240 
+00241 //=======================================================================
+00242 // get range for an axis
+00243 static HRESULT  GetDIAxisRange(LPDIRECTINPUTDEVICE8 device, uint offset, DWORD type, sint &min, sint &max)
+00244 {
+00245         DIPROPRANGE diprg; 
+00246     diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
+00247     diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
+00248     diprg.diph.dwHow        = DIPH_BYOFFSET; 
+00249     diprg.diph.dwObj        = offset;
+00250     
+00251         // Set the range for the axis
+00252         HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph);
+00253 
+00254         if (r == DIERR_OBJECTNOTFOUND)
+00255         {
+00256                 // try from its ID
+00257                 diprg.diph.dwHow        = DIPH_BYID; 
+00258                 diprg.diph.dwObj        = type;
+00259 
+00260                 // Set the range for the axis
+00261                 HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph);
+00262                 if (r !=  DI_OK)
+00263                 {
+00264                         // setup default values ...
+00265                         min = 0;
+00266                         max = 65535;
+00267                         return r;
+00268                 }
+00269         }
+00270         else if (r != DI_OK)
+00271         {
+00272                 min = 0;
+00273                 max = 65535;
+00274                 return r;
+00275         }
+00276                  
+00277 
+00278 /*      switch (r)
+00279         {
+00280                 default:
+00281                         nlinfo("ok");
+00282                 break;
+00283                 case DIERR_INVALIDPARAM: 
+00284                         nlinfo("invalid param");
+00285                 break;
+00286                 case DIERR_NOTEXCLUSIVEACQUIRED: 
+00287                         nlinfo("DIERR_NOTEXCLUSIVEACQUIRED");
+00288                 break;
+00289                 case DIERR_NOTINITIALIZED: 
+00290                         nlinfo("DIERR_NOTINITIALIZED");
+00291                 break;
+00292                 case DIERR_OBJECTNOTFOUND: 
+00293                         nlinfo("DIERR_OBJECTNOTFOUND");
+00294                 break;
+00295                 case DIERR_UNSUPPORTED: 
+00296                         nlinfo("DIERR_UNSUPPORTED");
+00297                 break;
+00298         }*/
+00299 
+00300         
+00301         min = (sint) diprg.lMin;
+00302         max = (sint) diprg.lMax;
+00303         
+00304         return r;
+00305 }
+00306 
+00307 //============================================================================
+00308 BOOL CDIGameDevice::processEnumObject(LPCDIDEVICEOBJECTINSTANCE lpddoi)
+00309 {
+00310         // the dwSize field gives us the size of the objects, and the available fields
+00311         // has this object the field guidType and dwOfs ?
+00312         if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwOfs) + sizeof(DWORD)) return DIENUM_CONTINUE;
+00313 
+00314         uint ctrlType = (uint) lpddoi->dwType;
+00315 
+00317         //      axis, we only support absolute ones  //
+00319 
+00320         if (lpddoi->guidType == GUID_XAxis && (ctrlType & DIDFT_ABSAXIS) )
+00321         {               
+00322                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[XAxis].Min, _Axis[XAxis].Max);
+00323                 BuildCtrlName(lpddoi, _Axis[XAxis].Name, "X Axis");                             
+00324                 _Axis[XAxis].Present = true;
+00325                 return DIENUM_CONTINUE;
+00326         }
+00327         if (lpddoi->guidType == GUID_YAxis && (ctrlType & DIDFT_ABSAXIS))
+00328         {               
+00329                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[YAxis].Min, _Axis[YAxis].Max);
+00330                 BuildCtrlName(lpddoi, _Axis[YAxis].Name, "Y Axis");                                                             
+00331                 _Axis[YAxis].Present = true;
+00332                 return DIENUM_CONTINUE;
+00333         }
+00334         
+00335         if (lpddoi->guidType == GUID_ZAxis && (ctrlType & DIDFT_ABSAXIS))
+00336         {        
+00337                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[ZAxis].Min, _Axis[ZAxis].Max);
+00338                 BuildCtrlName(lpddoi, _Axis[ZAxis].Name, "Z Axis");             
+00339                 _Axis[ZAxis].Present = true;
+00340                 return DIENUM_CONTINUE;
+00341         }
+00342         if (lpddoi->guidType == GUID_RxAxis && (ctrlType & DIDFT_ABSAXIS))
+00343         {        
+00344                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RXAxis].Min, _Axis[RXAxis].Max);
+00345                 BuildCtrlName(lpddoi, _Axis[RXAxis].Name, "RX Axis");                           
+00346                 _Axis[RXAxis].Present = true;
+00347                 return DIENUM_CONTINUE;
+00348         }
+00349         if (lpddoi->guidType == GUID_RyAxis && (ctrlType & DIDFT_ABSAXIS))
+00350         {        
+00351                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RYAxis].Min, _Axis[RYAxis].Max);
+00352                 BuildCtrlName(lpddoi, _Axis[RYAxis].Name, "RY Axis");           
+00353                 _Axis[RYAxis].Present = true;
+00354                 return DIENUM_CONTINUE;
+00355         }
+00356         if (lpddoi->guidType == GUID_RzAxis && (ctrlType & DIDFT_ABSAXIS))
+00357         {        
+00358                 GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RZAxis].Min, _Axis[RZAxis].Max);
+00359                 BuildCtrlName(lpddoi, _Axis[RZAxis].Name, "RZ Axis");           
+00360                 _Axis[RZAxis].Present = true;
+00361                 return DIENUM_CONTINUE;
+00362         }
+00363 
+00364 
+00365         // has this object the field dwType ?
+00366         if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwType) + sizeof(DWORD)) return DIENUM_CONTINUE;
+00367 
+00368 
+00369         uint type = lpddoi->dwType;
+00371         // Buttons //
+00373         if (type & DIDFT_BUTTON)
+00374         {
+00375                 if (_Buttons.size() < MaxNumButtons)
+00376                 {
+00377                         _Buttons.push_back(CButton());
+00378                         uint buttonIndex = _Buttons.size() - 1;
+00379                         char defaultButtonName[32];
+00380                         smprintf(defaultButtonName, 32, "BUTTON %d", buttonIndex + 1);
+00381                         BuildCtrlName(lpddoi, _Buttons[buttonIndex].Name, defaultButtonName);           
+00382                         return DIENUM_CONTINUE;
+00383                 }
+00384         }
+00385 
+00387         // Sliders //
+00389         if (type & DIDFT_ABSAXIS)
+00390         {
+00391                 if (_Sliders.size() < MaxNumSliders)
+00392                 {
+00393                         _Sliders.push_back(CSlider());
+00394                         uint sliderIndex = _Sliders.size() - 1;
+00395                         GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Sliders[sliderIndex].Min, _Sliders[sliderIndex].Max);
+00396                         char defaultSliderName[32];
+00397                         smprintf(defaultSliderName, 32, "SLIDER %d", sliderIndex + 1);
+00398                         BuildCtrlName(lpddoi, _Sliders[sliderIndex].Name, defaultSliderName);                                   
+00399                 }
+00400                 return DIENUM_CONTINUE;
+00401         }
+00402 
+00403 
+00405         // POVs //
+00407         if (type & DIDFT_POV)
+00408         {
+00409                 if (_POVs.size() < MaxNumPOVs)
+00410                 {
+00411                         _POVs.push_back(CPOV());
+00412                         uint povIndex = _POVs.size() - 1;
+00413                         char defaultPOVName[16];
+00414                         smprintf(defaultPOVName, 16, "POV %d", povIndex + 1);
+00415                         BuildCtrlName(lpddoi, _POVs[povIndex].Name, defaultPOVName);                            
+00416                 }
+00417                 return DIENUM_CONTINUE;
+00418         }
+00419         
+00420         return DIENUM_CONTINUE;
+00421 }
+00422 
+00423 //============================================================================
+00424 void    CDIGameDevice::querryControls()
+00425 {
+00426         HRESULT r = _Device->EnumObjects(&DIEnumDeviceObjectsCallback, (LPVOID) this, DIDFT_ALL);
+00427         nlassert(r == DI_OK);
+00428 }
+00429 
+00430 //============================================================================
+00431 bool  CDIGameDevice::setBufferSize(uint size)
+00432 {
+00433         // uisually not supported by this kind of devices
+00434         return false;
+00435 }
+00436 
+00437 //============================================================================
+00438 uint  CDIGameDevice::getBufferSize() const
+00439 {
+00440         // uisually not supported by this kind of devices
+00441         return 0;
+00442 }
+00443 
+00444 //============================================================================
+00445 uint  CDIGameDevice::getNumButtons() const
+00446 {
+00447         return _Buttons.size();
+00448 }
+00449 
+00450 //============================================================================
+00451 bool            CDIGameDevice::hasAxis(TAxis axis) const
+00452 {
+00453         nlassert(axis < MaxNumAxis);
+00454         return _Axis[axis].Present;
+00455 }
+00456 
+00457 //============================================================================
+00458 uint            CDIGameDevice::getNumSliders() const
+00459 {
+00460         return _Sliders.size();
+00461 }
+00462 
+00463 //============================================================================
+00464 uint            CDIGameDevice::getNumPOV() const 
+00465 {
+00466         return _POVs.size();
+00467 }
+00468 //============================================================================
+00469 const char *CDIGameDevice::getButtonName(uint index) const
+00470 {
+00471         nlassert(index < _Buttons.size());
+00472         return _Buttons[index].Name.c_str();
+00473 }
+00474 
+00475 //============================================================================
+00476 const char *CDIGameDevice::getAxisName(TAxis axis) const
+00477 {
+00478         nlassert(axis < MaxNumAxis);
+00479         nlassert(hasAxis(axis)); // ! Not an axis of this device
+00480         return  _Axis[axis].Name.c_str();
+00481 }
+00482 
+00483 //============================================================================
+00484 const char *CDIGameDevice::getSliderName(uint index) const
+00485 {
+00486         nlassert(index < _Sliders.size());
+00487         return _Sliders[index].Name.c_str();
+00488 }
+00489 
+00490 //============================================================================
+00491 const char *CDIGameDevice::getPOVName(uint index) const
+00492 {
+00493         nlassert(index < _POVs.size());
+00494         return _POVs[index].Name.c_str();
+00495 }
+00496 
+00497 //============================================================================
+00498 bool            CDIGameDevice::getButtonState(uint index) const
+00499 {
+00500         nlassert(index < _Buttons.size());
+00501         return _Buttons[index].Pushed;
+00502 }
+00503 
+00504 //============================================================================
+00505 float           CDIGameDevice::getAxisValue(TAxis axis) const
+00506 {
+00507         nlassert(axis < MaxNumAxis);
+00508         nlassert(hasAxis(axis)); // ! Not an axis of this device
+00509         return  _Axis[axis].Value;
+00510 }
+00511 
+00512 //============================================================================
+00513 float           CDIGameDevice::getSliderPos(uint index) const
+00514 {
+00515         nlassert(index < _Sliders.size());
+00516         return _Sliders[index].Pos;
+00517 }
+00518 
+00519 //============================================================================
+00520 float           CDIGameDevice::getPOVAngle(uint index) const
+00521 {
+00522         nlassert(index < _POVs.size());
+00523         return _POVs[index].Angle;
+00524 }
+00525 
+00526 
+00527 
+00528 } // NLMISC
+00529 
+00530 
+00531 #endif // NL_OS_WINDOWS
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1