De hecho, me encontré con este dilema con la entrada del controlador Xbox. Aunque no es exactamente lo mismo, es muy similar. Puede cambiar el código en mi ejemplo para satisfacer sus necesidades.
Editar: su situación usaría esto ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
Y puede aprender cómo crear una clase de entrada sin formato a través de ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Pero ... ahora en el algoritmo súper impresionante ... no realmente, pero bueno ... es bastante genial :)
* Entonces ... ¡podemos almacenar los estados de cada botón y cuáles son presionados, liberados y retenidos! También podemos verificar el Tiempo de retención, pero eso requiere una sola declaración if y puede verificar cualquier número de botones, pero hay algunas reglas que se encuentran a continuación para obtener esta información.
Obviamente, si queremos comprobar si se presiona, suelta, etc., debe hacer "If (This) {}", pero esto muestra cómo podemos obtener el estado de la prensa y luego desactivarlo en el siguiente cuadro para que su " ismousepressed "en realidad será falso la próxima vez que verifique.
Código completo aquí:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Cómo funciona..
Por lo tanto, no estoy seguro de los valores que recibe cuando describe si se presiona un botón o no, pero básicamente cuando cargo en XInput obtengo un valor de 16 bits entre 0 y 65535, esto tiene 15 bits de estados posibles para "Presionado".
El problema era que cada vez que revisaba esto simplemente me daría el estado actual de la información. Necesitaba una forma de convertir el estado actual en valores presionados, liberados y retenidos.
Entonces, lo que hice es lo siguiente.
Primero creamos una variable "ACTUAL". Cada vez que verificamos estos datos, establecemos "ACTUAL" en una variable "ANTERIOR" y luego almacenamos los nuevos datos en "Actual" como se ve aquí ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
¡Con esta información, aquí es donde se pone emocionante!
¡Ahora podemos averiguar si un botón se está DETENIENDO!
BUTTONS_HOLD = LAST & CURRENT;
Lo que esto hace es básicamente que compara los dos valores y cualquier pulsación de botón que se muestra en ambos permanecerá 1 y todo lo demás se establecerá en 0.
Es decir (1 | 2 | 4) y (2 | 4 | 8) rendirán (2 | 4).
Ahora que tenemos qué botones están "HELD" hacia abajo. Podemos obtener el resto.
Presionado es simple ... tomamos nuestro estado "ACTUAL" y eliminamos cualquier botón presionado.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Lanzado es el mismo, solo que lo comparamos con nuestro ÚLTIMO estado.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Entonces mirando la situación presionada. Si digamos que actualmente teníamos 2 | 4 | 8 presionado. Encontramos que 2 | 4 donde se celebró. Cuando eliminamos los bits retenidos, solo nos queda 8. Este es el bit recién presionado para este ciclo.
Lo mismo se puede aplicar para Liberado. En este escenario, "ÚLTIMO" se estableció en 1 | 2 | 4. Entonces, cuando quitamos el 2 | 4 bits Nos quedamos con 1. Entonces, el botón 1 se soltó desde el último fotograma.
Este escenario anterior es probablemente la situación más ideal que puede ofrecer para la comparación de bits y proporciona 3 niveles de datos sin sentencias if o para bucles, solo 3 cálculos rápidos de bits.
También quería documentar los datos retenidos, así que aunque mi situación no es perfecta ... lo que hace es básicamente establecer los holdbits que queremos verificar.
Por lo tanto, cada vez que configuramos nuestros datos de Prensa / Liberación / Retención, verificamos si los datos de retención aún son iguales a la verificación de bit de retención actual. Si no es así, restablecemos la hora actual. En mi caso, lo configuro en índices de cuadros para saber cuántos cuadros se han mantenido presionados.
La desventaja de este enfoque es que no puedo obtener tiempos de espera individuales, pero puede verificar varios bits a la vez. Es decir, si establezco el bit de retención en 1 | 16 si no se mantienen 1 o 16, esto fallará. Por lo tanto, se requiere que TODOS esos botones se mantengan presionados para continuar marcando.
Luego, si observa el código, verá todas las llamadas a funciones ordenadas.
Por lo tanto, su ejemplo se reduciría a simplemente verificar si se presionó un botón y solo se puede presionar un botón con este algoritmo. En la próxima comprobación para presionar, no existirá, ya que no puede presionar más de una vez que tendría que soltar antes de poder presionar nuevamente.