Skip to main content
La portabilidad de XInput a GameInput es la menos complicada de todas las API heredadas. Esto se debe a que GameInput estuvo muy influenciado por el modelo de programación sencillo (y fácil de usar) de XInput y, por lo tanto, muchas API de XInput se corresponden 1:1 con funciones equivalentes en GameInput.

Diferencias clave

Las diferencias clave entre XInput y GameInput se describen en las secciones siguientes.

C frente a C++

La API de XInput es una colección de funciones planas de C. GameInput, en cambio, es C++ y usa interfaces (igual que las API de gráficos y audio). En la práctica, esto no complica el código que usa la API de GameInput, no afecta al rendimiento y tiene algunas ventajas que se hacen evidentes una vez que se familiariza con el funcionamiento de GameInput. Es importante comprender que, aunque estas interfaces pueden parecer COM, no lo son. Solo se requiere una comprensión básica del recuento de referencias para usar estas interfaces. Para obtener más información, consulte la sección Interfaces del tema Aspectos básicos de GameInput.

Obtención de entrada

En XInput, la mayoría de los juegos recorren en bucle los índices de usuario hasta encontrar uno con un dispositivo conectado, y luego se lee el estado de ese dispositivo. Los juegos suelen recordar el índice de usuario para no tener que repetir el bucle la próxima vez. Por ejemplo, el código siguiente es típico de un juego que pide al usuario que “presione A” en su mando:
En GameInput, primero se obtiene la entrada sin especificar un dispositivo y, si lo desea, puede consultar de qué dispositivo procede la entrada. El código es similar, pero eliminar la necesidad de una enumeración explícita de dispositivos puede dar lugar a algoritmos más sencillos.
El código no es tan sencillo como el de XInput, pero es muy similar. A medida que se familiarice con la API de GameInput, verá cómo este modelo proporciona opciones eficaces para controlar la entrada que no existen en XInput. También cabe destacar que XInput devuelve valores analógicos de los gatillos como tipo BYTE, y valores analógicos de los joysticks como tipo SHORT. Con la API de GameInput, estos valores analógicos se devuelven como valores float de 0 a 1 (gatillos) o de -1 a 1 (joysticks).

Retroalimentación de vibración

En XInput, los juegos simplemente llaman aXInputSetState para enviar comandos de vibración a un dispositivo. En GameInput, los juegos deben adquirir la instancia de IGameInputDevice del dispositivo y, a continuación, llamar a su método SetRumbleState. El uso es similar entre estos dos métodos. Este es un ejemplo de cuándo llamará a funciones en la interfaz del dispositivo, en lugar de que esta sea únicamente un identificador de dispositivo.

Foco de la aplicación

En la consola, GameInput proporciona entrada a una aplicación solo cuando esta tiene el foco. De lo contrario, el estado devuelto contiene valores neutros o de “reposo”, como si el usuario no estuviera tocando el dispositivo en absoluto. Esto elimina la necesidad de código de entrada adicional que gestione el cambio de foco (por ejemplo, llamar aXInputEnable). En PC, la entrada llega a todos los procesos de forma predeterminada. En el futuro, este comportamiento podrá cambiarse mediante el método SetFocusPolicy.

El contenedor XInputOnGameInput

Microsoft Game Development Kit (GDK) incluye un archivo de encabezado llamadoXInputOnGameInput.h que contiene una implementación de la API de XInput sobre GameInput. Se recomienda portar directamente a GameInput, especialmente si quiere usar teclado y mouse u otros dispositivos de entrada. Sin embargo, el contenedor XInputOnGameInput se puede usar para ayudar a arrancar un esfuerzo de portabilidad inicial sin requerir ningún cambio en el código de XInput existente. Para usar el contenedor XInputOnGameInput, simplemente reemplace este código:
por este código:
y, a continuación, vuelva a compilar su código. La implementación del código del contenedor de XInput está íntegramente en el archivo de encabezado, por lo que también puede examinarse como ejemplo de uso de la API de GameInput o modificarse según sea necesario.

Diferencias entre XInput y XInputOnGameInput

En general, el contenedor XInputOnGameInput es un reemplazo directo de la API de XInput heredada. Sin embargo, hay algunas diferencias menores:
  • Para simplificar, en el contenedor solo se ha codificado la compatibilidad con dispositivos de tipo mando. Si necesita compatibilidad con otros dispositivos, como volantes de carreras o joysticks arcade, use GameInput directamente o agregue compatibilidad con esos dispositivos en el código de XInputOnGameInput.
  • El contenedor devolverá entrada del mando solo cuando el juego tenga el foco. Cuando el juego no tiene el foco, cualquier estado de mando devuelto se establece en valores neutros o de “reposo”, como si el usuario no estuviera tocando el mando. Esto se hace independientemente de las llamadas aXInputEnable (o de la ausencia de ellas).
  • El valor deXUSER_MAX_COUNT se ha aumentado de 4 a 8. En general, esto debería ser transparente para la mayoría del código de XInput heredado. Sin embargo, asegúrese de revisar cuidadosamente cualquier uso de la funciónXInputGetKeystroke en su código para garantizar que nada esté codificado de forma rígida asumiendo que se devuelve un valor máximo de 4 en el miembroUserIndex de la estructuraXINPUT_KEYSTROKE. De lo contrario, podría producirse una saturación del búfer.
  • Se han agregado algunas funciones nuevas (vea a continuación) que solo deberían interesarle si tiene previsto seguir usando el contenedor de XInput en código de producción.

Uso de XInputOnGameInput en código de producción

El contenedor XInputOnGameInput está escrito para ofrecer un alto rendimiento y no usar bloqueos, heredando todas las optimizaciones de rendimiento de la API de GameInput, y por lo tanto es adecuado para usarse en código de producción. También hereda la compatibilidad más amplia con dispositivos de GameInput (como los mandos HID populares) y agrega las siguientes funciones nuevas a la API:
  • XInputSetStateEx es similar aXInputSetState, pero agrega compatibilidad con los motores de los gatillos.
  • XInputGetStateWithToken es similar aXInputGetState, pero permite al autor de la llamada proporcionar un token de canalización de fotogramas de D3DX para asociar una lectura de entrada específica con un fotograma de gráficos y analizarla posteriormente en PIX.
    [!NOTE] En la versión May Preview,XInputGetStateWithToken se comporta actualmente de manera idéntica aXInputGetState, porque el código subyacente de GameInput no está completamente implementado.
  • XInputGetDeviceId devuelve elAPP_LOCAL_DEVICE_ID del dispositivo en un índice de usuario determinado. Al pasar este identificador al método FindDeviceFromId de IGameInput, se devuelve el IGameInputDevice correspondiente a ese índice de usuario. Este puede usarse después para acceder a funcionalidad adicional de la API de GameInput que no está expuesta a través del contenedor de XInput.

Optimización del código del contenedor

De forma predeterminada, el contenedor XInputOnGameInput está configurado para ser un reemplazo directo compatible con la API de XInput heredada. Los juegos que no requieran un comportamiento 100 % compatible pueden ajustar el comportamiento y el rendimiento del contenedor definiendo cualquiera de las siguientes macros de preprocesador:
XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION
De forma predeterminada, el contenedor de XInput inicializa de forma diferida la API de GameInput subyacente automáticamente la primera vez que se llama a cualquiera de las funciones del contenedor. Esto garantiza la compatibilidad directa con el código de XInput existente, pero tiene varios inconvenientes menores:
  1. El tiempo de ejecución de la primera llamada a una función del contenedor de XInput será más largo de lo habitual.
  2. Cada función del contenedor de XInput debe realizar una comprobación para ver si se ha efectuado la inicialización diferida cada vez que se la llama. Se trata de una simple comprobación de una variable global, por lo que el predictor de saltos debería mitigar el costo, pero es una sobrecarga adicional.
  3. Aunque nunca debería fallar, no hay forma de saber si la inicialización diferida de la API de GameInput subyacente se realizó correctamente.
  4. La instancia subyacente de IGameInput no se libera hasta que se limpian las variables globales del contenedor de XInput (ya sea por la descarga del módulo o por la finalización del proceso).
Los juegos pueden tomar el control manual de la inicialización y el apagado del contenedor definiendo la macroXINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION. Esto agrega dos nuevas funciones,XInputOnGameInputInitialize yXInputOnGameInputUninitialize, a las que se puede llamar para controlar con precisión cuándo se producen la inicialización y el apagado.
XINPUT_ON_GAMEINPUT_NO_XINPUTENABLE
El código necesario para implementar la funciónXInputEnable agrega una sobrecarga adicional a cada llamada de las funcionesXInputGetState,XInputGetStateWithToken,XInputSetState,XInputSetStateEx yXInputGetKeystroke. Si su código no llama aXInputEnable, o si puede eliminarse fácilmente de su código, definir la macroXINPUT_ON_GAMEINPUT_NO_XINPUTENABLE eliminará la compatibilidad conXInputEnable y la sobrecarga asociada que conlleva. De todos modos, el código subyacente de GameInput realiza automáticamente la funcionalidad deXInputEnable en los cambios de foco, por lo que la mayoría de los juegos querrán definir esta macro si pueden.
XINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE
El código necesario para implementar la funciónXInputGetKeystroke agrega algunas funciones y variables adicionales a la implementación del contenedor. No agrega sobrecarga a ninguna de las otras funciones de la API de XInput, pero si su código no llama aXInputGetKeystroke, puede definir la macroXINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE para reducir ligeramente el tamaño de código/datos del contenedor de XInput.

Documentación de referencia de la API

Consulte también

Información general de GameInput Referencia de la API de GameInput Microsoft Game Development Kit
Última modificación el 28 de agosto de 2026