Tutorial de SDL – Parte 20 – Force Feedback

Continuando nossa série de artigos traduzido do site lazyfoo, e agora que sabemos como usar joysticks com SDL, veremos agora como usar a nova API haptics para fazer o dispositivo vibrar.

//Game Controller 1 handler with force feedback
SDL_Joystick* gGameController = NULL;
SDL_Haptic* gControllerHaptic = NULL;
Um dispositivo háptico é um tipo de dispositivo que fornece algum tipo de feedback físico. No nosso caso, faz o joystick vibrar. O tipo de dado para um dispositivo háptico é chamado intuitivamente de SDL_haptic.
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC ) < 0 )
{
   printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
   success = false;
}
Como no caso do subsistema de joystick, você precisa se certificar de inicializar o subsistema háptico especifico para poder os recursos necessários.
//Check for joysticks
if( SDL_NumJoysticks() < 1 )
{
   printf( "Warning: No joysticks connected!\n" );
}
else
{
   //Load joystick
   gGameController = SDL_JoystickOpen( 0 );
   if( gGameController == NULL )
   {
      printf( "Warning: Unable to open game controller! SDL Error: %s\n", SDL_GetError() );
   }
   else
   {
      //Get controller haptic device gControllerHaptic = SDL_HapticOpenFromJoystick( gGameController );
      if( gControllerHaptic == NULL )
      {
         printf( "Warning: Controller does not support haptics! SDL Error: %s\n", SDL_GetError() );
         }
         else
         {
            //Get initialize rumble
            if( SDL_HapticRumbleInit( gControllerHaptic ) < 0 )
            {
               printf( "Warning: Unable to initialize rumble! SDL Error: %s\n", SDL_GetError() );
            }
         }
      }
}

Após inicializar o joystick, precisamos obter o dispositivo háptico do joystick usando a função SDL_HapticOpenFromJoystick com um joystick aberto. Se conseguirmos obter esse tipo de dispositivo de um joystick, temos que inicializar a vibração usando SDL_HapticRumbleInit.

void close()
{
   //Free loaded images
   gSplashTexture.free();
   //Close game controller with haptics
   SDL_HapticClose( gControllerHaptic );
   SDL_JoystickClose( gGameController );
   gGameController = NULL;
   gControllerHaptic = NULL;
   //Destroy window
   SDL_DestroyRenderer( gRenderer );
   SDL_DestroyWindow( gWindow );
   gWindow = NULL;
   gRenderer = NULL;
   //Quit SDL subsystems
   IMG_Quit(); SDL_Quit();
}
Assim que tivermos finalizado o uso de um dispositivo háptico, chamamos a função SDL_HapticClose.
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
   //User requests quit
   if( e.type == SDL_QUIT )
   {
      quit = true;
   }
   //Joystick button press
   else if( e.type == SDL_JOYBUTTONDOWN )
   {
      //Play rumble at 75% strenght for 500 milliseconds
      if( SDL_HapticRumblePlay( gControllerHaptic, 0.75, 500 ) != 0 )
      {
         printf( "Warning: Unable to play rumble! %s\n", SDL_GetError() );
      }
   }
}
Para fazer o joystick vibrar de fato, você precisa executar algum tipo de vibração. A maneira mais fácil de fazer isso é chamando SDL_HapticRumblePlay, que recebe o dispositivo háptico, a força (em percentual) e a duração da vibração. No exemplo, fazemos o joystick vibrar com uma força de 75& para meio segundo  toda vez que o evento SDL_JoyButtonEvent ocorre.
A API háptica do SDL 2 possui muitos outros recursos não cobertos aqui, incluindo a criação de efeitos personalizados e mouses hápticos. Você pode verificar esses recursos em SDL 2 force feedback documentation.
Baixe o código fonte para esse artigo aqui.