Detectar pressionamentos extremamente rápidos do botão do joystick?

7

Geralmente, é possível ao jogador pressionar e soltar um botão em um único quadro, para que o mecanismo do jogo não tenha tempo para detectá-lo?

Como os programadores geralmente lidam com essa situação? É mesmo necessário lidar com isso?

Durante os testes, pude pressionar e soltar um botão em cerca de 14 ou 15 milissegundos (mais de 1 clique / quadro). No entanto, eu não era capaz de fazer isso enquanto mantinha o joystick normalmente, e o ciclo de liberação da imprensa teria que começar quase na hora exata em que o quadro inicia.

Especificamente, estou perguntando sobre os recursos de entrada do joystick do GLFW.

Atualmente, estou usando o GLFW para criar um jogo e notei que o teclado e o mouse têm funções de retorno de chamada, enquanto os joysticks não. Além disso, não parece possível ativar "teclas de aderência" para um joystick. (Apenas recentemente comecei a usar o GLFW, por favor, corrija-me se estiver errado, pois isso poderia resolver o problema.)

Embora eu esteja perguntando sobre o GLFW, respostas relacionadas a qualquer biblioteca / mecanismo / idioma são bem-vindas.

Maçãs
fonte

Respostas:

7

No hardware da Nintendo e da Sony, às vezes pesquisamos a entrada em uma taxa mais alta do que desenhávamos quadros; use um encadeamento acionado por timer para observar a E / S do controlador em 120hz, por exemplo, mesmo quando estávamos renderizando a 30hz. Por "um segmento controlado por timer", quero dizer que houve um timer de hardware que provocou uma interrupção que fez com que uma função específica fosse chamada em tempo real. Nesses sistemas, o controlador aparecia como E / S mapeada na memória; portanto, basta carregar uma palavra em um local específico da memória e que teria a posição do eixo X do joystick naquele momento. Você o salvaria em algum lugar da memória principal e, quando o loop do jogo principal fosse executado, ele teria um histórico de 4 ou 8 ou, no entanto, muitas amostras de dados de entrada em um intervalo de tempo consistente.

Isso não foi para detectar o pressionamento de botões, mas para obter um tempo intraframe nítido para jogos de luta onde importava (porque você tinha permissão para enfileirar entradas "antes" de um quadro de disparo crítico na animação, e a taxa de animação pode não ser tão estável como gostamos, por isso precisávamos distinguir se você pressionaria o botão antes do limite do quadro ou nele).

Não sei se é possível com o GFWL. O sistema de entrada do DirectX está bastante ligado ao ciclo de renderização, e há muitos sistemas operacionais entre você e os switches no gamepad USB.

Crashworks
fonte
Esta é a melhor solução que eu já vi até agora. Até onde eu sei, a entrada do joystick, pelo menos no Windows, não está vinculada ao sistema de renderização de forma alguma. Por padrão, estou pesquisando a entrada uma vez por quadro (quando troco buffers), mas certamente é possível mover isso para um encadeamento.
Maçãs
2

Você tem certeza sobre isso? Eu posso ver uma transição de estado indo tão rápido aqui e ali, mas você percebe que levaria 70 pressionamentos por segundo para ver um botão pressionado a cada 14ms? Sinto muito, mas isso não é fisicamente possível, embora talvez você possa induzi-lo aqui e ali com um apertar de botão louco de todos os nós, e talvez haja até algum salto no próprio hardware. Você já assistiu a um vídeo de jogadores profissionais de StarCraft, onde eles usam todos os dedos de uma mão e um mouse e clicam tão rápido que é um borrão? Esses caras são deuses se puderem executar 300 ações por minuto, ou seja, 5 por segundo usando as duas mãos ...

Dito isto, em geral, com muitos jogos, você apenas vê as entradas pesquisadas em todos os quadros. A possibilidade de uma imprensa completa de imprensa acontecer dentro de um quadro e se perder é bastante remota nas taxas de quadros interativas, e eu nunca soube que um desenvolvedor de jogos se preocupasse com isso.

Em alguns sistemas, você pode obter entrada em buffer. O sistema monitora os dispositivos de entrada de forma assíncrona e preenche uma fila com todas as alterações de estado ocorridas desde a última consulta, e geralmente você deixa o buffer preencher entre os quadros e processá-lo em cada quadro, para que a resolução seja maior do que a pesquisa o estado de cada quadro.

Alguns sistemas são controlados por eventos, portanto, você pode registrar um retorno de chamada que é acionado toda vez que o estado de entrada é alterado, embora a resolução dependa do restante da pilha de software e possa ou não ser significativamente melhor do que uma verificação por quadro. Por exemplo, se a API estiver apenas pesquisando o hardware em cada quadro, comparando-o com o último quadro e acionando os retornos de chamada aplicáveis, você não estará melhor.

Com sistemas embarcados e alguns sistemas de jogos antigos programados para o metal, você teria interrupções nos botões. Uma interrupção é um pequeno pedaço de código que você registra no sistema que é executado sempre que algo acontece. No caso de uma interrupção de botão, o hardware seria fisicamente projetado para que, quando a tensão no fio conectado ao botão for de baixa a alta ou alta a baixa, ele execute esse código. Este seria o sistema mais direto e responsivo, mas a maioria dos jogos hoje em dia tem uma tonelada de hardware e software entre você e os botões.

Suboptimus
fonte
11
Concordo com o que você está dizendo, mas nessa situação o número médio de impressoras por segundo não importa tanto quanto a velocidade de um único toque. Por exemplo, em meus testes, meu tempo médio de toque (medido pela quantidade de tempo que o botão estava no estado "inativo") era de cerca de 50 ms. Isso não significa, no entanto, que eu estava pressionando o botão 20 vezes por segundo, pois o tempo médio em que o botão estava no estado "liberado" era de cerca de 150 ms. Isso mostra que é muito mais fácil pressionar e soltar um botão em um quadro, em vez de manter uma média de 60 toques por segundo.
Maçãs
OK eu vejo. Isso faz sentido, semelhante à situação que o Crashworks discutiu com os jogos de luta, onde o tempo dos eventos em alta resolução é importante. Definitivamente, entendo como isso pode ser um problema para você, provavelmente quer fazer amostragem de entrada assíncrona, como ele sugeriu.
Suboptimus 8/06/12
0

Supondo que um jogo seja executado a 60 qps, cada quadro é de cerca de 17 milissegundos. É altamente improvável que alguém possa pressionar e liberar nesse período de tempo. Se você pode clicar rápido o suficiente para obter cerca de 60 cliques por segundo , pressiona e libera rápido o suficiente para vencer os quadros.

MichaelHouse
fonte
Isso é verdade, mas ainda vejo alguns casos extremos onde isso pode acontecer. Talvez seja melhor simplesmente não se preocupar com isso, pois um usuário pressiona um botão que rapidamente o está fazendo acidentalmente ou está usando uma ferramenta de trapaça. No entanto, ainda estou procurando uma solução para o problema.
Maçãs
Nenhum jogo profissional faz algo especial para lidar com isso, e você não ouve pessoas reclamando. Os seres humanos não podem pressionar botões tão rápido.
Sean Middleditch
2
@DBRalir Se você está pesquisando informações, não há como detectar isso, pois, no que diz respeito ao seu programa, isso não aconteceu. Há coisas mais importantes com que se preocupar do que esse caso excepcionalmente raro.
MichaelHouse
@ Byte56 Sim, eu estou ignorando. Posso obter regularmente tempos de toque abaixo de 15 ms, mas isso geralmente se sobrepõe à rotina de pesquisa. Para que o programa perca completamente a torneira, ele teria que durar cerca de 7 ms, o que não parece possível. Obrigado pela sua resposta.
Maçãs
Bom ouvir. Parece que o seu jogo será rápido! Isso vai ser divertido. Boa sorte com isso :)
MichaelHouse