Skip to main content
Portar do XInput para o GameInput é a portabilidade menos complicada entre todas as APIs legadas. Isso ocorre porque o GameInput foi fortemente influenciado pelo modelo de programação simples (e fácil de usar) do XInput e, portanto, muitas APIs do XInput são mapeadas 1:1 com funções equivalentes no GameInput.

Principais diferenças

As principais diferenças entre o XInput e o GameInput são discutidas nas seções a seguir.

C vs. C++

A API XInput é uma coleção de funções C simples. O GameInput, por outro lado, é C++ e usa interfaces (assim como as APIs de gráficos e áudio). Na prática, isso não complica o código que usa a API GameInput, não afeta o desempenho e tem algumas vantagens que se tornam evidentes à medida que você se familiariza com o funcionamento do GameInput. É importante entender que, embora essas interfaces possam parecer COM, elas não são. Apenas um entendimento básico de contagem de referências é necessário para usar essas interfaces. Para obter mais informações, confira a seção Interfaces do tópico Fundamentos do GameInput.

Obtenção de entrada

No XInput, a maioria dos jogos percorre os índices de usuário em loop até encontrar um com um dispositivo conectado e, em seguida, o estado é lido desse dispositivo. Os jogos geralmente lembram o índice de usuário para não precisarem percorrer o loop na próxima vez. Por exemplo, o código a seguir é típico de um jogo que solicita ao usuário que “pressione A” no controle:
No GameInput, você primeiro obtém a entrada sem especificar um dispositivo e pode consultar de qual dispositivo a entrada veio, se quiser. O código é parecido, mas eliminar a necessidade de enumeração explícita de dispositivos pode levar a algoritmos mais simples.
O código não é tão simples quanto o do XInput, mas é muito parecido. À medida que você se familiarizar com a API GameInput, verá como esse modelo oferece opções poderosas para lidar com a entrada que não existem no XInput. Também vale observar que o XInput retorna os valores analógicos dos gatilhos como tipo BYTE e os valores analógicos dos direcionais analógicos como tipo SHORT. Com a API GameInput, esses valores analógicos são retornados como valores float de 0 a 1 (gatilhos) ou de -1 a 1 (direcionais analógicos).

Resposta de vibração

No XInput, os jogos simplesmente chamamXInputSetState para enviar comandos de vibração a um dispositivo. No GameInput, os jogos precisam obter a instância de IGameInputDevice do dispositivo e, em seguida, chamar o método SetRumbleState dela. O uso é semelhante entre esses dois métodos. Este é um exemplo de quando você chamará funções na interface do dispositivo, em vez de usá-la apenas como identificador de dispositivo.

Foco do aplicativo

No console, o GameInput fornece entrada a um aplicativo somente quando ele está em foco. Caso contrário, o estado retornado contém valores neutros ou de “repouso”, como se o usuário não estivesse tocando no dispositivo. Isso elimina a necessidade de código de entrada extra para lidar com a mudança de foco (por exemplo, chamarXInputEnable). No PC, por padrão, a entrada vai para todos os processos. No futuro, esse comportamento poderá ser alterado usando o método SetFocusPolicy.

O wrapper XInputOnGameInput

O Microsoft Game Development Kit (GDK) é fornecido com um arquivo de cabeçalho chamadoXInputOnGameInput.h que contém uma implementação da API XInput sobre o GameInput. Recomendamos portar diretamente para o GameInput, especialmente se você quiser teclado e mouse ou outros dispositivos de entrada. No entanto, o wrapper XInputOnGameInput pode ser usado para ajudar a iniciar um esforço inicial de portabilidade sem exigir alterações no código XInput existente. Para usar o wrapper XInputOnGameInput, basta substituir este código:
por este código:
e, em seguida, recompilar o código. A implementação do código do wrapper XInput está inteiramente no arquivo de cabeçalho, portanto, também pode ser examinada como exemplo de uso da API GameInput e/ou modificada conforme necessário.

Diferenças entre o XInput e o XInputOnGameInput

Em geral, o wrapper XInputOnGameInput é um substituto direto para a API XInput legada. No entanto, há algumas pequenas diferenças:
  • Para simplificar, apenas o suporte a dispositivos gamepad foi codificado no wrapper. Se você precisar dar suporte a outros dispositivos, como volantes de corrida ou arcade sticks, use o GameInput diretamente ou adicione suporte a esses dispositivos no código do XInputOnGameInput.
  • O wrapper retornará a entrada do gamepad somente quando o jogo estiver em foco. Quando o jogo não estiver em foco, qualquer estado de gamepad retornado é definido com valores neutros ou de “repouso”, como se o usuário não estivesse tocando no gamepad. Isso é feito independentemente de quaisquer chamadas aXInputEnable (ou da falta delas).
  • O valor deXUSER_MAX_COUNT foi aumentado de 4 para 8. Em geral, isso deve ser transparente para a maior parte do código XInput legado. No entanto, revise cuidadosamente qualquer uso da funçãoXInputGetKeystroke no seu código para ajudar a garantir que nada esteja codificado para presumir um valor máximo de 4 retornado no membroUserIndex da estruturaXINPUT_KEYSTROKE. Caso contrário, poderá ocorrer uma saturação de buffer.
  • Algumas novas funções foram adicionadas (veja a seguir), que devem interessar apenas se você pretende continuar usando o wrapper XInput em código de produção.

Uso do XInputOnGameInput em código de produção

O wrapper XInputOnGameInput foi escrito para ser de alto desempenho e livre de bloqueio, herdando todas as otimizações de desempenho da API GameInput e, portanto, é adequado para uso em código de produção. Ele também herda o suporte mais amplo a dispositivos do GameInput (como gamepads HID populares) e adiciona as seguintes novas funções à API:
  • XInputSetStateEx é semelhante aXInputSetState, mas adiciona suporte aos motores dos gatilhos.
  • XInputGetStateWithToken é semelhante aXInputGetState, mas permite que o chamador forneça um token de pipeline de quadro D3DX para associar uma leitura de entrada específica a um quadro gráfico para análise posterior no PIX.
    [!NOTE] Na versão May Preview,XInputGetStateWithToken atualmente se comporta de forma idêntica aXInputGetState, porque o código subjacente do GameInput não está totalmente implementado.
  • XInputGetDeviceId retorna oAPP_LOCAL_DEVICE_ID do dispositivo em um determinado índice de usuário. Passar essa ID para o método FindDeviceFromId em IGameInput retorna o IGameInputDevice correspondente a esse índice de usuário. Isso pode então ser usado para acessar funcionalidades adicionais da API GameInput que não são expostas pelo wrapper XInput.

Otimização do código do wrapper

Por padrão, o wrapper XInputOnGameInput é configurado para ser um substituto direto compatível com a API XInput legada. Os jogos que não exigem comportamento 100% compatível podem ajustar o comportamento e o desempenho do wrapper definindo qualquer uma das seguintes macros de pré-processador:
XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION
Por padrão, o wrapper XInput inicializa de forma lenta a API GameInput subjacente automaticamente na primeira vez em que qualquer uma das funções do wrapper é chamada. Isso garante a compatibilidade direta com o código XInput existente, mas tem várias pequenas desvantagens:
  1. O tempo de execução da primeira chamada de função do wrapper XInput será maior do que o normal.
  2. Toda função do wrapper XInput precisa verificar se a inicialização lenta foi realizada sempre que é chamada. Esse é um teste simples de uma variável global, portanto, o preditor de desvios deve amenizar o custo, mas é uma sobrecarga extra.
  3. Embora nunca deva falhar, não há como saber se a inicialização lenta da API GameInput subjacente foi bem-sucedida.
  4. A instância subjacente de IGameInput não é liberada até que as variáveis globais do wrapper XInput sejam limpas (seja devido ao descarregamento do módulo ou ao encerramento do processo).
Os jogos podem assumir o controle manual da inicialização e do desligamento do wrapper definindo a macroXINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION. Isso adiciona duas novas funções,XInputOnGameInputInitialize eXInputOnGameInputUninitialize, que podem ser chamadas para controlar com precisão quando a inicialização e o desligamento ocorrem.
XINPUT_ON_GAMEINPUT_NO_XINPUTENABLE
O código necessário para implementar a funçãoXInputEnable adiciona sobrecarga extra a cada chamada das funçõesXInputGetState,XInputGetStateWithToken,XInputSetState,XInputSetStateEx eXInputGetKeystroke. Se o seu código não chamaXInputEnable, ou se essa chamada puder ser facilmente eliminada do seu código, definir a macroXINPUT_ON_GAMEINPUT_NO_XINPUTENABLE removerá o suporte aXInputEnable e a sobrecarga associada. De qualquer forma, o código subjacente do GameInput executa automaticamente a funcionalidade deXInputEnable nas mudanças de foco, portanto, a maioria dos jogos vai querer definir essa macro, se puder.
XINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE
O código necessário para implementar a funçãoXInputGetKeystroke adiciona algumas funções e variáveis extras à implementação do wrapper. Ele não adiciona sobrecarga a nenhuma das outras funções da API XInput, mas, se o seu código não chamaXInputGetKeystroke, você pode definir a macroXINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE para diminuir ligeiramente o tamanho do código/dados do wrapper XInput.

Documentação de referência da API

Confira também

Visão geral do GameInput Referência da API GameInput Microsoft Game Development Kit
Last modified on October 6, 2026