Survive — Controlando objetos

Survive-8_controle

Quando do comecei este projeto tinha em mente que seu objetivo não seria o de demonstrar como (re)fazer o jogo A, ou B. Para tal bastaria (re)escrevê-lo, publicar o código e aí comentar tediosamente a função de cada bloco de código. A ideia sempre foi a de documentar o processo de desenvolvimento (o durante) mas também repassar a teoria necessária para o caso de alguém se aventurar em algo parecido.

Nesta parte é a vez de aprender como mandar das “instruções” para movimentar os objetos na tela usando os joysticks do MSX.

Joysticks no MSX

Os computadores padrão MSX tem duas portas para joystick que seguem, obviamente, o padrão da arquitetura MSX e NÃO o padrão Atari! Apesar deles compartilharem o mesmo conector DB9 e alguns pinos estarem na mesma posição ao ponto de possibilitar a conexão de um CX-40 sem medo há certas diferenças — a mais óbvia é a implementação de um segundo botão de disparo e a mais interessante a existência de pinos que funcionam para entrada e saída de dados — que fazem com que a recíproca possa não ser lá muito verdadeira.

No MSX as portas de joystick estão implementadas a partir das portas de E/S do próprio PSG (Programmable Sound Generator — Gerador de sons programável), o AY-3-8910. E ele também está encarregado de funcionalidades relacionadas à tecla «かな» dos modelos japoneses¹ e da porta do gravador cassete — nada de circuitos subutilizados aqui²! 🙂

O mais importante é saber que os joysticks são digitais, ou seja, as quatro direções possíveis (cima, baixo, esquerda e direita) são informadas em valores 0 ou 1 com as diagonais sendo combinações destes valores (cima+esquerda, por exemplo). Algo diferente do que acontece em joysticks analógicos que retornam um par de números entre -n e n representando a quantidade de deslocamento horizontal e/ou vertical a partir de um ponto central (que tanto pode ser a posição original do objeto como o centro da tela).

A diferença de funcionamento entre os dois não torna a programação mais simples ou mais complexa; apenas são abordagens diferentes para um mesmo problema. Aliás as mesmas portas que implementam os dois joystick digitais são também usados para a conexão do mouse e de paddles — ou seja, elas também funcionam como portas analógicas quando convém.

(¹) Acredito que os modelos que escrevem em alfabetos árabe, cirílico ou coreano devam usá-la de forma parecida. No caso dos modelos latinos ela é a tecla «Code» para a obtenção de caracteres especiais — funcionando como a tecla «Alt Gr» dos computadores atuais — da mesma forma como a tecla «Graph» para símbolos gráficos.

(²)  Um hábito bastante comum pelo visto já que no Atari ST as mesmas portas do PSG foram utilizadas para mapear funcionalidades das portas paralela, serial e da interface de drive de disquetes.

Rotinas de leitura

A BIOS possui duas rotinas para leitura do estado dos joysticks, GTSTCK (0x00D5) e GTTRIG (0x00D8), que estão acessíveis, respectivamente, pelo MSX-BASIC na forma das funções STICK() e STRIG(). A parte boa é que elas smapeiam as teclas direcionais e a barra de espaço do teclado como se também fosse um joystick — ou seja, para todos os efeitos o MSX tem três portas de joysticks, uma virtual (o teclado, identificado como 0) e duas físicas (joysticks A e B, identificados como 1 e 2). 🙂

A rotina GTSTCK — e por conseguinte a função STICK() — simplifica o processo de leitura do estado do joystick pois retorna um número entre 0 e 8 que indicam a direção que foi escolhida:

Survive-8_direções

O valor 0 indica que nenhuma direção (repouso) e os números entre 1 a 8 representando no sentido horário “cima”, “cima+direita”, “direita”, “direita+baixo” etc… — Ou se preferir os pontos cardeais norte, nordeste, leste, sudeste, sul, sudoeste, oeste e noroeste.

A rotina GTSTRIG verifica o estado de cada botão de disparo, eles são identificados como:

  • 0 →Barra de espaços do teclado;
  • 1 → Botão 1 do joystick A;
  • 2 → Botão 1 do joystick B;
  • 3 → Botão 2 do joystick A e
  • 4 → Botão 2 do joystick B.

Pois é, faltou um segundo botão de disparo no teclado…

O valor retornado é 0  (falso no MSX-BASIC) para repouso ou então -1 (verdadeiro no MSX-BASIC) para botão pressionado³. Aliás, até hoje a Microsoft tem este hábito de usar 0 e -1 é para codificar os tipos boolianos do BASIC.

(³) Uma curiosidade, tanto GTTRIG quanto STRIG() retornam -1! A primeira devolve um inteiro de 8-bit com sinal, ou seja, 0xFF no registrador A do Z80 enquanto que a outra retorna um inteiro de 16-bit com sinal, ou seja, 0xFFFF que é o tamanho dos números inteiros em MSX-BASIC.

Código de exemplo

Esta é a forma mais rápida de verificar o estado do joystick usando apenas o MSX-BASIC e tanto o “Gotcha” como o programa de teste de colisão utilizaram algo parecido:

E ela funciona da seguinte maneira, digamos que o joystick esteja apontando para o canto inferior esquerdo — lembrando que a função STICK() retorna 6 e que o MSX-BASIC trata 0 como falso e -1 como verdadeiro):

X=X-(K=2)-(K=3)-(K=4)+(K=8)+(K=7)+(K=6)
X=X-(False)-(False)-(False)+(False)+(False)+(True)
X=X-0-0-0+0+0+(-1)
X=X-1
Y=Y-(K=6)-(K=5)-(K=4)+(K=8)+(K=1)+(K=2)
Y=Y-(True)-(False)-(False)+(False)+(False)+(False)
Y=Y-(-1)-0-0-0+0+0
Y=Y+1

Isto faz a mesma coisa que uma sequência de IF…THEN…ELSE ou mesmo os quase exotéricos ON STICK GOSUB … e ON STRIG GOSUB … — lembra da orientação a evento?

E o que este programa faz e movimentar um quadradinho branco pela SCREEN 3 nas oito direções possíveis e rabiscar nela quando a barra de espaços é pressionada. Na linha 110 a variável K recebe o valor da leitura da porta do joystick 0 (que é o teclado) enquanto que na linha 115 verifico se a barra de espaço é pressionada para então usar PSET. Para fazer o programa trabalhar com os joysticks basta substituir os valores das linhas 110 e 115.

Controlando o “Herói”

Cheguei a produzir uma versão assembly de uma rotina bem parecida ao do exemplo anterior e com as diagonais sendo obtidas da mameira mais pouco usual possível. Ela funciona bem, movendo o “herói” corretamente pela tela e o resultado até pode ser visualizado no primeiro vídeo que publiquei sobre o jogo.

Porém o resultado final, com a abordagem padrão de incremento contínuo não me agradou. Alguma coisa estava faltando. E esta coisa se chamava aceleração, não era apenas fazê-lo se movimentar mais rápido pela tela era também produzir a sensação de aumento gradual de velocidade criando uma vaga sensação de inércia.

Sendo assim:

O grande retângulo azul é a área onde você pode movimentar o cursor (o pequeno sprite em forma de “+”) enquanto que  o conjunto de caixas coloridas no canto inferior representam a velocidade de aceleração (Amarelo→8, Laranja→4, Vermelho→2 e Vermelho escuro→1) que funcionam de forma independente nos dois eixos.

No fundo este programa tenta simular um pouco o funcionamento do controle analógico existente nos joystick modernos. Neste protótipo em MSX-BASIC fiz a aceleração geométrica e com poucos valores para que a performance fosse aceitável, em assembly poderei deixá-la mais suave.

E você pode testar o programa no seu navegador a partir do MSXPen! 🙂

Finalizando esta parte

Com a rotina de posicionamento dos sprites, detecção de colisão e agora controle do “herói” definida é chegada a hora de dar alguma atenção para as “caixas” pois sem adversários o jogo não terá a menor graça.

Até lá!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s