home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / ReplicaNetFreewareV5_4.exe / data1.cab / Program_Executable_Files / Example4 / DIInterface.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  23.4 KB  |  838 lines

  1. /* START_LICENSE_HEADER
  2.  
  3. Copyright (C) 2000 Martin Piper, original design and program code
  4. Copyright (C) 2001-2005 Replica Software
  5.  
  6. This program file is copyright (C) Replica Software and can only be used under license.
  7. For more information visit: http://www.replicanet.com/
  8. Or email: info@replicanet.com
  9.  
  10. END_LICENSE_HEADER */
  11. // Direct Input Interface code
  12. #include <stdio.h>
  13. #include <windows.h> 
  14. #include <assert.h>
  15. #define DIRECTINPUT_VERSION 0x0800
  16. #include <dinput.h> 
  17. #include <math.h> 
  18. #include "diinterface.h"
  19.  
  20. // Lots of nasty globals
  21. TDIHandler* gDIHandler = 0;
  22. bool gIgnoreDInputWarnings = true;
  23.  
  24.  
  25. TDIDevice::TDIDevice(void)
  26. {
  27.     fEffect = NULL;
  28.     fDevice = NULL;
  29.     fBuffer = NULL;
  30.  
  31.     fJoystick.fDIDevice = this;
  32. }
  33.  
  34. TDIDevice::~TDIDevice(void)
  35. {
  36.     if (fBuffer) delete [] fBuffer;
  37.     
  38.     if (fDevice)
  39.     {
  40.         fDevice->Unacquire();
  41.         fDevice->Release();
  42.     }
  43. }
  44.  
  45.  
  46.  
  47.  
  48. //
  49. //  void TDIDevice::Acquire(int acquire)
  50. //
  51. //
  52. //
  53. void TDIDevice::Acquire(int acquire)
  54. {
  55.     HRESULT hr;
  56.     
  57.     if (acquire)
  58.     {
  59.         hr=fDevice->Acquire();
  60.         if (NULL != fEffect) 
  61.         {      
  62.             HRESULT hr2;
  63.             hr2 = fEffect->Start( 1, 0 );
  64.         }
  65.     }
  66.     else
  67.         hr=fDevice->Unacquire();
  68.  
  69. #ifdef _DEBUG
  70.     if (!gIgnoreDInputWarnings)
  71.     {
  72.         switch (hr)
  73.         {
  74.             case DI_OK :
  75.                 printf("TDIDevice::Acquire - result = DI_OK\n");
  76.                 break;
  77.  
  78.             case S_FALSE :
  79.                 printf("TDIDevice::Acquire - result = S_FALSE (device already acquired)\n");
  80.                 break;
  81.  
  82.             case DIERR_INVALIDPARAM :
  83.                 printf("TDIDevice::Acquire - result = DIERR_INVALIDPARAM\n");
  84.                 break;
  85.  
  86.             case DIERR_NOTINITIALIZED :
  87.                 printf("TDIDevice::Acquire - result = DIERR_NOTINITIALIZED\n");
  88.                 break;
  89.  
  90.             case DIERR_OTHERAPPHASPRIO :
  91.                 printf("TDIDevice::Acquire - result = DIERR_OTHERAPPHASPRIO\n");
  92.                 break;
  93.         };
  94.  
  95.         assert(SUCCEEDED(hr));
  96.     }
  97. #endif
  98. }
  99.  
  100.  
  101. //
  102. // void TDIDevice::Read()
  103. //
  104. //
  105. //
  106. void TDIDevice::Read()
  107. {
  108.     HRESULT dirval = fDevice->GetDeviceState(fBufSize,(LPVOID)fBuffer);
  109.     if( dirval == DI_OK )
  110.         return;
  111.     
  112.     assert(dirval == DIERR_INPUTLOST || dirval == DIERR_NOTACQUIRED);
  113.     dirval = fDevice->Acquire();        // Might fail, but will work next frame
  114.     memset(fBuffer,0,fBufSize);
  115. }
  116.  
  117.  
  118.  
  119. //
  120. //  void TDIDevice::InitialiseKeyboard(REFGUID guid,LPCDIDATAFORMAT dataFormat,int bufferSize)
  121. //
  122. //
  123. //
  124. extern HWND                    ghWnd; 
  125. void TDIKeyboard::InitialiseKeyboard(REFGUID guid,LPCDIDATAFORMAT dataFormat,int bufferSize)
  126. {
  127.     memset(fDeBounce, 0, 256 * sizeof (int));
  128.  
  129. #if DIRECTINPUT_VERSION < DIRECTINPUT8_VERSION
  130.     LPDIRECTINPUTDEVICE tempDevice;
  131. #endif
  132.  
  133.     // initialise the buffer
  134.     fBufSize=bufferSize;
  135.     fBuffer = new char[bufferSize];
  136.     memset(fBuffer,0,bufferSize);
  137.     
  138. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION
  139.     // (DirectX8) create keyboard device
  140.     #if D3D_SDK_VERSION == DX_BETA_WEEKLY2
  141.         HRESULT hr = gDIHandler->fDI->CreateDevice(    guid,                            // guid
  142.                                                     &fDevice,                        // device
  143.                                                     NULL );                            // must be set to NULL
  144.     #else
  145.         HRESULT hr = gDIHandler->fDI->CreateDeviceEx(    guid,                        // guid
  146.                                                         IID_IDirectInputDevice8,    // interface req
  147.                                                         (LPVOID*) &fDevice,            // device
  148.                                                         NULL );                        // must be set to NULL
  149.     #endif
  150. #else
  151.     // create keyboard device
  152.     HRESULT hr = gDIHandler->fDI->CreateDevice(    guid,                                // guid
  153.                                                 &tempDevice,                        // device
  154.                                                 NULL );                                // must be set to NULL
  155.     assert(SUCCEEDED(hr));
  156.  
  157.     // query for IDirectInputDevice2 interface
  158.     hr = tempDevice->QueryInterface( IID_IDirectInputDevice2, (VOID**)&fDevice );
  159.     assert(SUCCEEDED(hr));
  160. #endif
  161.     
  162.     // set the data format
  163.     hr = fDevice->SetDataFormat(dataFormat); 
  164.     assert(SUCCEEDED(hr));
  165.     
  166.     // set the cooperative level
  167.     hr = fDevice->SetCooperativeLevel(ghWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
  168.     assert(SUCCEEDED(hr));
  169.     
  170.     // acquire it
  171.     Acquire(true); 
  172. }
  173.  
  174.  
  175. //
  176. //   void TDIKeyboard::ReadInputs(void) 
  177. //
  178. //   fills in the fJoystick flags with the keyboard
  179. //
  180. void TDIKeyboard::ReadInputs(void) 
  181. {
  182.     fJoystick.Clear();
  183.  
  184.     Read();          // Check we have the keyboard
  185.  
  186.     if (SysKeyDown(DIK_LEFT))       fJoystick.fButtons |= JOYSTICK_LEFT;
  187.     if (SysKeyDown(DIK_RIGHT))      fJoystick.fButtons |= JOYSTICK_RIGHT;
  188.     if (SysKeyDown(DIK_UP))         fJoystick.fButtons |= JOYSTICK_UP;
  189.     if (SysKeyDown(DIK_DOWN))       fJoystick.fButtons |= JOYSTICK_DOWN;
  190.     if (SysKeyDown(DIK_SPACE))      fJoystick.fButtons |= JOYSTICK_JUMP;
  191.     if (SysKeyDown(DIK_H))            fJoystick.fButtons |= JOYSTICK_HORN;
  192.     if (SysKeyDown(DIK_O))            fJoystick.fButtons |= JOYSTICK_USE1;
  193.     if (SysKeyDown(DIK_P))            fJoystick.fButtons |= JOYSTICK_USE2;
  194.     if (SysKeyDown(DIK_J))          fJoystick.fButtons |= JOYSTICK_USE3;
  195.     if (SysKeyDown(DIK_TAB))        fJoystick.fButtons |= JOYSTICK_PULL_CAMERA;
  196.  
  197.     if (SysKeyDown(DIK_N))          fJoystick.fButtons |= JOYSTICK_LEFT;
  198.     if (SysKeyDown(DIK_M))          fJoystick.fButtons |= JOYSTICK_RIGHT;
  199.     if (SysKeyDown(DIK_A))          fJoystick.fButtons |= JOYSTICK_ACCELERATE;
  200.     if (SysKeyDown(DIK_Z))          fJoystick.fButtons |= JOYSTICK_BRAKE;
  201.  
  202.     if (SysKeyDown(DIK_W))          fJoystick.fButtons |= JOYSTICK_W;
  203.     if (SysKeyDown(DIK_A))          fJoystick.fButtons |= JOYSTICK_A;
  204.     if (SysKeyDown(DIK_S))          fJoystick.fButtons |= JOYSTICK_S;
  205.     if (SysKeyDown(DIK_D))          fJoystick.fButtons |= JOYSTICK_D;    
  206. }
  207.  
  208.  
  209. //
  210. // void TDIJoystick::ReadInputs(void) 
  211. //
  212. //   Read the joystick
  213. //
  214. void TDIJoystick::ReadInputs(void) 
  215. {
  216.     DIJOYSTATE*              js;  
  217.  
  218.     // poll the joystick to read the current state
  219.     fDevice->Poll(); 
  220.  
  221.     // Fill in the buffer
  222.     Read();
  223.     
  224.     js = (DIJOYSTATE*)fBuffer;
  225.  
  226.     fJoystick.Clear();
  227.  
  228.     if (0)
  229.     {
  230.         int i = 0;
  231.  
  232.         /*if (js->lX > 0) { gRenderer->DebugPrintf(200, 10 + 10*i, "lX +ve (RHS)"); i++; }
  233.         if (js->lX < 0) { gRenderer->DebugPrintf(200, 10 + 10*i, "lX -ve (LHS)"); i++; }
  234.  
  235.         if (js->lY > 0) { gRenderer->DebugPrintf(200, 10 + 10*i, "lY -ve (FWD)"); i++; }
  236.         if (js->lY < 0) { gRenderer->DebugPrintf(200, 10 + 10*i, "lY +ve (REV)"); i++; }*/
  237.  
  238.         char buf[256];
  239.         for(int c = 0; c < 32; c++)
  240.             if (js->rgbButtons[c] & 0x80) 
  241.             { 
  242.                 sprintf(buf, "BTN %d\0", c); 
  243.                // gRenderer->DebugPrintf(200, 10 + 10*i, buf);
  244.                 i++; 
  245.             }
  246.     }
  247.  
  248.     // Now study the position of the stick and the buttons.
  249.  
  250.     fJoystick.fstickX = js->lX;
  251.     fJoystick.fstickY = js->lY;
  252.  
  253.     // USE1 reverse
  254.     // USE2 re-start
  255.     // JUMP jump
  256.  
  257.     int                                    deadZone = 150;
  258.  
  259.   //  if (!gPreferences.fUseWheel)
  260.     {
  261.      /*   if (js->lX < -deadZone)         fJoystick.fButtons |= JOYSTICK_LEFT;
  262.         else if (js->lX > deadZone)     fJoystick.fButtons |= JOYSTICK_RIGHT;
  263.  
  264.         if (js->lY < -deadZone)         fJoystick.fButtons |= JOYSTICK_UP;
  265.         else if (js->lY > deadZone)     fJoystick.fButtons |= JOYSTICK_DOWN;*/
  266.  
  267.         if (js->rgbButtons[7] & 0x80)   
  268.             fJoystick.fButtons |= JOYSTICK_ACCELERATE; 
  269.         
  270.         if (js->rgbButtons[6] & 0x80)   
  271.             fJoystick.fButtons |= JOYSTICK_BRAKE;
  272.  
  273.         if (js->rgbButtons[1] & 0x80)  
  274.             fJoystick.fButtons |= JOYSTICK_JUMP;
  275.  
  276.         if (js->rgbButtons[2] & 0x80)   
  277.             fJoystick.fButtons |= JOYSTICK_USE1;
  278.  
  279.         if (js->rgbButtons[8] & 0x80)   
  280.             fJoystick.fButtons |= JOYSTICK_USE2;
  281.  
  282.         if (js->rgbButtons[9] & 0x80)   
  283.             fJoystick.fButtons |= JOYSTICK_HORN;
  284.  
  285.         if (js->rgbButtons[3] & 0x80)   
  286.             fJoystick.fButtons |= JOYSTICK_USE3;
  287.  
  288.         if (js->rgbButtons[4] & 0x80)   
  289.             fJoystick.fButtons |= JOYSTICK_PULL_CAMERA;
  290.  
  291.         if (js->rgbButtons[5] & 0x80)
  292.             fJoystick.fButtons |= JOYSTICK_W;
  293.  
  294.         if (js->rgbButtons[0] & 0x80)
  295.             fJoystick.fButtons |= JOYSTICK_A;
  296.  
  297.         if (js->rgbButtons[10] & 0x80)
  298.             fJoystick.fButtons |= JOYSTICK_S;
  299.  
  300.         if (js->rgbButtons[11] & 0x80)
  301.             fJoystick.fButtons |= JOYSTICK_D;
  302.     }
  303.  
  304.     // Read the 'hat' (digital joypad directions)
  305.     if (LOWORD(js->rgdwPOV[0]) == 0xFFFF)            // -1 -> centre
  306.     {
  307.         fJoystick.frightstickX = 0;
  308.         fJoystick.frightstickY = 0;
  309.     }
  310.     else
  311.     {
  312.         fJoystick.frightstickX = long(sinf(float(js->rgdwPOV[0]) / 100.0f / 360.0f * 2.0f * 3.14159265f) * 1000.0f);
  313.         fJoystick.frightstickY = long(cosf(float(js->rgdwPOV[0]) / 100.0f / 360.0f * 2.0f * 3.14159265f) * -1000.0f);
  314.     }
  315.  
  316.    /* else // hacked wheel case...
  317.     {
  318.         if (js->lX < 0)                 fJoystick.fButtons |= JOYSTICK_LEFT;
  319.         else if (js->lX > 0)            fJoystick.fButtons |= JOYSTICK_RIGHT;
  320.  
  321.         if (js->lY < -100)                 fJoystick.fButtons |= JOYSTICK_ACCELERATE;
  322.         else if (js->lY > 100)            fJoystick.fButtons |= JOYSTICK_BRAKE;
  323.  
  324.         if (js->rgbButtons[0] & 0x80)   fJoystick.fButtons |= JOYSTICK_JUMP;
  325.         if (js->rgbButtons[3] & 0x80)   fJoystick.fButtons |= JOYSTICK_USE1;
  326.         if (js->rgbButtons[5] & 0x80)   fJoystick.fButtons |= JOYSTICK_USE2;
  327.     }*/
  328.  
  329.  
  330. //
  331. //  TDIHandler::TDIHandler(void)
  332. //
  333. //
  334. //
  335. TDIHandler::TDIHandler(void)
  336. {
  337.     fDI=NULL;
  338.     fNumDevices = 0;
  339.     fNextJoystick = 0;
  340.  
  341.     for (int i = 0; i < MAX_NUM_DEVICES; i++)
  342.     {
  343.         fDevice[i] = NULL;
  344.     }
  345.  
  346.     fMouse = NULL;
  347.     fGrabbed = false;
  348. }
  349.  
  350.  
  351.  
  352. //
  353. //  TDIHandler::~TDIHandler(void)
  354. //
  355. //
  356. //
  357. TDIHandler::~TDIHandler(void)
  358. {
  359.     for (int i = 0; i < fNumDevices; i++)
  360.     {
  361.         delete fDevice[i];
  362.     }
  363.  
  364.  
  365.     if (fDI)
  366.     {
  367.         fDI->Release();
  368.         fDI=NULL;
  369.     }
  370.  
  371.     if (fMouse != NULL)
  372.     {
  373.         fMouse->Unacquire();
  374.         fMouse->Release();
  375.         fMouse = NULL;
  376.     }
  377. }
  378.  
  379.  
  380.  
  381. //
  382. // void TDIHandler::Initialise(void)
  383. //
  384. //
  385. //  Create the input driver and the devices (keyboard and joystick) here
  386. //
  387. extern HINSTANCE    gAppInstance;
  388. void TDIHandler::Initialise(void)
  389. {
  390. // DirectX 8 initialisation
  391. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION
  392.     HRESULT hr = DirectInput8Create(    gAppInstance,
  393.                                         DIRECTINPUT_VERSION,
  394.                                         IID_IDirectInput8,
  395.                                         (LPVOID*) &fDI,
  396.                                         NULL );
  397. #else
  398.     // Previous versions
  399.     HRESULT hr = DirectInputCreate(gAppInstance,DIRECTINPUT_VERSION,&fDI,NULL);
  400. #endif
  401.     assert(SUCCEEDED(hr));
  402.  
  403. // Enumerate for available joystick/game controllers
  404. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION_WEEKLY2
  405.     // DirectX 8 enumeration
  406.     // joysticks are now referred to as game controllers
  407.     hr = fDI->EnumDevices(    DI8DEVCLASS_GAMECTRL,
  408.                             InitialiseJoystickEnum,
  409.                             this,
  410.                             DIEDFL_ATTACHEDONLY );
  411. #else
  412.     hr = fDI->EnumDevices(    DIDEVTYPE_JOYSTICK,
  413.                             InitialiseJoystickEnum,
  414.                             this,
  415.                             DIEDFL_ATTACHEDONLY );
  416. #endif
  417.     assert(SUCCEEDED(hr));
  418.  
  419.     for (int i = 0; i < fNumDevices; i++)
  420.     {
  421.         {
  422.             HRESULT  hr;
  423.  
  424.             hr = fDevice[i]->fDevice->EnumEffects(    JoystickEffectsEnum,
  425.                                                     (LPVOID) fDevice[i]->fDevice,
  426.                                                     DIEFT_CONSTANTFORCE );
  427.             assert(hr == DI_OK);
  428.  
  429.             // acquire device
  430.             fDevice[i]->Acquire(true);
  431.         }
  432.     }
  433.  
  434.     // create the system keyboard
  435.     fDevice[fNumDevices] = new TDIKeyboard;
  436.     fDISysKeyboard = (TDIKeyboard*)fDevice[fNumDevices];  // Cache ptr to keyboard for fast key reading in editor
  437.     fDISysKeyboard->InitialiseKeyboard(GUID_SysKeyboard,&c_dfDIKeyboard,256);
  438.     fNumDevices++;
  439.  
  440.     InitMouse();
  441. }
  442.  
  443.  
  444. //
  445. //  void TDIHandler::ReadAllInputs()
  446. //
  447. //   Called every frame,  fills in the fJoystick flags within each device
  448. //
  449. void TDIHandler::ReadAllInputs()
  450. {
  451.     for (int i = 0; i < fNumDevices; i++)
  452.         fDevice[i]->ReadInputs();
  453.  
  454. #if 0
  455.     static int counter = 0;
  456.     DWORD max_t = 0;
  457.     DWORD pre_t = timeGetTime();
  458.  
  459.     counter++;
  460.     if ( counter > 100 )
  461.     {
  462.         DWORD t = timeGetTime() - pre_t;
  463.         max_t = max(max_t, t);
  464.         gRenderer->DebugPrintf(40, 250, "INPUT TIME: %d", t);
  465.         gRenderer->DebugPrintf(40, 260, "INPUT TIME: %d MAX", max_t);
  466.     }
  467. #endif
  468. }
  469.  
  470. TJoystick* TDIHandler::GetJoystick(int theIndex)
  471. {
  472.     // Used to get joysticks for recording, probably only ever used to 
  473.     // get joystick 0
  474.     assert (theIndex < MAX_NUM_DEVICES);
  475.     assert (fDevice[theIndex] != NULL);
  476.  
  477.     return &fDevice[theIndex]->fJoystick;
  478.  
  479. }
  480.  
  481.  
  482. TJoystick* TDIHandler::GetNextJoystick()
  483. {
  484.     // Used to alloca t the joysticks on a first-come first served basis
  485.  
  486.     if (fNextJoystick >= MAX_NUM_DEVICES)
  487.         return NULL;
  488.  
  489.     if (fDevice[fNextJoystick] != NULL)
  490.     {
  491.         fNextJoystick++;
  492.         return (&fDevice[fNextJoystick - 1]->fJoystick);
  493.     }
  494.  
  495.     return NULL;
  496. }
  497.  
  498.  
  499. void TDIHandler::ResetJoystickAllocation()
  500. {
  501.     fNextJoystick = 0;
  502. }
  503.  
  504.  
  505. BOOL PASCAL JoystickEffectsEnum(LPCDIEFFECTINFO pdei, LPVOID pvRef)
  506. {
  507.     return true;
  508. }
  509.  
  510.  
  511. void TDIDevice::SetForce(float x, float y)
  512. {
  513.     if (!fEffect) return;
  514.  
  515.     // Modifying an effect is basically the same as creating
  516.     // a new one, except you need only specify the parameters
  517.     // you are modifying; the rest are left alone.
  518.     LONG rglDirection[2] = { (LONG)x, (LONG)y };
  519.  
  520.     DICONSTANTFORCE        cf;
  521.     DIEFFECT            eff;
  522.     cf.lMagnitude = (DWORD)sqrt( (double)x * (double)x +
  523.                                  (double)y * (double)y );
  524.  
  525.     eff.dwSize = sizeof(DIEFFECT);
  526.     eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
  527.     eff.cAxes = 2;
  528.     eff.rglDirection = rglDirection;
  529.     eff.lpEnvelope = 0;
  530.     eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
  531.     eff.lpvTypeSpecificParams = &cf;
  532.  
  533.     // now set the new parameters and start the effect immediately.
  534.     HRESULT hr;
  535.     hr = fEffect->SetParameters(    &eff, 
  536.                                     DIEP_DIRECTION |
  537.                                     DIEP_TYPESPECIFICPARAMS |
  538.                                     DIEP_START );
  539.  
  540.     if (FAILED(hr)) assert(false);
  541. }
  542.  
  543.  
  544. //
  545. //  BOOL PASCAL InitialiseJoystickEnum(LPCDIDEVICEINSTANCE pdinst, LPVOID pvRef) 
  546. //
  547. //   Call back for enumeration of the joystick devices
  548. //
  549. BOOL PASCAL InitialiseJoystickEnum(LPCDIDEVICEINSTANCE pdinst, LPVOID pvRef) 
  550.    TDIHandler*        handler = (TDIHandler*)pvRef;
  551.    HRESULT            hResult;
  552.  
  553. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION
  554.    // DirectX 8 pointers
  555.    LPDIRECTINPUT8            pdi = handler->fDI;
  556. #else
  557.    // Previous version pointers
  558.    LPDIRECTINPUT            pdi = handler->fDI; 
  559.    LPDIRECTINPUTDEVICE        tempDevice;          // Till we get a v2 interface
  560. #endif
  561.  
  562.    if (handler->fDevice[handler->fNumDevices] == NULL)              
  563.    {
  564.       handler->fDevice[handler->fNumDevices] = new TDIJoystick;
  565.       assert (handler->fDevice[handler->fNumDevices] != NULL);
  566.    }
  567.  
  568. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION
  569.     #if D3D_SDK_VERSION == DX_BETA_WEEKLY2
  570.         hResult = pdi->CreateDevice(    pdinst->guidInstance,
  571.                                         &handler->fDevice[handler->fNumDevices]->fDevice,
  572.                                         NULL );
  573.     #else
  574.         hResult = pdi->CreateDeviceEx(    pdinst->guidInstance,
  575.                                         IID_IDirectInputDevice8,
  576.                                         (LPVOID*) &handler->fDevice[handler->fNumDevices]->fDevice,
  577.                                         NULL );
  578.     #endif
  579. #else
  580.     hResult = pdi->CreateDevice(    pdinst->guidInstance,
  581.                                     &tempDevice,
  582.                                     NULL );
  583. #endif
  584.  
  585.     if( FAILED( hResult ) )
  586.     { 
  587.         OutputDebugString("IDirectInput::CreateDevice FAILED\n"); 
  588.         delete handler->fDevice[handler->fNumDevices];
  589.         handler->fDevice[handler->fNumDevices] = NULL;
  590.         return DIENUM_CONTINUE;    
  591.     } 
  592.  
  593. #if DIRECTINPUT_VERSION < DIRECTINPUT8_VERSION
  594.     //  Get a version 2 interface
  595.     if (tempDevice->QueryInterface(IID_IDirectInputDevice2, (VOID**)&handler->fDevice[handler->fNumDevices]->fDevice) != DI_OK)
  596.     { 
  597.         OutputDebugString("IDirectInput::Getting device interface 2 FAILED\n"); 
  598.         delete handler->fDevice[handler->fNumDevices];
  599.         handler->fDevice[handler->fNumDevices] = NULL;
  600.         return DIENUM_CONTINUE;    
  601.     }
  602. #endif
  603.  
  604.     //  Tell direct input its a joystick
  605.     if (handler->fDevice[handler->fNumDevices]->fDevice->SetDataFormat(&c_dfDIJoystick) != DI_OK) 
  606.     { 
  607.         OutputDebugString("IDirectInputDevice::SetDataFormat FAILED\n"); 
  608.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  609.         delete handler->fDevice[handler->fNumDevices];
  610.         handler->fDevice[handler->fNumDevices] = NULL;
  611.         return DIENUM_CONTINUE; 
  612.     } 
  613.  
  614.     // Set the cooperation level
  615.     //if(handler->fDevice[handler->fNumDevices]->fDevice->SetCooperativeLevel(ghWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK) 
  616.     if(handler->fDevice[handler->fNumDevices]->fDevice->SetCooperativeLevel(ghWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) 
  617.     { 
  618.         OutputDebugString("IDirectInputDevice::SetCooperativeLevel FAILED\n"); 
  619.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  620.         delete handler->fDevice[handler->fNumDevices];
  621.         handler->fDevice[handler->fNumDevices] = NULL;
  622.         return DIENUM_CONTINUE;
  623.     } 
  624.  
  625.  
  626.     // Set the range to be returned for the x-axis, from -1000 to 1000
  627.     DIPROPRANGE diprg;     
  628.     diprg.diph.dwSize       = sizeof(diprg); 
  629.     diprg.diph.dwHeaderSize = sizeof(diprg.diph); 
  630.     diprg.diph.dwObj        = DIJOFS_X; 
  631.     diprg.diph.dwHow        = DIPH_BYOFFSET;    
  632.     diprg.lMin              = -1000; 
  633.     diprg.lMax              = +1000;  
  634.    
  635.     if FAILED(handler->fDevice[handler->fNumDevices]->fDevice->SetProperty(DIPROP_RANGE, &diprg.diph))    
  636.     { 
  637.         OutputDebugString("IDirectInputDevice::SetProperty(DIPH_RANGE) FAILED\n");       
  638.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  639.         delete handler->fDevice[handler->fNumDevices];
  640.         handler->fDevice[handler->fNumDevices] = NULL;
  641.         return DIENUM_CONTINUE;    
  642.     }
  643.  
  644.     // Set the range to be returned for the y-axis, from -1000 to 1000
  645.     diprg.diph.dwSize       = sizeof(diprg); 
  646.     diprg.diph.dwHeaderSize = sizeof(diprg.diph); 
  647.     diprg.diph.dwObj        = DIJOFS_Y; 
  648.     diprg.diph.dwHow        = DIPH_BYOFFSET;    
  649.     diprg.lMin              = -1000; 
  650.     diprg.lMax              = +1000;  
  651.  
  652.     if FAILED(handler->fDevice[handler->fNumDevices]->fDevice->SetProperty(DIPROP_RANGE, &diprg.diph))    
  653.     { 
  654.         OutputDebugString("IDirectInputDevice::SetProperty(DIPH_RANGE) FAILED\n");       
  655.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  656.         delete handler->fDevice[handler->fNumDevices];
  657.         handler->fDevice[handler->fNumDevices] = NULL;
  658.         return DIENUM_CONTINUE;    
  659.     } 
  660.  
  661.  
  662.     // Set the dead zone to extend for half the range of the x axis movement
  663.     DIPROPDWORD dipdead;
  664.  
  665.     dipdead.diph.dwSize       = sizeof(dipdead); 
  666.     dipdead.diph.dwHeaderSize = sizeof(dipdead.diph); 
  667.     dipdead.diph.dwObj        = DIJOFS_X; 
  668.     dipdead.diph.dwHow        = DIPH_BYOFFSET;   
  669.     dipdead.dwData = 0;
  670.     //(gPreferences.fUseWheel) ? dipdead.dwData = 0 : dipdead.dwData = 200; // the range
  671.  
  672.  
  673.     // set X axis dead zone to 50% (to avoid accidental turning) 
  674.     if FAILED(handler->fDevice[handler->fNumDevices]->fDevice->SetProperty(DIPROP_DEADZONE, &dipdead.diph)) 
  675.     { 
  676.         OutputDebugString("IDirectInputDevice:: SetProperty(DIPH_DEADZONE) FAILED\n"); 
  677.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  678.         delete handler->fDevice[handler->fNumDevices];
  679.         handler->fDevice[handler->fNumDevices] = NULL;
  680.         return DIENUM_CONTINUE;    
  681.     } 
  682.  
  683.     // Set the dead zone to extend for half the range of the y axis movement
  684.     dipdead.diph.dwSize       = sizeof(dipdead); 
  685.     dipdead.diph.dwHeaderSize = sizeof(dipdead.diph); 
  686.     dipdead.diph.dwObj        = DIJOFS_Y; 
  687.     dipdead.diph.dwHow        = DIPH_BYOFFSET;    
  688.     dipdead.dwData            = 200;                 // the range
  689.  
  690.  
  691.     // set X axis dead zone to 50% (to avoid accidental turning) 
  692.     if FAILED(handler->fDevice[handler->fNumDevices]->fDevice->SetProperty(DIPROP_DEADZONE, &dipdead.diph)) 
  693.     { 
  694.         OutputDebugString("IDirectInputDevice:: SetProperty(DIPH_DEADZONE) FAILED\n"); 
  695.         handler->fDevice[handler->fNumDevices]->fDevice->Release(); 
  696.         delete handler->fDevice[handler->fNumDevices];
  697.         handler->fDevice[handler->fNumDevices] = NULL;
  698.         return DIENUM_CONTINUE;    
  699.     } 
  700.  
  701.     {
  702.         HRESULT hr;
  703.  
  704.         // remove the force centering effect
  705.  
  706.         DIPROPDWORD dipdw;
  707.         dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  708.         dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  709.         dipdw.diph.dwObj = 0;
  710.         dipdw.diph.dwHow = DIPH_DEVICE;
  711.         dipdw.dwData = FALSE;
  712.  
  713.         //hr = handler->fDevice[handler->fNumDevices]->fDevice->
  714.         //    SetProperty( DIPROP_AUTOCENTER, &dipdw.diph );
  715. //        if (hr != DI_OK) assert(false);     // Removed ph 10/11/98
  716.  
  717.         // This application needs only one effect:  Applying raw forces.
  718.         DIEFFECT eff;
  719.         DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y };
  720.         LONG rglDirection[2] = { 0, 0 };
  721.         DICONSTANTFORCE cf = { 0 };
  722.  
  723.         eff.dwSize = sizeof(DIEFFECT);
  724.         eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
  725.         eff.dwDuration = INFINITE;
  726.         eff.dwSamplePeriod = 0;
  727.         eff.dwGain = DI_FFNOMINALMAX;
  728.         eff.dwTriggerButton = DIEB_NOTRIGGER;
  729.         eff.dwTriggerRepeatInterval = 0;
  730.         eff.cAxes = 2;
  731.         eff.rgdwAxes = rgdwAxes;
  732.         eff.rglDirection = rglDirection;
  733.         eff.lpEnvelope = 0;
  734.         eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
  735.         eff.lpvTypeSpecificParams = &cf;
  736.  
  737.         // create the prepared effect
  738.         hr = handler->fDevice[handler->fNumDevices]->fDevice->
  739.             CreateEffect(GUID_ConstantForce,
  740.                 &eff,
  741.                 &handler->fDevice[handler->fNumDevices]->fEffect,
  742.                 NULL );
  743.  
  744. //        assert(hr == DI_OK);  // Removed ph 10/11/98 
  745.  
  746.         /*
  747.         if (hr != DI_OK)
  748.         {
  749.             int error = -1;
  750.             switch(hr)
  751.             {
  752.             case DIERR_DEVICENOTREG:
  753.                 error = 1;
  754.                 break;
  755.             case DIERR_DEVICEFULL:
  756.                 error = 2;
  757.                 break;
  758.             case DIERR_INVALIDPARAM:
  759.                 error = 3;
  760.                 break;
  761.             case DIERR_NOTINITIALIZED:
  762.                 error = 4;
  763.                 break;
  764.             default:
  765.                 assert(false);
  766.             }
  767.             assert(hr == DI_OK);
  768.         }
  769.         */
  770.     }
  771.  
  772.     // Fill in the buffers for later
  773.     handler->fDevice[handler->fNumDevices]->fBufSize = sizeof(DIJOYSTATE);
  774.     handler->fDevice[handler->fNumDevices]->fBuffer = new char[sizeof(DIJOYSTATE)];
  775.     assert (handler->fDevice[handler->fNumDevices]->fBuffer != NULL);
  776.  
  777.     handler->fNumDevices++;      // Succesfully got one
  778.     return DIENUM_CONTINUE;    
  779. }
  780.  
  781.  
  782. void TDIHandler::GrabMouse()
  783. {
  784.     HRESULT hr; 
  785.     if (fMouse != NULL)
  786.     {
  787.         hr = fMouse->Acquire();
  788.     }
  789. }
  790.  
  791. void TDIHandler::ReleaseMouse()
  792. {
  793.     HRESULT hr; 
  794.     if (fMouse != NULL)
  795.     {
  796.         hr = fMouse->Unacquire();
  797.     }
  798. }
  799.  
  800.  
  801. void TDIHandler::InitMouse()
  802. {
  803.     assert (fMouse == NULL);
  804.  
  805.     HRESULT hResult;
  806.  
  807. #if DIRECTINPUT_VERSION >= DIRECTINPUT8_VERSION
  808.     // (DirectX8) Create Mouse Device
  809.     #if D3D_SDK_VERSION == DX_BETA_WEEKLY2
  810.         hResult = fDI->CreateDevice(    GUID_SysMouse,
  811.                                         &fMouse,
  812.                                         NULL );
  813.     #else
  814.         hResult = fDI->CreateDeviceEx(    GUID_SysMouse,
  815.                                         IID_IDirectInputDevice8,
  816.                                         (LPVOID*) &fMouse,
  817.                                         NULL );
  818.     #endif
  819. #else
  820.     // (Previous versions) Create Mouse Device
  821.     hResult = fDI->CreateDevice(    GUID_SysMouse,
  822.                                     &fMouse,
  823.                                     NULL);
  824. #endif
  825.     assert (SUCCEEDED(hResult));
  826.     assert (fMouse != NULL);
  827.  
  828.     // set data format
  829.     hResult = fMouse->SetDataFormat( &c_dfDIMouse );
  830.     assert (SUCCEEDED(hResult));
  831.  
  832.     // set cooperative level
  833.     hResult = fMouse->SetCooperativeLevel( ghWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND ); 
  834.     assert (SUCCEEDED(hResult));
  835. }
  836.