ALAN JAHNEL / Engenharia de software

Artigos

GBA em Assembly — 9. Do exemplo ao Tower Defense

Aprenda a investigar falhas e conecte os exemplos de hardware ao artigo principal de Tower Defense, com um roteiro de leitura e próximos passos.

Se você seguiu os exemplos, já escreveu cores na memória de vídeo, acompanhou o ciclo da tela, leu botões e organizou posição e estado na RAM. Agora temos a base para chegar ao artigo principal de Tower Defense para Game Boy Advance.

Antes disso, vamos aprender a separar um erro de construção, um erro de acesso ao hardware e um erro de regra. Essa separação torna a investigação muito menor do que tentar entender “por que o jogo inteiro não funciona”. O índice da série permite voltar a qualquer experiência.

Roteiro deste capítulo

  1. Abra seu último minijogo funcionando e confira movimento, vitória e reinício. Se falhar, volte àquela conferência antes de acrescentar regras de Tower Defense.
  2. Comece pelas verificações de arquivos e construção abaixo. Depois use os comandos de inspeção de símbolos para relacionar nomes como hero_x a endereços. Não é necessário configurar um depurador para concluir o curso.
  3. Explique a sequência com suas palavras: ler botões, atualizar a RAM, escolher cor e posição, gravar pixels e repetir acompanhando o tempo do vídeo.
  4. Use a tabela de comparação abaixo para localizar cada ideia conhecida no artigo principal. Comece pela primeira etapa didática, que desenha o cenário, e confira cada etapa antes de habilitar a seguinte.

Ponto de conferência: você consegue reconstruir o minijogo, descrever por que ele vence e se recuperar de uma falha de construção corrigindo o primeiro erro informado. Agora pode abordar o Tower Defense um sistema por vez. A tabela final de recursos de hardware lista assuntos futuros, não outros pré-requisitos.

Começar pelo último resultado conhecido

Os seis exemplos do pacote são independentes. Se o minijogo falhar, abra a ROM do movimento. Se o movimento falhar, confira o teste dos botões. Se nada aparecer, volte à primeira tela estática.

ExemploO que ele isolaO que observar
primeira-rom.sEntrada no programa, vídeo e um endereço de pixelFundo vermelho e ponto branco
retangulo.sCoordenadas e laços de escritaÁrea verde de 32 por 32
pisca.sSincronização e variável em RAMAlternância a cada 32 atualizações
botoes.sEntrada e transição de botãoCor acompanha A; contador cresce por aperto
movimento.sPosição, limites e restauraçãoQuadrado se move sem deixar rastro
minijogo.sRegras e estadosAlvo produz vitória; Start reinicia

Esse percurso também funciona ao contrário: comece pelo menor programa que passa e acrescente uma alteração por vez. Assim você sabe em qual passo o comportamento mudou.

Antes de depurar, confira qual arquivo está executando

Os quatro comandos de construção produzem arquivos diferentes. Se o assembler falhar e você continuar abrindo um .gba antigo, o emulador pode estar executando a versão de antes da mudança.

Pare no primeiro comando que der erro. Leia a mensagem e a linha indicada. Depois de uma construção completa, confira o caminho usado para abrir a ROM. rom.py mostra o SHA-256 do conteúdo final, que ajuda a identificar se duas cópias são iguais.

Um erro de sintaxe, um símbolo indefinido ou uma instrução incompatível com ARM7TDMI acontece nas ferramentas do computador. Não adianta tentar resolvê-lo mudando a configuração do emulador.

Usar o ELF para enxergar os nomes

Consulte as ferramentas de construção e inspeção e a pseudoinstrução LDR com sinal de igual para interpretar os resultados.

O .gba é a sequência de bytes usada como cartucho. O .elf também conserva informações sobre seções e símbolos. Com as ferramentas instaladas no capítulo 3, podemos inspecioná-lo:

Shell
arm-none-eabi-nm -n minijogo.elf
arm-none-eabi-objdump -h minijogo.elf
arm-none-eabi-objdump -d minijogo.elf

O primeiro comando lista nomes e endereços. Procure hero_x, hero_y e game_state: eles devem estar na região de RAM que começa em 0x02000000. Procure boot e main_loop: devem estar na região da ROM que começa em 0x08000000.

O segundo mostra as seções. O terceiro apresenta a desmontagem: instruções reconstruídas a partir dos bytes. A pseudoinstrução ldr r0, =constante pode aparecer de outra forma, porque o assembler escolhe como realizá-la. Não conclua que uma diferença textual indica um erro de montagem.

Em uma interface de depuração que ofereça inspeção de memória, os endereços de nm permitem acompanhar as variáveis. Os recursos e comandos de interface variam entre distribuições do mGBA; o arquivo ELF e os conceitos continuam úteis mesmo sem depender de um nome específico de menu.

Inspecionar a fronteira que deveria ter mudado

A referência ajuda a separar endereçamento, flags e condições ao investigar uma falha.

Se A não muda a cor, investigue a cadeia na ordem:

  1. A janela recebe o teclado e a tecla está associada ao botão A do GBA?
  2. O bit correspondente muda na leitura de KEYINPUT?
  3. A versão normalizada em keys tem o bit 0 ligado?
  4. A escolha da cor usa keys e a máscara 1?
  5. fill_rect recebe a cor correta e escreve na área esperada?

Se a posição muda na RAM, mas a imagem fica parada, a leitura dos controles já funcionou. O próximo ponto de investigação é o desenho. Se o quadrado anda, mas não vence, confira as coordenadas usadas na comparação do alvo.

O mesmo raciocínio serve para uma falha visual. Um rastro costuma indicar que a imagem antiga não foi restaurada. Um deslocamento que vira uma faixa sugere erro no salto entre linhas. Um acesso com largura ou alinhamento inadequados pertence à comunicação com a memória, antes de qualquer regra de jogo.

Saber o que foi verificado

Os seis exemplos foram montados com GNU Binutils e executados no núcleo mGBA 0.10.5 via uma interface de testes. Foram verificados o pixel central, as bordas do retângulo, a alternância de cor, novas pressões e botões segurados, os quatro limites de movimento, a vitória e o reinício. As ações de jogo foram realizadas por entradas de controle, sem escrever diretamente no estado para forçar o resultado.

Essa execução verifica os comportamentos descritos nos exemplos. Não equivale a teste em console físico e não demonstra que uma alteração futura respeitará todos os tempos do hardware. Os comandos e o relatório de validação ficam no repositório do site, em docs/gba-assembly-series.md e docs/evidence/gba-assembly-series.json.

Agora, chegar ao Tower Defense

O artigo principal usa os mesmos fundamentos para construir uma partida com uma estrada, um herói, um ponto de construção e uma onda de quatro inimigos. Leia-o nesta ordem de perguntas:

O que você já fezO que procurar no Tower Defense
Desenhar um retânguloComo células do tabuleiro viram áreas em pixels
Guardar X e Y em RAMOnde ficam posição, vida, moedas e recargas
Esperar VBlankComo entrada, regras e desenho formam o laço principal
Distinguir keys e pressedPor que andar repete e construir acontece uma vez
Limitar a posição na telaComo impedir entrada na base e na torre
Comparar duas áreasComo decidir se um inimigo está ao alcance
Mudar game_stateComo representar jogando, vitória e derrota
Reiniciar o minijogoQuais valores precisam voltar ao estado inicial

O inimigo passa a ser outra posição que muda com o tempo. A torre testa condições e altera a vida desse inimigo. As moedas são outra palavra na RAM. O aumento de complexidade vem da quantidade de relações entre regras; as operações básicas continuam reconhecíveis.

Não é preciso entender a campanha completa de dez mapas para acompanhar a primeira partida pequena. Comece pelo recorte didático do artigo e confira um comportamento por vez.

As próximas peças do hardware

Os exemplos usam Mode 3 para tornar visível a relação entre um endereço e uma cor. Depois de dominar isso, existem outros caminhos:

RecursoO problema que ajuda a resolverConceito novo
Tiles e fundosReutilizar desenhos pequenos no cenárioImagem, mapa de índices e paleta
Sprites e OAMPosicionar objetos pelo circuito de vídeoAtributos de posição, imagem e prioridade
DMATransferir blocos sem um laço de cópia por instruçãoOrigem, destino, quantidade e momento de transferência
TimersContar tempo com unidades do hardwareFrequência, divisão e transbordamento
InterrupçõesResponder a eventos sem consultar o tempo todoHabilitação, tratamento e retorno
ÁudioProduzir tons e reproduzir amostrasCanais, configuração e alimentação de dados

Cada um merece um novo exemplo isolado. DMA não é uma função que entende “carregue meu mapa”, e OAM não substitui as regras de colisão do jogo. São interfaces de hardware com formatos e restrições que o programa precisa respeitar.

O Tonc organiza referências para esses assuntos. O passo imediato, porém, é aplicar o que já aprendemos: construir a primeira partida de Tower Defense em Assembly.

Anterior: primeiro minijogo. Continuação: o artigo principal de Tower Defense.

Voltar ao início