Página principal   Lista alfabética   Lista de componentes   Lista de archivos   Miembros de las clases   Archivos de los miembros  

joy.cpp

Ir a la documentación de este archivo.
00001 #include "joy.h"
00002 
00003 enum DeviceKind { keyboard, mouse, joystick } CurrentDevice;
00004 BOOL                                    g_FFAvailable;
00005 LPDIRECTINPUTDEVICE2    g_lpdidKeyboard,g_lpdidJoy;
00006 LPDIRECTINPUT                   lpdi;
00007 DIDEVICEINSTANCE                diDeviceInstanceKeyb, diDeviceInstanceJoy;
00008 DWORD                                   ChangeButton;
00009 LPDIRECTINPUTEFFECT             g_lpTriggerEffect;
00010 BOOL                                    g_TriggerOK;
00011 
00012 DLL_EXPORT int STD IniciarDInput (long Tipo_Dispositivo)
00013 {
00014         HRESULT                                 hr;
00015         HINSTANCE                               hinst;
00016         
00017         switch (Tipo_Dispositivo)
00018         {
00019         case 0:
00020                 CurrentDevice=keyboard;
00021                 break;
00022         case 1:
00023                 CurrentDevice=joystick;
00024                 break;
00025         default:
00026                 CurrentDevice=keyboard;
00027                 break;
00028         }
00029 
00030         //  Intentamos crear un objeto Direct Input
00031 
00032         hinst=GetModuleHandle(NULL);
00033         hr=DirectInputCreate (hinst,DIRECTINPUT_VERSION,&lpdi,NULL);
00034 
00035         //      Si no se puede crear el objeto Direct Input devolvemos false
00036 
00037         if (hr!=DI_OK){
00038                 return false;
00039         }
00040         
00041         //      Hemos conseguido crear el objeto Direct Input y continuamos
00042         //   continuamos con su inicialización
00043 
00044         lpdi->EnumDevices(DIDEVTYPE_JOYSTICK,Reasignacion,lpdi,DIEDFL_ATTACHEDONLY);
00045         g_lpdidKeyboard=CreateDevice2 (lpdi,( GUID * )&GUID_SysKeyboard);
00046 
00047         diDeviceInstanceKeyb.dwSize = sizeof( DIDEVICEINSTANCE );
00048         diDeviceInstanceJoy.dwSize = sizeof( DIDEVICEINSTANCE );
00049     g_lpdidKeyboard->GetDeviceInfo( &diDeviceInstanceKeyb );
00050         hr = g_lpdidKeyboard->SetDataFormat( &c_dfDIKeyboard );
00051 
00052         if ( g_lpdidJoy == NULL ) 
00053         {
00054                 if (CurrentDevice==joystick) CurrentDevice=keyboard;
00055         }
00056         else if ( g_lpdidJoy != NULL )
00057         {
00058                 g_lpdidJoy->GetDeviceInfo( &diDeviceInstanceJoy );
00059                 if ( GET_DIDEVICE_TYPE( diDeviceInstanceJoy.dwDevType )== DIDEVTYPE_JOYSTICK)
00060                 {
00061             hr = g_lpdidJoy->SetDataFormat( &c_dfDIJoystick );
00062                 }
00063         }
00064 /*
00065     switch ( GET_DIDEVICE_TYPE( diDeviceInstanceJoy.dwDevType ) )
00066     {
00067                 case DIDEVTYPE_KEYBOARD:
00068             hr = g_lpdidKeyboard->SetDataFormat( &c_dfDIKeyboard );
00069             CurrentDevice = keyboard;
00070             break;
00071 
00072         case DIDEVTYPE_MOUSE:
00073             hr = g_lpdid2->SetDataFormat( &c_dfDIMouse );
00074             CurrentDevice = mouse;
00075             break;
00076 
00077         case DIDEVTYPE_JOYSTICK:
00078             hr = g_lpdidJoy->SetDataFormat( &c_dfDIJoystick );
00079             CurrentDevice = joystick;
00080             break;
00081     }
00082 */
00083         // Fijar el nivel cooperativo. 
00084 /*
00085     DWORD cl, cl1;
00086     if ( CurrentDevice == keyboard ) 
00087     {
00088                 cl = DISCL_NONEXCLUSIVE;
00089         }
00090     else 
00091         {
00092                 cl = DISCL_EXCLUSIVE;
00093         }
00094 
00095 // Fije nivel de primer plano para la versión comercial, pero use el nivel de segundo plano
00096 // para la depuración para no perder el dispositivo cuando pase a una ventana del 
00097 // depurador. Fíjese en que el ratón no puede tener nivel de segundo plano exclusivo.
00098 
00099     cl1 = DISCL_FOREGROUND;
00100 #ifdef _DEBUG
00101     cl1 = DISCL_BACKGROUND;
00102     if ( CurrentDevice == mouse ) cl = DISCL_NONEXCLUSIVE;
00103 #endif
00104 
00105     if ( FAILED( g_lpdid2->SetCooperativeLevel( handle,
00106                                 cl | cl1 ) ) )
00107     {
00108         OutputDebugString( "Fallo al fijar el nivel cooperativo del dispositivo de juego.\n" );
00109         g_lpdid2 = NULL;
00110     }
00111 */
00112     // Configurar el buffer de datos.
00113 
00114     DIPROPDWORD dipdw =
00115     {
00116         // La cabecera, la cual inicializamos   (DIPROHEADER)
00117         {
00118             sizeof( DIPROPDWORD ),      // diph.dwSize
00119             sizeof( DIPROPHEADER ),     // diph.dwHeaderSize
00120             0,                          // diph.dwObj
00121             DIPH_DEVICE,                // diph.dwHow
00122         },
00123         // Número de elementos en el buffer de datos    (DWORD)
00124         BUFFERSIZE,              // dwData              
00125     };
00126 
00127         switch (CurrentDevice)
00128         {
00129         case keyboard:
00130                 g_lpdidKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
00131                 break;
00132         case joystick:
00133                 g_lpdidJoy->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
00134                 break;
00135         }
00136 
00137         if ( CurrentDevice == joystick )
00138     { 
00139         IniJoystick();  
00140     }
00141         SetAcquireState( TRUE );
00142         return true;
00143 }
00144 
00145 int STD Reasignacion (LPCDIDEVICEINSTANCE pdinst, LPVOID pvRef)
00146 {       
00147         LPDIRECTINPUT pdi = LPDIRECTINPUT (pvRef); 
00148 
00149         g_lpdidJoy=CreateDevice2 (pdi,( GUID * ) &pdinst->guidInstance);
00150         return DIENUM_CONTINUE; 
00151 }
00152 
00153 LPDIRECTINPUTDEVICE2 CreateDevice2( LPDIRECTINPUT lpdi, GUID* pguid)
00154 {
00155     HRESULT hr, hr2;
00156   
00157     LPDIRECTINPUTDEVICE  lpdid1;  // Temporal.
00158     LPDIRECTINPUTDEVICE2 lpdid2;  // Para guardar la interfaz.
00159 
00160     hr = lpdi->CreateDevice( *pguid, &lpdid1, NULL );
00161  
00162     if ( SUCCEEDED( hr ) )
00163     { 
00164         hr2 = lpdid1->QueryInterface( IID_IDirectInputDevice2, 
00165                                       ( void ** )&lpdid2 ); 
00166         lpdid1->Release();
00167     } 
00168     else
00169     {
00170         OutputDebugString( 
00171                         "No se pudo crear el dispositivo IDirectInputDevice" );
00172         return NULL;
00173     } 
00174     if ( FAILED( hr2 ) )
00175     {
00176         OutputDebugString( 
00177                         "No se pudo crear el dispositivo IDirectInputDevice2" );
00178         return NULL;
00179     } 
00180     return lpdid2;
00181 }  // CreateDevice2
00182 
00183 BOOL IniJoystick( void )
00184 {
00185     // Fijar ranto. 
00186     // Nota: rango, zona muerta, y saturación se fijan para todo el
00187     // dispositivo. Ello podría provocar efectos no deseados sobre
00188     // los mandos deslizantes, ruedecillas, etc.
00189 
00190     DIPROPRANGE diprg; 
00191  
00192     diprg.diph.dwSize       = sizeof( diprg ); 
00193     diprg.diph.dwHeaderSize = sizeof( diprg.diph ); 
00194     diprg.diph.dwObj        = 0; 
00195     diprg.diph.dwHow        = DIPH_DEVICE; 
00196     diprg.lMin              = JOYMIN; 
00197     diprg.lMax              = JOYMAX; 
00198  
00199     if ( FAILED( g_lpdidJoy->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
00200         return FALSE; 
00201 
00202     // Fijar zona muerta.
00203     DIPROPDWORD dipdw;
00204 
00205     dipdw.diph.dwSize       = sizeof( dipdw ); 
00206     dipdw.diph.dwHeaderSize = sizeof( dipdw.diph ); 
00207     dipdw.diph.dwObj        = 0;
00208     dipdw.diph.dwHow        = DIPH_DEVICE;
00209     dipdw.dwData            = JOYDEAD;
00210 
00211     if ( FAILED( g_lpdidJoy->SetProperty( DIPROP_DEADZONE, &dipdw.diph ) ) )
00212         return FALSE;
00213 
00214     // Fijar saturación.
00215     dipdw.dwData            = JOYSAT;
00216     if ( FAILED( g_lpdidJoy->SetProperty( DIPROP_SATURATION, &dipdw.diph ) ) )
00217         return FALSE;
00218 
00219     // Averiguar si hay disponibles efectos resistivos.
00220     DIDEVCAPS didc;
00221     didc.dwSize = sizeof( DIDEVCAPS );
00222     if ( FAILED( g_lpdidJoy->GetCapabilities( &didc ) ) ) 
00223         return FALSE;
00224     g_FFAvailable = ( didc.dwFlags & DIDC_FORCEFEEDBACK );
00225 
00226     // Si es un joystick con efectos resistivos, desactivar el auto centrado para que
00227     // se interponga con nuestros efectos.
00228     if ( g_FFAvailable )
00229     {
00230         DIPROPDWORD DIPropAutoCenter;
00231         DIPropAutoCenter.diph.dwSize = sizeof( DIPropAutoCenter );
00232         DIPropAutoCenter.diph.dwHeaderSize = sizeof( DIPROPHEADER );
00233         DIPropAutoCenter.diph.dwObj = 0;
00234         DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
00235         DIPropAutoCenter.dwData = 0;
00236 
00237         g_lpdidJoy->SetProperty( DIPROP_AUTOCENTER, 
00238                                &DIPropAutoCenter.diph );
00239     } 
00240     return TRUE;
00241 }   // InitJoystick
00242 
00243 BOOL SetAcquireState( BOOL acq )
00244 {
00245     HRESULT hr;
00246 
00247     if ( !acq )  // Desadquirir.
00248     {
00249                 switch (CurrentDevice)
00250                 {
00251                 case keyboard:
00252                         hr = g_lpdidKeyboard->Unacquire();
00253                         break;
00254                 case joystick:
00255                         hr = g_lpdidJoy->Unacquire();
00256                         break;
00257                 }
00258     }
00259     else       // Adquirir.
00260     {
00261 // Podría llevar algo de tiempo con efectos resistivos.
00262                 switch (CurrentDevice)
00263                 {
00264                 case keyboard:
00265                         hr = g_lpdidKeyboard->Acquire();
00266                         break;
00267                 case joystick:
00268                         hr = g_lpdidJoy->Acquire();
00269                         break;
00270                 }
00271 
00272 /*        if ( SUCCEEDED( hr ) ) 
00273         {
00274             // Inicializar efectos; ignorar los fallos y sólo
00275             // solicitar efectos resistivos.
00276             if ( g_FFAvailable )      // Fijada por vez primera al inicializar el dispositivo.
00277             {
00278                 g_FFAvailable = InitFFEffects();
00279             }
00280         }
00281 */
00282     }
00283     /* Mientras estamos aquí, podríamos recuperar el tiempo de doble clic.
00284        Si el usuario está regresando del Panel de control aquí se obtendra cualquier
00285        configuración nueva. */
00286 
00287 //    DoubleClickTime = GetDoubleClickTime();
00288 
00289     return ( SUCCEEDED( hr ) );
00290 } // SetAcquireState
00291 
00292 
00293 /****************************************************************
00294 **  Devuelve el estado de las teclas de control del Navegador  **
00295 **   cuando si utilizamos el Direct Input                      **
00296 *****************************************************************/
00297 DLL_EXPORT Respuesta STD DirectInputPollDevice( void )
00298 {
00299     DIJOYSTATE                  dijs;
00300     char                                keys[256]; 
00301     static      DWORD           LastClickTime;
00302         long                            dato=10;
00303         Respuesta                       Pulsiones;                      
00304     HRESULT                             hr;
00305     DIDEVICEOBJECTDATA  rgdod[BUFFERSIZE];
00306     DWORD                               dwItems; 
00307 
00308         Pulsiones.Abajo=Pulsiones.Arriba=Pulsiones.Izquierda=Pulsiones.Derecha=false;
00309         Pulsiones.Switch =false;
00310 
00311         ChangeButton=BOTON_ELEGIDO;
00312 
00313         switch (CurrentDevice)
00314         {
00315         case keyboard:
00316                 if ( !g_lpdidKeyboard ) return Pulsiones;
00317                 break;
00318         case joystick:
00319                 if ( !g_lpdidJoy ) return Pulsiones;
00320                 break;
00321         }
00322 
00323 getBufferedData:
00324 
00325     dwItems = BUFFERSIZE;
00326         switch (CurrentDevice)
00327         {
00328         case keyboard:
00329             g_lpdidKeyboard->Poll();  // Puede no ser necesario, pero no perjudica.
00330 
00331                 hr = g_lpdidKeyboard->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), 
00332                                                 rgdod,         // ¿Dónde colocar los datos?
00333                                                 &dwItems,      // ¿Cuántos elementos?
00334                                                 0 );           // Banderas.
00335                 break;
00336         case joystick:
00337             g_lpdidJoy->Poll();  // Puede no ser necesario, pero no perjudica.
00338 
00339                 hr = g_lpdidJoy->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), 
00340                                                 rgdod,         // ¿Dónde colocar los datos?
00341                                                 &dwItems,      // ¿Cuántos elementos?
00342                                                 0 );           // Banderas.
00343                 break;
00344         }
00345 
00346     // Si se interrumpió el flujo de datos, readquirir el dispositivo e intentarlo de nuevo.
00347     if ( hr == DIERR_INPUTLOST )
00348     {
00349         if ( SetAcquireState( TRUE ) )
00350             goto getBufferedData;
00351     }
00352 
00353     // No podemos adquirir el dispositivo. Abandonar.
00354     if ( hr == DIERR_NOTACQUIRED )
00355     {
00356         OutputDebugString( "¡Dispositivo no adquirido!" );
00357         return Pulsiones;
00358     }
00359 
00360     // Obtuvimos entrada desde un buffer; actuar.
00361 /*    if ( SUCCEEDED( hr ) ) 
00362     { 
00363         // dwItems ahora contiene el número de elementos leídos (podría ser 0).
00364         // Pasamos por la secuencia de sucesos. Si el suceso está asociado con
00365         // un botón de disparo definido por el usuario, y si el botón "está pulsado"
00366         // disparamos.
00367 
00368         for ( DWORD d = 0; d < dwItems; d++ )
00369         {
00370             if ( rgdod[d].dwOfs == BOTON_ELEGIDO ) // Si es el botón de disparo.
00371             {
00372                                 Pulsiones.Switch =true;
00373                                 for (i=0;i<=BUFFERSIZE;i++){rgdod[i].dwOfs =NULL;}
00374             }  // If botón de disparo.
00375 
00376             if ( CurrentDevice == mouse )
00377             {
00378                 if ( rgdod[d].dwOfs == DIMOFS_X )
00379 //                    UpdateCursorPosition( rgdod[d].dwData, 0 );
00380                 else if ( rgdod[d].dwOfs == DIMOFS_Y )
00381 //                    UpdateCursorPosition( 0, rgdod[d].dwData );
00382             } // Ratón.
00383 
00384         }  // Concluido el bucle de sucesos.
00385         }
00386 */    
00387 getImmediateData:
00388     switch ( CurrentDevice )
00389     {
00390         case keyboard:
00391             hr = g_lpdidKeyboard->GetDeviceState( sizeof( keys ), keys );  
00392             break;
00393         case joystick:
00394             hr = g_lpdidJoy->GetDeviceState( sizeof( DIJOYSTATE ), &dijs ); 
00395             break;
00396     }
00397 
00398     // Se interrupió el flujo de datos. Readquirir el dispositivo e intentarlo de nuevo.
00399     if ( hr == DIERR_INPUTLOST )
00400     {
00401         if ( SetAcquireState( TRUE ) )
00402             goto getImmediateData;
00403     }
00404     if ( hr == DIERR_NOTACQUIRED )
00405     {
00406         OutputDebugString( "¡Dispositivo no adquirido!" );
00407         return Pulsiones;
00408     }
00409 
00410     // Tenemos datos inmediatos, actuar sobre ellos.  
00411     if ( SUCCEEDED( hr ) )
00412     {
00413         switch ( CurrentDevice )
00414         {
00415             case keyboard:
00416                 if ( BUTTONDOWN( keys[DIK_LEFT] ) )
00417                                         Pulsiones.Izquierda=true;
00418                                 if ( BUTTONDOWN( keys[DIK_RIGHT] ) )
00419                                         Pulsiones.Derecha=true;
00420                                 if ( BUTTONDOWN( keys[DIK_UP] ) )
00421                                         Pulsiones.Arriba=true;
00422                 if ( BUTTONDOWN( keys[DIK_DOWN] ) )
00423                                         Pulsiones.Abajo=true;
00424                                 if (BUTTONDOWN( keys[57])){
00425                                         Pulsiones.Switch=true;
00426                                         Sleep (500);
00427                                 }
00428                 break;
00429 
00430             case mouse:
00431                 break;
00432 
00433             case joystick:
00434                 if ( dijs.lX < 0 ) 
00435                                         Pulsiones.Izquierda=true;
00436                 if ( dijs.lX > 0 ) 
00437                                         Pulsiones.Derecha=true;
00438                 if ( dijs.lY < 0 ) 
00439                                         Pulsiones.Arriba=true;
00440                 if ( dijs.lY > 0 ) 
00441                                         Pulsiones.Abajo=true;
00442                 break;
00443 
00444         } // switch
00445 
00446         return Pulsiones;  // Tuvimos datos.
00447     }
00448     else              // FAILED( hr )
00449         return Pulsiones;
00450 }  // PollDevice()
00451 
00452 
00453 /****************************************************************
00454 **  Devuelve el estado de las teclas de control del Navegador  **
00455 **   cuando no utilizamos el Direct Input                      **
00456 *****************************************************************/
00457 DLL_EXPORT Respuesta STD NonDirectInputPollDevice( void )
00458 {
00459         Respuesta                       Pulsiones;      
00460         BYTE                            KeysState[256];
00461 
00462         //      Inicializamos el estado de las pulsaciones a falso
00463         Pulsiones.Abajo=Pulsiones.Arriba=Pulsiones.Izquierda=Pulsiones.Derecha=false;
00464         Pulsiones.Switch =false;
00465 
00466         GetKeyboardState((LPBYTE)&KeysState);
00467 
00468         //  Comparamos el estado de KeysState[tecla] con el bit
00469         //  más significativo que es el que me dice si esta pulsada
00470         //  o no
00471         if (KeysState[VK_UP] & 128) Pulsiones.Arriba=true;
00472         if (KeysState[VK_DOWN] & 128) Pulsiones.Abajo=true;
00473         if (KeysState[VK_LEFT] & 128) Pulsiones.Izquierda=true;
00474         if (KeysState[VK_RIGHT] & 128) Pulsiones.Derecha=true;
00475         if (KeysState[VK_SPACE] & 128) Pulsiones.Switch=true;
00476         return Pulsiones;
00477 }
00478 
00479 DLL_EXPORT void STD CerrarDInput (void)
00480 {
00481     SetAcquireState( FALSE );
00482 
00483     g_lpdidKeyboard->Release();
00484     g_lpdidKeyboard=NULL;
00485 
00486     if ( g_lpdidJoy != NULL ) 
00487     {
00488         g_lpdidJoy->Release();
00489         g_lpdidJoy = NULL;
00490     }
00491 
00492     if ( lpdi != NULL )
00493     { 
00494         lpdi->Release();
00495         lpdi = NULL;
00496     }
00497 }
00498 

Generado el Tue Apr 24 06:55:48 2001 para Dllcontrol por doxygen1.2.6 escrito por Dimitri van Heesch, © 1997-2001