1 pontos por GN⁺ 2024-02-26 | 1 comentários | Compartilhar no WhatsApp
  • Magicore Anomala implementa CG em tela cheia e transições no estilo animação com os recursos gráficos e sonoros do Amiga, lançado em 1985, mas dentro do motor do jogo é preciso resolver ao mesmo tempo o layout da RAM, a divisão da tela e as limitações dos sprites
  • Em uma configuração comum do Amiga 500, há apenas 512 KB de Chip RAM disponíveis para gráficos e som, então os 48 KB descompactados de uma CG 320x240 com 32 cores pesam bastante
  • A CG é reduzida para cerca de 8 KB com compressão ZX0, fica na RAM de expansão e é descompactada para a Chip RAM pouco antes de ser exibida, reutilizando os 48.000 bytes da memória de tela já existente
  • O efeito de transição é criado com o copper, que altera registradores de hardware em scanlines específicas e desliga e religa o DMA de bitplanes, enquanto a CPU ajusta os valores da copperlist a cada frame conforme a largura do split
  • As motion lines do fundo precisam contornar dependências de cor, reutilização e bitplane dos sprites do Amiga, e os mecanismos centrais são attached sprites, bits de controle falsos, manutenção de 1 bitplane e ajuste de BPLMOD1

O problema de RAM para colocar uma CG em tela cheia no Amiga 500

  • A plataforma-alvo de Magicore Anomala é um Amiga 500 típico, com 512 KB de Chip RAM e 512 KB de RAM de expansão
    • A memória que o chipset do Amiga pode usar para saída gráfica e sonora é apenas a Chip RAM
    • A RAM de expansão só pode ser acessada pela CPU, então é difícil usá-la diretamente para gráficos e som
  • A graphic de personagem em tela cheia (CG) é uma imagem bitmap 320x240 com 32 cores e ocupa 48 KB sem compressão
    • Considerando assets compartilhados, dados de fase e alocação de memória de tela, 48 KB é um overhead grande
  • O suporte adicionado recentemente para compressão de assets usa o formato de compressão ZX0
    • A CG comprimida cai para cerca de 8 KB
    • Ao carregar os assets da fase, a CG comprimida é colocada na RAM de expansão
    • Pouco antes da exibição, ela é descompactada para a Chip RAM

Como evitar reservar mais 48 KB de Chip RAM

  • Em vez de procurar 48 KB livres de Chip RAM só para a CG, parte da memória de tela existente é reutilizada
    • Imagem de fundo da sala
    • Camada de tela para renderizar objetos perigosos
    • Área da tela da caixa de texto
  • Essas três regiões de memória são contíguas na RAM, e o tamanho combinado é de 48.000 bytes, exatamente o tamanho da CG
  • A imagem de fundo da sala pode ser restaurada depois que a CG termina de ser exibida, então não há problema em sobrescrevê-la
  • A descompressão da CG leva cerca de 500 ms, mas isso é inserido no fluxo da cutscene para não parecer um carregamento
  • O vídeo de proof-of-concept da gameplay de Magicore Anomala pode ser visto no YouTube

Efeito de divisão de tela e uso do copper

  • No começo foi considerada uma transição vertical em wipe, mas para ficar bonita ela precisaria de um gradiente com ajuste da paleta de cores em cada scanline
    • Foi considerado difícil definir todas as 32 cores em um único blank horizontal usando apenas o copper
    • Como não havia interesse em lidar com “racing the beam”, foi escolhido o efeito de divisão de tela
  • O efeito de divisão de tela parece mais impressionante para o público em geral, e o copper do Amiga funciona praticamente como se tivesse sido feito para esse tipo de efeito
    • Um caso semelhante embutido no Amiga Workbench pode ser visto neste vídeo
  • A implementação usa duas funções do Amiga em conjunto
    • O copper executa sua própria lista de instruções em paralelo com a CPU e pode alterar registradores de hardware em linhas específicas da tela
    • Os ponteiros de tela podem ser definidos em registradores de hardware para mudar a memória de tela para qualquer posição dentro da Chip RAM

Parando o DMA de bitplanes e retomando o desenho depois

  • Por exemplo, se a memória principal da tela começa em 0x20000, normalmente o copper define esse endereço nos registradores de DMA de bitplanes
    • Quando os bitplanes são ativados, o DMA lê essa região de memória em sequência e a desenha na tela
  • Se cada linha horizontal ocupa 0x100 bytes, definir o ponteiro de tela como 0x20800 faz a tela parecer rolada 8 linhas para cima
    • Isso acontece porque o ponto inicial da tela foi deslocado 8 linhas para baixo na memória
  • A metade superior do split é rolada para cima dessa forma
  • No ponto do split, o copper desliga o DMA de bitplanes e muda a cor de fundo para vermelho
    • Os registradores de hardware ligados aos bitplanes praticamente congelam nesse momento
    • Ao chegar à parte inferior do split, a cor de fundo é restaurada e o DMA de bitplanes é ligado novamente
    • A tela volta a ser desenhada a partir da posição em que havia parado, mas a posição real de exibição já está mais abaixo
  • A cada frame, a CPU ajusta vs_TCopTop e vs_TCopBottom de acordo com a largura atual do split
    • O ajuste do ponteiro de tela para o split superior também é feito, mas não está incluído no exemplo de código

Contornos com sprites para as motion lines do “woosh”

  • As motion lines do fundo animado são desenhadas com sprites
    • Como os sprites são desenhados independentemente da memória de tela e podem se mover, eles são adequados para esse uso
    • Ainda assim, os sprites do Amiga têm muitas limitações e são complicados de lidar
  • Restrições de cor

    • Os sprites compartilham bitplanes e paleta de cores, então é preciso usar o mínimo possível de cores
    • As motion lines usam apenas 3 cores, deixando 28 cores para a CG e 1 cor para o fundo
    • No Amiga, o intervalo de cores da paleta usado varia conforme cada par de sprites
      • Os dois primeiros sprites usam as cores 16-19
      • Os dois sprites seguintes usam as cores 20-23
    • Ao fazer attach de dois sprites, eles passam a funcionar como um único sprite com paleta de 16 cores e podem usar as cores 16-31
    • As motion lines usam 4 attached sprites e, nos gráficos, usam apenas as cores 29-31
  • Usando o mesmo gráfico de sprite em várias posições

    • Os 4 primeiros bytes do gráfico do sprite são bits de controle que definem posição e altura
    • Essa estrutura vira um problema quando se quer desenhar o mesmo gráfico em várias posições
    • Tentou-se definir diretamente os bits de controle do sprite por registradores de hardware, mas não foi possível fazer com que aparecessem na tela
    • O DMA de sprites do Amiga, assim como o DMA de bitplanes, segue o ponteiro dos dados do sprite e desenha na tela
    • A solução foi criar 8 sprites falsos de 4 bytes
      • Esses sprites falsos contêm apenas bits de controle
      • Todos os ponteiros de sprite são primeiro definidos para os sprites falsos
      • Por volta da linha 19, o sprite DMA lê os ponteiros e carrega os bits de controle
      • Depois disso, todos os ponteiros são trocados para o gráfico real da “motion line”
    • Com isso, o DMA fica carregado para desenhar sprites em posições diferentes enquanto usa o mesmo gráfico, e essa troca é feita na copperlist

O problema de os sprites sumirem quando os bitplanes são desligados

  • Antes de a CG chegar ao topo da tela, há um espaço vazio entre a parte superior da tela e o ponto inicial da CG
    • Se os bitplanes ficarem ligados nesse momento, lixo visual será desenhado na tela
  • Nessa área, é preciso desligar os bitplanes para que o DMA não leia dados inválidos
  • O problema é que, ao desligar os bitplanes, os sprites também deixam de ser desenhados
    • As motion lines acabam aparecendo apenas dentro dos limites da CG
  • A solução é não desligar completamente os bitplanes: mantém-se apenas 1 ativo e o ponteiro da tela é definido para dados vazios
    • Algo é desenhado na tela, mas na prática nada fica visível
  • Não é necessário preparar uma tela vazia inteira
    • Considerando pixels de 1 bit, uma linha de 320 pixels tem 320 bits, ou 40 bytes
    • Ao definir BPLMOD1 como -40, depois de cada linha o ponteiro volta 40 bytes e repete o desenho dos mesmos 40 bytes
    • Basta deixar zerados os primeiros 40 bytes da safety margin da tela

Resultado e pequenas tarefas que ainda restam

  • No início havia dúvida se valeria a pena colocar esse tipo de CG no jogo por causa da exigência de RAM, mas depois de implementar a compressão de dados ficou claro que o overhead é bastante razoável
  • Isso permitiu adicionar mais ornamentação visual ao Magicore
  • Ainda restam pequenas tarefas não abordadas
    • Por exemplo, evitar que a parte de baixo de uma motion line de 100 px desapareça de repente depois que ela sai pelo topo da tela
  • Esse efeito não usa o blitter em nenhum momento
  • O Amiga continua sendo uma plataforma capaz de impressionar as pessoas com sua exibição de gráficos coloridos hoje, assim como impressionava no fim dos anos 1980

1 comentários

 
GN⁺ 2024-02-26
Comentários do Hacker News
  • Entendo exatamente o que quer dizer “Racing the beam”. Antigamente, a gente mudava a cor do feixe no início e no fim de uma rotina sincronizada com vsync para calcular quantas scanlines de tempo de CPU podíamos usar por frame
    Lembro que o endereço usado para isso era $dff180. Era a paleta de cores 0, então sempre aparecia também nas bordas da tela fora da área do bitmap
    Aprendi esse truque todo no boca a boca, sem internet, e nem sabia que hoje ainda havia gente tentando extrair mais daquele chipset

  • Tenho muita curiosidade sobre que tipo de gente consegue arranjar tempo para criar jogos no Amiga. Imagino que os mais jovens não se interessem por computadores tão antigos, e que quem cresceu usando isso esteja ocupado com família e trabalho
    Mesmo que não estejam ocupados, há tantos projetos igualmente divertidos e capazes de manter uma pegada moderna. Ainda assim, é muito legal

    • Nasci em 1991 e, antes de migrarmos para um PC com Windows 95, havia um Amiga 1000 em casa. Então sempre tive nostalgia pelo Amiga, e meu carinho por ele só cresceu conforme fui entendendo melhor os chips únicos e poderosos que davam a ele aquele desempenho
      Hoje trabalho em tempo integral como desenvolvedor indie de jogos. Fazer um jogo para Amiga era quase um sonho de vida, e agora acho que tenho as habilidades para realizá-lo
      Quero mostrar que, usando as ferramentas atuais e o conhecimento amplamente disponível, é possível dar nova vida a um hardware clássico querido com uma experiência de jogo baseada em princípios modernos de design
    • Para muita gente, não há nada tão divertido quanto Amiga, C64, Atari e ZX Spectrum
      Se você relaciona tudo na vida à carreira, a vida inteira vira trabalho
      É parecido com perguntar por que praticar pintura a óleo se existe Photoshop, ou por que restaurar carros antigos se existe Tesla
    • Talvez eu não seja jovem o bastante para entrar nesse grupo, mas gosto muito de computadores que são um pouco anteriores à minha época. Consegui um Commodore 64, troquei os capacitores, substituí o PLA e ainda instalei dual SID e uma modificação de “troca de região”
      A modificação de troca de região é bem complexa, porque é preciso alternar entre dois VIC-II e dois osciladores. Também tenho um MSX2; não usei muito, mas ele tem muito charme
      Arranjar tempo para realmente escrever código para essas máquinas é difícil, mas, como na maioria dos hobbies de quem trabalha, é uma questão de dedicar noites e fins de semana quando a inspiração aparece
      Retrocomputação é um hobby excelente, fascinante e gratificante. Minha maior queixa, porém, nem é o tempo, mas o preço e a dificuldade de conseguir peças
      É uma pena ver que, no mercado de computadores, parece haver cada vez mais gente tentando vender caro qualquer coisa que receba o rótulo de “antigo” ou “vintage”
      Sobre o pessoal mais velho, é difícil falar por eles, mas parece que alguns dos que ainda fazem demos para Commodore 64 têm uma vontade forte de se reconectar com a infância
      Há obras que quase contam isso diretamente, como a demo relativamente recente “Mojo”, da Bonzai e da Pretzel Logic. Tentar fazer uma narrativa “séria” em uma produção da demoscene é meio constrangedor, mas ainda assim é caloroso e simpático
      É um hobby que consome muito tempo, mas, se você realmente quer arranjar tempo, acaba encontrando um jeito
      [1]: https://csdb.dk/release/?id=232966, https://www.youtube.com/watch?v=HXi3oJ9huiI
    • Tenho um amigo que cria interfaces para conectar controles novos a computadores antigos. Aqui ele conectou um Nintendo Balance Board para jogar Decathlon do Commodore 64
      [1] https://retro.moe/2024/02/04/bluepad32-v4-0/
      [2] https://www.youtube.com/watch?v=Nj5fZlt_834
    • Sou 5 anos mais velho que o autor do post original. No começo da pandemia, reuni um Atari, um Amiga e alguns materiais para aprender assembly por diversão. Também há um curso na Udemy
      https://www.udemy.com/course/programming-games-for-the-atari...
      Achei que trabalhar de casa me daria mais tempo livre, mas não foi bem assim. Ainda assim, um dia preciso continuar mexendo nisso
  • Sempre me perguntei como seriam jogos no estilo dos consoles japoneses no Amiga, e se o Amiga realmente não tinha desempenho suficiente ou se o design da maioria dos jogos simplesmente não era do meu gosto
    Bonk foi muito bem portado pela Factor 5, mas eles eram praticamente magos

  • A parte que diz “um Amiga 500 comum tem 512 KB de Chip RAM e 512 KB de RAM de expansão” é um pouco imprecisa. O A500 básico tinha apenas 512 KB de Chip RAM
    Muitos usuários adicionavam a expansão de RAM A501, acrescentando 512 KB de Fast RAM que o hardware gráfico não podia acessar diretamente
    Embora fosse chamada de Fast RAM, por causa da arquitetura da expansão ela era mais lenta que a Fast RAM de verdade

    • A chamada Slow RAM
      A maioria dos donos de A500 tinha a expansão de 512 KB no trapdoor. Muitos softwares, incluindo jogos como Monkey Island, não rodavam sem 1 MB de RAM no total
      Hoje há muitas expansões baratas de trapdoor baseadas em projetos de hardware aberto, oferecendo 1,5 MB de Slow RAM, 512 KB de Chip RAM para chegar a 1 MB total, e até RTC
  • Há algo incrivelmente atraente em programar dentro dessas limitações

    • “O inimigo da arte é a ausência de restrições
  • Que bom ver o IE. É legal vê-lo explorando o Amiga

  • Tenho a impressão de que muita gente brincou com um Amiga diferente do que eu tive. Havia, sem dúvida, jogos com visual bonito, mas o Nintendo NES também tinha, e não olho para nenhum dos dois com tanta ternura
    Ainda assim, é muito legal mostrar como uma animação dessas foi feita

    • Tive os dois, e o Amiga, sinceramente, parecia uma máquina duas gerações à frente. Olhando para a diferença de hardware, não é surpresa
      O Amiga era realmente um sistema com tudo dentro. Tinha uma CPU avançada de 32 bits, aceleração gráfica, áudio excelente e literalmente 256 vezes mais RAM que o NES
      Nem o SNES chegou perto; só na época do Sega Saturn vi uma máquina superar o Amiga
    • Só para confirmar: você sabe que isto é um jogo novo em desenvolvimento agora, certo?
      https://www.youtube.com/watch?v=4SB20aFHc08