Fazer novos jogos para consoles retrô é algo que os desenvolvedores amadores podem fazer facilmente graças à tecnologia atual. No ano passado, lancei um novo jogo para o meu console favorito: o Super Nintendo (SNES). O projeto chegou a ser um lançamento físico real, com um cartucho e uma caixa de papelão como nos anos 90. Neste artigo, apresentarei as inúmeras etapas dessa incrível jornada: projetar o jogo, superar problemas técnicos relacionados ao SNES ao programá-lo, fabricar novos cartuchos SNES e criar o manual e a caixa.

O jogo : Yo-Yo Shuriken

Yo-Yo Shuriken é um jogo de arcade rápido para 1 ou 2 jogadores no Super Nintendo (SNES).

 

A jogabilidade principal gira em torno de atirar em um único shuriken que você pode magicamente lembrar a qualquer momento, para que você possa acertar inimigos pela frente ou por trás! Você pode até mesmo concentrar energia no shuriken para entregar um poderoso ataque carregado que pode cortar vários inimigos de uma só vez.

O jogo está disponível em cartucho com uma bela caixa de papelão e um manual da Catskull Games:
https://catskullgames.com/yo-yo-shuriken

E se você preferir jogá-lo em emuladores, você também pode obter a ROM do jogo aqui:
https://drludos.itch.io/yo-yo-shuriken

Agora que você está mais familiarizado com o jogo em si, vamos explorar como ele foi projetado.

Projetando o jogo

Fazer Yo-Yo Shuriken foi um processo bastante orgânico. Testei ideias de jogabilidade à medida que as criei e tentei refiná-las até ter um jogo “divertido” em mãos. Comecemos pela ideia inicial. Por muito tempo, eu queria fazer um jogo de tiro com uma única bala. Assim, o jogador deve recuperá-lo cada vez que atirar. Além da ideia de “uma bala”, eu também queria fazer um jogo que pudesse ser apreciado com um amigo, em co-op. Com as duas ideias em mente, criei o jogo passo a passo. Cada grande progresso que fiz foi rotulado como uma nova “versão” e testado pesadamente. Se a versão atual era boa, eu continuava a adicionar novos recursos. Caso contrário, continuei trabalhando nos recursos atuais até que o jogo fosse divertido de jogar novamente antes de adicionar qualquer coisa nova. Aqui está um resumo dos principais protótipos de jogos, com capturas de tela. Se você quiser jogar as ROMs reais desses protótipos, eles são uma das muitas vantagens disponíveis para meus apoiadores do Patreon.

1) Cyber Ninja - versão 1

A primeira coisa a fazer ao fazer um jogo em uma plataforma que você não conhece é exibir algo na tela! Então desenhei um sprite ninja robótico e tentei ter o SNES para exibi-lo na tela. Quando funcionou, adicionei código para fazer os movimentos de sprite com o D-Pad. E então fiz uma animação ambulante quando o sprite se moveu. Esses primeiros passos podem parecer simples. Mas lembre-se que foi minha primeira vez fazendo um jogo para o SNES! Então, realmente levou algum tempo para fazer, pois eu estava aprendendo como a máquina funcionava enquanto fazia o jogo. Como o projeto atual exibia apenas um ninja robótico, eu o chamei de “Cyber Ninja”.

2) Cyber Ninja - versão 2

O jogador real sprite, um ninja, apareceu nesta segunda versão. Assim, os sprites robôs naturalmente se tornaram seus inimigos, pois todos sabem que ninjas e robôs se odeiam! Como um ninja orgulhoso, o jogador pode lançar um único shuriken. O shuriken pode ficar preso na borda da tela, e o jogador deve pegá-lo para poder atirar novamente. Os inimigos robôs podem se mover sem rumo na tela, mas nenhuma detecção de colisão é realizada ainda.

3) Yo-Yo Shuriken - versão 1

Depois de vários testes, pensei que o shuriken poderia voltar para o ninja automaticamente quando o jogador pressionasse o botão uma segunda vez. Eu me diverti muito ao testar essa mecânica, então ela se tornou o núcleo de todo o jogo! Também mudei o título do projeto para refletir essa evolução: diga adeus a “Cyber Ninja” e seja bem-vindo a “Yo-Yo Shuriken”! De fato, no jogo o shuriken vai e volta, muito parecido com um ioiô.

Também adicionei a detecção de colisões. Agora, os robôs desaparecem quando o shuriken os atinge. Mas se um robô atinge o jogador, ele é quem desaparece. Embora tudo ainda esteja em um estado muito básico, a jogabilidade principal do jogo está quase completa neste terceiro protótipo de jogo. Então decidi “testar o estresse” do motor para ver até onde eu poderia empurrá-lo antes que o jogo atrasasse. Consegui ter até 80 inimigos andando e interagindo na tela. Lembre-se que um SNES pode exibir um total de 128 sprites, então ter 80 deles atualizados 60 vezes por segundo com colisões e animações é algum tipo de conquista.

4) Yo-Yo Shuriken - versão 2

Nesta quarta versão, os inimigos não se limitam mais a movimentos em linha reta. Eles agora podem se mover em várias direções. Eles também saltam das bordas da tela para evitar sair da área de jogo. O jogo ficou mais interessante como resultado.

5) Yo-Yo Shuriken - versão 3

Eu adicionei uma cor de fundo diferente, e um sistema para gerar inimigos infinitamente. Na versão anterior, uma vez que os 80 robôs foram destruídos, o jogo estava vazio. Aqui um exército interminável de robôs é gerado! Os inimigos também podem seguir o jogador, para forçá-lo a continuar se movendo. De fato, nesta quinta versão, o jogo se tornou rapidamente chato se o jogador permanecesse estático.

6) Yo-Yo Shuriken - versão 4

Nesta versão, enfrentei minha primeira grande dificuldade técnica: exibir grandes sprites de explosão sempre que um robô morre. Eu escolhi ter jogadores bem pequenos e inimigos sprites: 16x16 pixels. Dessa forma, eu poderia exibir muitos deles na tela, mantendo espaço vazio suficiente para o jogador se mover e evitar bater em inimigos (a resolução da tela SNES é de 256x224 pixels). No entanto, decidi desenhar minhas explosões em tamanho maior: 32x32 pixels. O Super Nintendo é capaz de exibir dois sprites diferentes ao mesmo tempo. O desenvolvedor pode escolher um tamanho de sprite “pequeno” e um “grande” de uma pequena lista de tamanhos (8x8, 16x16, 32x32 e 64x64) e o console usará essas informações ao acessar a RAM de vídeo para exibir os dados do sprite na tela. Este é um dos muitos recursos gráficos que facilitam a vida dos desenvolvedores de jogos. Mas como qualquer recurso técnico, pode se tornar assustador quando você não sabe como usá-lo!

No meu caso, neste protótipo atual, eu só era capaz de exibir uma pequena parte dos sprites de explosão, não importa o que eu fizesse. O problema era realmente bastante simples: eu não estava carregando os dados do sprite onde necessário na memória de vídeo SNES. Então a máquina não conseguia lê-los de volta. Eu encontrei a solução depois de passar várias horas nas documentações maravilhosas feitas pela comunidade homebrew ao longo dos anos. Agradeço-lhes muito pelo seu trabalho árduo na criação e partilha de todo este precioso conhecimento: sem eles, amadores como eu não seriam capazes de fazer jogos SNES!

7) Yo-Yo Shuriken - versão 5

Este protótipo marca a adição de outra característica importante: o modo cooperativo para dois jogadores!

Novos tipos de inimigos também entram na briga: os robôs laranjas podem levar vários golpes antes de explodir, e os robôs azuis podem perseguir o jogador em qualquer lugar. Eu também adicionei moedas que você tem que coletar para marcar pontos. Isso mecanic melhora muito a jogabilidade. Na verdade, a única maneira de marcar pontos é coletar moedas. Matar robôs não traz nenhuma “recompensa” em si, é apenas uma maneira de evitar que seu avatar morra. Os robôs soltam moedas quando morrem. Mas as moedas desaparecem depois de alguns segundos. E há sempre muitos robôs na tela, que vão matá-lo instantaneamente quando tocado. Para ganhar pontos, o jogador deve, portanto, correr muitos riscos e se mover entre os robôs, caso contrário, ele não será capaz de fazer uma pontuação alta. Mas, às vezes, é melhor deixar algumas moedas desaparecerem para evitar perder uma vida. Isso é o que os designers de jogos chamam de escolha de “risco / recompensa”, e é uma ótima maneira de tornar um jogo interessante. Aqui, este mecanismo permite que Yo-Yo Shuriken ofereça uma progressão de dificuldade suave aos jogadores. Normalmente, um jogador novato tenderá a permanecer estático e se concentrará apenas em destruir os robôs. Ele não vai conseguir pontos, mas vai conseguir continuar no jogo e derrotar o chefe final. Uma vez que um jogador começa a ficar mais confiante, ele será capaz de coletar moedas para fazer um highscore. E, claro, jogadores experientes podem tentar fazer uma “corrida perfeita” coletando todas as moedas, embora isso signifique correr uma quantidade insana de riscos!

8) Yo-Yo Shuriken - versão 6

À medida que os testes de jogo foram acontecendo, percebi que o jogo estava se tornando bastante repetitivo. Testei várias ideias para resolver esse problema. O que achei mais interessante foi segurar o botão de disparo para “carregar” seu shuriken. Quando você solta o botão, ele dispara um “super tiro” que pode cortar vários inimigos. Essa mecânica traz um pouco de pensamento estratégico para o jogo. Agora, o jogador pode optar por executar vários tiros simples para matar os inimigos um por um. Ou ele pode optar por executar um tiro carregado para matar vários inimigos de uma só vez. Mas aí ele vai ficar vulnerável enquanto o super tiro está carregando.

9) Yo-Yo Shuriken - versão 7

A partir desta versão, todas as mecânicas do jogo que definem a jogabilidade principal estavam dentro. Assim, o projeto entrou na fase mais longa e tediosa: adicionar conteúdo e polir o jogo. Primeiro, adicionei efeitos sonoros, que criei com BFXR. Também incluí as maravilhosas faixas musicais compostas por XRACECAR. Eu também modifiquei a GUI do jogo e movi-lo para o topo da tela.

Em relação aos gráficos, adicionei um padrão ao fundo do jogo. Como minhas habilidades artísticas são limitadas, tive dificuldade em desenhar um fundo convincente. Fiz várias tentativas, inclusive essa, antes de me acomodar em um “piso de tábuas de madeira” para enfatizar que o jogo se passa dentro de um dojo (veja a próxima versão).

Por último, mas não menos importante, comecei a criar os vários níveis de jogo. Cada nível é composto por várias ondas de inimigos, com força e números crescentes. Passei uma quantidade insana de tempo testando e equilibrando essas ondas inimigas para tornar o jogo divertido. Cada designer de jogos faz isso do seu jeito. Pessoalmente, para um jogo de arcade, gosto de misturar momentos intensos e desafiadores com momentos mais fáceis para que o jogador possa recuperar o fôlego. Por exemplo, se o jogador conseguir passar um momento com robôs em movimento rápido perseguindo-o enquanto o dojo já está cheio de inimigos em movimento lento, eu o recompensarei com um momento mais lento. Como 4-5 inimigos básicos movendo-se muito lentamente para que você possa facilmente matá-los e coletar suas moedas.

Em uma nota lateral, você pode notar que os gráficos de explosões ainda são particularmente horríveis nesta fase.

10) Yo-Yo Shuriken - versão 8

Nesta versão, um novo tipo de inimigo entrou na briga: o robô “escudo”. Eles só podem ser atingidos por trás. O “ioiô shuriken” mecanic torna-se ainda mais significativo aqui. Na verdade, a melhor maneira de matar robôs de escudo é atirar em torno deles primeiro. Então, você terá que chamar o shuriken de volta e tentar atingi-los controlando sua trajetória de retorno. Eu também fiz novos sprites de explosões, e a imagem de fundo é mais bonita. Eu até adicionei um captador de bônus de invencibilidade (uma cabeça ninja branca, substituída por uma estrela no jogo final).

11) Yo-Yo Shuriken - versão 9

O último grande recurso chegou nesta versão: os chefes do jogo. Passo muito tempo projetando e testando inúmeros chefes. Esta foi uma das partes mais agradáveis do processo de desenvolvimento do jogo!

Nas imagens, é possível ver um protótipo do chefe “cobra” e um chefe não presente na versão final: o tanque. O chefe do tanque deve ser destruído em várias etapas. Tem vários pontos fracos (as bolas laranjas) que têm de ser acertados um atrás do outro. Uma vez que um ponto fraco é destruído, ele remove parte da estrutura dos tanques, expondo novos pontos fracos. Era um chefe desafiador. Por exemplo, um ponto fraco está no fim de um túnel, por isso requer uma mira muito precisa.

 

No papel, essa ideia do chefe era bem interessante. Levei vários dias para programá-lo. Mas depois de muitas sessões de jogo, decidi retirá-lo do jogo, pois era chato. De fato, às vezes era muito difícil destruir o chefe por causa de seu enorme tamanho. Além disso, se o chefe conseguiu bloqueá-lo em um canto, você estava morto, pois não poderia acertar nenhum de seus pontos fracos. No final, enfrentar esse chefe foi uma experiência mais frustrante do que divertida. Como você pode ver, mesmo em projetos de jogos amadores, às vezes você tem que cortar conteúdo decepcionante, apesar do tempo que você gastou fazendo! 

12) Yo-Yo Shuriken - versão 10

A palavra-chave dessa versão final foi “polimento”. Adicionei a tela de título, as animações de introdução e final, e uma tela para explicar como o jogo funciona. O toque final foi incluir um modo bônus oculto: o modo “ninja duplo”, onde você pode controlar dois ninjas com um único controle. Para desbloquear este modo, você simplesmente precisa terminar o jogo uma vez (ou usar um código de trapaça!).

Então, depois de mais de um ano de desenvolvimento e 5491 linhas de código, Yo-Yo Shuriken foi finalmente concluído! A ROM do jogo funciona perfeitamente. Foi testado em várias versões do console original (Super Famicom japonês, Super NES dos EUA, PAL Super Nintendo); em versões modernas (PAL modded com o kit 50/60hz de FFVIMan, Analogue Super NT); e em muitos emuladores (Higan/BSNES, SNES9X, ZSNES, No$SNS, RetroArch, etc.) para várias plataformas (PC, smartphone, PSP, Raspberry Pi, etc.).

Uma vez que a versão final do software do jogo foi validada (todos os bugs corrigidos após uma extensa fase de testes beta), a parte de hardware do projeto poderia começar. Em outras palavras, precisávamos disponibilizar o jogo em cartuchos reais com uma bela caixa de papelão! Mas antes de explorar essa parte do processo, gostaria de dar mais detalhes sobre o desenvolvimento deste jogo para um SNES.

Programando o jogo

Fazer jogos em plataformas retrô vem com muitas restrições técnicas. O uso de ferramentas modernas simplifica a tarefa em comparação com o que os desenvolvedores dos anos 90 enfrentavam. Mas você ainda tem muitas restrições relacionadas às especificações limitadas do hardware. Como todos os outros desenvolvedores homebrew, eu lutei com essas limitações ao fazer Yo-Yo Shuriken. Aqui estão as ferramentas que usei e os principais problemas que enfrentei. Espero que eles ajudem você a descobrir como o SNES funciona sob o capô.

Ferramentas do ofício

Nos anos 90, os programadores de jogos tinham que aprender e usar a montagem para cada máquina em que estavam trabalhando. O SNES era uma máquina difícil de trabalhar porque você tinha que aprender não uma, mas duas linguagens de montagem: o assembly 65816 para a CPU e o assembly SPC700 para o chip de áudio.

Hoje em dia, você ainda pode usar a montagem, e é realmente a única rota para obter o máximo de energia de qualquer máquina retrô. Mas você também pode fazer alguns jogos muito legais com linguagens mais fáceis de aprender, como C ou Basic. Para o SNES, você tem apenas um compilador C disponível: tcc816. Está longe de ser perfeito, pois você tem que usar algum script python para otimizar/corrigir bugs no código que ele produz, mas funciona. Um talentoso codificador chamado Alekmaul pegou este compilador e construiu uma estrutura completa para facilitar a criação de jogos: o PVSNESlib.

Eu usei essa biblioteca para fazer Yo-Yo Shuriken, para que eu pudesse codificá-la em linguagem C. Para gráficos, desenhei imagens BMP que foram convertidas para o formato gráfico SNES. Para áudio, o framework aceitava arquivos wav para efeitos sonoros e arquivos .it (formato Impulse Tacker) para música. Ainda era um grande desafio fazer um jogo rodando no SNES, mas PVSNESlib fez dele um “desafio difícil, mas divertido”!

Como funciona um SNES?

Em comparação com outras máquinas como o Mega Drive / Genesis ou o PC-Engine / TurboGrafx16, o SNES é uma máquina bastante complexa, com muitos modos gráficos diferentes. Mas seu fluxo de trabalho geral é realmente bastante simples. Basicamente, um SNES pode exibir dados gráficos usando dois canais: o “fundo” e os “sprites”. O plano de fundo é uma imagem de tela cheia feita de blocos 8x8. O plano de fundo pode ter várias camadas (de 1 a 4) que podem ser roladas independentemente. A RAM de vídeo é limitada, então você geralmente tem que transmitir dados gráficos da ROM do cartucho para a RAM de vídeo em tempo real, a fim de exibir algumas áreas de rolagem infinitas ou grandes.

Para os sprites, o SNES pode exibir diferentes tamanhos: 8x8, 16x16, 32x32 e 64x64 - apenas dois desses tamanhos podem estar na tela ao mesmo tempo. Para animar sprites você tem que definir manualmente sua posição na tela e modificar os dados gráficos que eles irão exibir, 60 vezes por segundo. Para fazer isso, como com o fundo, você primeiro tem que copiar os dados gráficos (ou seja.part do seu spritesheet) do chip ROM do cartucho para a RAM de vídeo do console.

O SNES também pode reproduzir áudio usando um chip dedicado (SPC700). Para entrada, é muito fácil ler quais botões os jogadores pressionaram nos gamepads SNES. (o melhor gamepad já projetado!)

No final, mesmo se você usar uma ferramenta como PVSNESLib, você precisará estar familiarizado com como o SNES funciona, a fim de fazer jogos reais para ele. Espero que a maravilhosa comunidade homebrew tenha consolidado alguma documentação muito extensa. Vou recomendar:

Agora que abordamos alguns conceitos básicos, vamos nos aprofundar em alguns problemas técnicos que enfrentei.

Quantos inimigos podemos exibir na tela?

Em um jogo como Yo-Yo Shuriken, quanto mais sprites na tela (inimigos, explosões, etc.), melhor será o jogo! No entanto, o jogo não pode se dar ao luxo de atrasar. Então você tem que encontrar o número máximo de inimigos que a CPU pode lidar enquanto mantém uma exibição suave de 60 fps. O SNES é frequentemente apontado como “lento” em comparação com o Genesis / Mega Drive (“Blast Processing” alguém?). E, de certa forma, isso é verdade. Enquanto o SNES pode exibir imagens mais coloridas e som de maior qualidade, o tempo de CPU disponível é geralmente menor do que o Genesis. Em outras palavras, o Genesis geralmente poderia mover mais sprites na tela do que o SNES. Os melhores exemplos dessa diferença são Contra III (SNES) e IV (Gênesis). E mais especificamente, como cada jogo lida com explosões:

 

Explosão em Contra III do SNES (esquerda) são feitos com alguns sprites ao lado de um efeito gráfico especial (transparência), enquanto Contra IV de Genesis (direita) os renderiza com uma quantidade insana de sprites na tela. Ao programar cada console como eles devem ser, diretamente no montador, você pode sentir essa diferença no poder de processamento. Mas ao usar um compilador C como fiz para Yo-Yo Shuriken, a diferença se torna ainda mais óbvia. Assim, onúmero de inimigos que eu poderia exibir era limitado pelo tempo de CPU disponível. Mas as tarefas da CPU não se limitam ao gerenciamento de sprites. Ele também deve lidar com animações, carregar dados gráficos para a RAM de vídeo, gerenciar colisões, ler entradas do controlador, disparar sons e música no chip de áudio, etc. Desenvolver Yo-Yo Shuriken era uma luta constante para manter o maior número possível de inimigos na tela, enquanto todos os outros elementos estavam comendo o tempo total de CPU disponível. Assim, tive que diminuir o número de inimigos várias vezes à medida que adicionava novos recursos ao jogo.

No início, quando havia apenas robôs padrão se movendo em linha reta sem detecção de colisão, eu era capaz de exibir 80 inimigos na tela (mais 1 jogador e seu shuriken). Quando adicionei a detecção de colisões entre inimigos, jogador e shuriken, tive que reduzir esse número para 40 inimigos. Adicionando o segundo player, explosões, efeitos sonoros e música também tomou uma grande parte do tempo de CPU disponível. No final, o jogo final só pode exibir até 24 inimigos na tela, a fim de manter uma taxa de exibição suave de 60 fps. Embora possa parecer pouco no papel, quando você jogar o jogo verá que 24 inimigos são mais do que suficientes para oferecer um desafio, especialmente nos níveis mais avançados do jogo!

Honestamente, ser capaz de gerenciar 38 sprites animados na tela (24 inimigos + 2 jogadores + 2 shurikens + 10 explosões) sem qualquer lentidão ainda é uma conquista. Mas há um truque por trás dessa conquista: nem todos os sprites são atualizados a cada quadro. De fato, enquanto o jogador e o shuriken são atualizados 60 vezes por segundo, os inimigos e explosões são atualizados apenas a cada dois quadros, e até mesmo a cada quarto quadro em alguns casos. Esse truque de programação era bastante comum durante os anos 90. Ele permite espalhar os cálculos relacionados à colisão por vários quadros, a fim de exibir mais sprites na tela sem diminuir a taxa de quadros do jogo.

LUT faz sprites girarem!

Enquanto os inimigos padrão têm padrões de movimento simples, com movimento reto ou diagonal, os chefes se movem de forma mais complexa. Por exemplo, muitos chefes têm bolas girando em torno deles.

 

Do ponto de vista matemático, você simplesmente precisa calcular o seno e o cosseno de cada ângulo de bola para movê-los em um movimento circular. Em uma plataforma moderna, esses cálculos são fáceis e rápidos de fazer. Mas em plataformas retrô, isso é um desafio e tanto! A CPU das máquinas de 8/16 bits não tem funções internas para computar seno e cosseno no hardware. Então você tem que computá-los em software, combinando um monte de cálculos mais complexos. Isso obviamente leva uma quantidade significativa de tempo. O SNES não seria capaz de computar o seno e o cosseno para 24 inimigos a uma taxa de 60 fps, além de todo o resto. Como as bolas se movem lentamente, elas são atualizadas apenas uma vez a cada 4 quadros, elevando o número de cálculos de 24 para 6. Mas neste caso em particular, isso ainda é demais: a CPU não pode computar 6 seno e 6 cosseno a cada quadro, além de todas as outras tarefas.

Claro, há um truque para resolver essa questão em particular, que também era muito comum nos anos 90. Para reduzir a carga na CPU, você pode simplesmente usar uma “Tabela de pesquisa” em vez de fazer os cálculos de seno e cosseno a cada quadro. Simplificando, calculei os valores de seno e cosseno para uma grande variedade de ângulos com antecedência, usando um programa de planilha na minha máquina moderna. Então, eu armazenei todos esses valores em uma tabela gigante dentro da ROM do jogo. Dessa forma, a CPU agora pode ler os valores de seno e cosseno que precisa para mover as bolas na ROM, em vez de perder tempo para computá-las a cada quadro. Essa tabela gigante de dados pré-computados é chamada de “Tabela de Pesquisa”, ou LUT. LUTs eram muito comuns em jogos feitos antes da era dos 32 bits. E não se limitam ao seno e ao cosseno! Qualquer coisa que seja “lenta para computar” em uma CPU geralmente será computada com antecedência para que os resultados possam ser armazenados em uma LUT: trigonometria, efeitos de cor, geração de números aleatórios, efeitos de varredura raster, etc.

Quando os consoles de 32 bits chegaram, esse problema foi resolvido porque sua CPU apresentava função de hardware para executar cálculos de trigonometria em um piscar de olhos. De fato, a trigonometria é uma parte essencial de qualquer renderização baseada em 3D. Assim, máquinas como o PlayStation e o Saturn precisavam ser capazes de fazer isso de forma rápida e repetida a cada quadro. Ao ler isso, você deve estar se perguntando: se isso é verdade, será queo SNES pode renderizar gráficos 3D em um jogo como Starfox?

Nesse caso, uma LUT não seria suficiente: há muitos cálculos a serem feitos. Assim, os criadores do Starfox simplesmente adicionaram um novo processador que pode computar trigonometria rapidamente dentro do cartucho: o famoso chip “Super FX”! O SNES não seria capaz de computar e exibir todos esses objetos 3D sem o Super FX. Mas Starfox não é o único jogo a usar esse chip. Super Mario Kart e Pilotwings usam outro chip para o mesmo propósito, o “DPS-1”. Como o Super FX, ele pode executar cálculos de trigonometria mais rápido do que a CPU SNES. Enquanto o DPS-1 é usado apenas para fazer cálculos, o Super FX é muito mais poderoso e pode realmente renderizar polígonos em um framebuffer 2D, como o PlayStation e o Saturn fazem.

Cuidado com o VBLANK!

Uma vez que a CPU tenha terminado de computar, ela deve dizer ao chip gráfico para exibir o resultado de sua computação na tela. É assim que qualquer console funciona, seja qual for a data de lançamento. Mas os da era dos 8/16 bits têm um comportamento específico: a CPU só pode enviar dados para o chip gráfico durante um período de tempo específico: o “VBLANK”. Mas o que é o VBLANK?

Em uma televisão CRT padrão, a imagem é desenhada através de um feixe de elétrons que se move de cima para baixo e da esquerda para a direita. Enquanto o feixe de elétrons se move atrás da tela para desenhar a imagem, ele pinta “pixels” de uma cor específica usando instruções do chip gráfico do console. Sem esse chip gráfico, o feixe de elétrons não saberia qual cor pintar e, portanto, nenhuma imagem seria exibida na tela. Uma vez que o feixe de elétrons terminou de pintar uma imagem, ele chega à parte inferior da tela. Ele deve então voltar para o topo da tela para começar a pintar uma nova imagem, usando as novas instruções enviadas pelo chip gráfico. O período time enquanto o feixe de elétrons está desligado para que ele possa se mover de volta para o topo da tela é chamado de “Vertical Blanking”, ou VBLANK.

Em um SNES, quando o chip gráfico envia instruções para o feixe de elétrons, ele não pode fazer mais nada. Além disso, você não pode nem mesmo modificar a memória de vídeo neste momento, pois contém a imagem para exibir na tela. De fato, o chip gráfico precisa dele para controlar o feixe de elétrons. Se conseguirmos de alguma forma modificar a memória de vídeo enquanto o chip gráfico está exibindo uma imagem na tela, ele exibiria uma imagem corrompida, ou pior. Portanto, o SNES foi projetado para evitar isso: a CPU simplesmente não pode acessar a memória de vídeo enquanto o chip gráfico está exibindo uma imagem. A CPU precisa aguardar o período VBLANK para poder enviar os dados gráficos da nova imagem para exibir na tela na memória de vídeo. E esse período de tempo é bem curto.

Então, quais são as consequências reais de todas essas limitações relacionadas ao VBLANK? Simplificando, é outra limitação severa no tempo total disponível para o desenvolvedor de jogos exibir seu jogo na tela. Primeiro de tudo, para evitar que o jogo fique para trás, você precisa realizar todos os cálculos de jogabilidade (colisões, movimento, animações, etc.) entre dois períodos VBLANK. Se o código do jogo levar mais tempo para ser computado, você não poderá exibir o quadro resultante a tempo e, portanto, o jogo ficará visivelmente atrasado na tela.

Mas uma limitação ainda mais difícil é que você só pode enviar muito poucos dados gráficos para a memória de vídeo durante cada VBLANK. De fato, a velocidade de transferência de dados gráficos é limitada pelo que é chamado de “barramento”. O “ônibus” é a linha eletrônica real que conecta todos os chips. Se você tentar enviar mais dados do que o que é possível transferir durante o período VBLANK, os dados adicionais serão simplesmente cortados e não exibidos.

Um bug vicioso: a armadilha de 50hz/60hz!

Eu experimentei as limitações VBLANK em primeira mão enquanto fazia Yo-Yo Shuriken. Foi a causa do bug mais cruel que encontrei durante todo o projeto. Durante os testes beta, usando o emulador ZSNES e meu próprio console, tudo estava exibindo bem. Mas, quando testei o jogo em outros emuladores que são conhecidos por serem mais precisos que o ZSNES, ou seja, SNES9X e Higan/BSNES, alguns sprites não foram exibidos. Mais especificamente, as explosões foram “cortadas”, como você pode ver nas imagens abaixo:

     
ZSNES e meu console (esquerda) / BSNES-Higan (direita)

Durante semanas, tentei resolver essa questão, sem sucesso. Eu finalmente fui capaz de corrigi-lo graças à ajuda de assistentes do fórum SNESDev. a comunidade SNESDev me ajudou mais de uma vez durante este projeto, e eu não poderia estar mais grato por toda a ajuda que eles forneceram! Eles descobriram que a causa desse problema era simplesmente que eu estava enviando muitos dados para o chip gráfico a cada quadro. O tempo necessário para transferir todos os dados foi superior ao período VBLANK. Assim, a animação de explosões não teve tempo de chegar ao chip gráfico antes do fim do VBLANK, e foi simplesmente cortada. Mas você pode se perguntar: por que esse bug só estava acontecendo em algum emulador preciso, e não no console real?

É aí que o inseto se torna vicioso. Como todos os amantes de SNES que vivem na Europa, meu console de infância funciona no formato de TV “PAL”, rodando em 50hz. Em outras palavras, o chip gráfico do console exibe uma nova imagem na tela 50 vezes por segundo. Nos EUA e no Japão, o formato da TV é diferente: é “NTSC”, rodando em 60hz. Assim, os consoles NTSC exibem uma nova imagem na tela 60 vezes por segundo. Isso significa que os jogos americanos e japoneses rodam mais rápido do que os europeus? Infelizmente, sim! (mas não sabíamos disso durante os anos 90…). Pergunte a qualquer fã de jogos de luta, e eles explicarão por que as versões NTSC são melhores para jogar: mais rápido, mais suave, sem borda preta, etc.

No entanto, o formato PAL tem uma vantagem sobre o NTSC. Como as TVs PAL exibem 50 imagens por segundo em vez de 60, o feixe de elétrons se move mais lentamente. Portanto, o período VBLANK é mais longo em consoles PAL do que em NTSC. Assim, você pode transferir mais dados gráficos a cada quadro em um console PAL em comparação com um modelo NTSC. E esta foi a causa raiz do meu bug. Quando testei o jogo no meu console de infância, rodando em 50hz, os sprites de explosões foram perfeitamente exibidos porque o período VBLANK era longo o suficiente para que todos os dados fossem transferidos corretamente. Mas no BSNES/Higan, um emulador extremamente preciso rodando em 60hz, os sprites foram cortados, pois o VBLANK é mais curto e todos os dados não puderam ser transferidos a tempo. Mas por que o ZSNES, também rodando em 60hz, exibiu os sprites sem problemas?

Bem, simplesmente porque o ZSNES é um emulador mais antigo, com menos precisão na hora de reproduzir todas as limitações técnicas do SNES. Por exemplo, ZSNES não impede que você modifique o conteúdo da memória de vídeo fora do VBLANK - uma grande diferença técnica em comparação com o console real! No final, essa questão me provou como era importante usar emuladores precisos ao desenvolver homebrews, e que nada pode substituir os testes em hardware real e em todas as versões de hardware. Então eu tive que comprar um SNES extra rodando em “60hz” para poder testar o jogo mais completamente!

Tornando-se físico: fabricação de cartuchos

Para mim, um projeto homebrew não é concluído até que os jogadores sejam capazes de colocar um cartucho real do jogo em seu próprio console infantil. Mas como podemos criar um lançamento físico para um console que a única fabricante de cartuchos, a Nintendo, interrompeu a produção há cerca de 20 anos?

A resposta é simples: você mesmo tem que fabricá-los! Para essa parte, fiz uma parceria com um mago da eletrônica chamado Catskull, que já projetava cartuchos para meus jogos de Game Boy. Para este projeto, Catskull projetou um novo SNES PCB do zero. Ele usou apenas novos componentes, ou seja, Flash ROM. Todos os cartuchos são construídos à mão. Aqui está um detalhe do processo de montagem completo com fotos:

1) PCB nu

Comecemos pelo começo: o PCB nu. Catskull têm os PCBs fabricados profissionalmente. Ele os recebe “nus”, como mostra a imagem abaixo:

2) Aplicação de pasta de solda

Para adicionar componentes (ou seja, chips eletrônicos) à PCB, primeiro você precisa aplicar a pasta de solda. É uma “cola” que vai amarrar os chips no PCB. Esta é uma tarefa meticulosa. Catskull usa uma máscara para aplicar a pasta apenas nas áreas necessárias:

Como resultado, a PCB agora tem pasta em toda a parte que hospedará componentes:

3) Assentamento de componentes

Esta é outra tarefa meticulosa. Todos os componentes (chips) devem ser colocados na PCB. Catskull constrói 5 PCBs de cada vez (você verá o porquê na próxima etapa). Aqui estão os PCBs sem componentes:

 

E os mesmos PCBs com todos os chips colocados onde pertencem:

4) Cartuchos de panificação!

A pasta de solda é como um cimento para chips eletrônicos. Quando aplicado, ele ainda está “molhado”, para que você possa reposicionar os cavacos se necessário. Para finalizar os PCBs, você precisa secar a pasta com um forno. Então, tecnicamente, a última etapa do processo de construção é “assar” os cartuchos:

 

5) Piscando a ROM do jogo

Agora que o circuito eletrônico está pronto e funcionando, podemos gravar a ROM do jogo no chip de memória. Para fazer isso, Catskull usa o maravilhoso INLretro Dumper-Programmer da Infinite NES Lives. Para quem não o conhece, Infinite NES Life é outro assistente de eletrônica que criou muitos componentes de hardware para NES e SNES. Ele publicou vários homebrew NES de alto perfil, ele está patrocinando a competição anual NESDev, e ele vende PCBs NES e SNES e carrinhos para pessoas que querem produzir homebrew: http://www.infiniteneslives.com

Tanto Catskull quanto eu gostaríamos de agradecer muito Infinite NES Lives por seu apoio neste projeto . Em primeiro lugar, ele ajudou Catskull a consertar a pinagem do PCB. Então, ele adicionou suporte para Catskull PCB em seu pisca-pisca, para que pudéssemos usá-lo para fabricar nosso jogo. E, por último, mas não menos importante, ele nos forneceu o chip CIC que é necessário para construir cartuchos que podem inicializar em consoles originais! Então, graças ao INL, Catskull agora pode facilmente transformar sua PCB montada à mão em um cartucho de jogo SNES funcional executando Yo-Yo Shuriken:

 

6) Abrigando o PCB na casca

Para completar a montagem do cartucho, o Catskull coloca a PCB dentro de um escudo de cartucho. Como você deve saber, os lançamentos comerciais do SNES dos anos 90 tinham duas variantes de cartuchos. Os japoneses e europeus tinham bordas arredondadas, enquanto os americanos eram um pouco maiores e mais retangulares. Claro, você não pode conectar um cartucho japonês/europeu em um console dos EUA e vice-versa.

Para Yo-Yo Shuriken, queríamos fazer uma única versão mundial. Então, tivemos que usar um shell que pudesse ser conectado às duas variantes de consoles. Felizmente, há pessoas que projetaram “conchas universais” que podem ser conectadas em todos os modelos de consoles. Por exemplo, você pode facilmente encontrar tais conchas na China por um preço baixo. Mas queríamos materiais de maior qualidade. Esperançosamente, Catskull conseguiu encontrar um fornecedor baseado nos EUA que projetou suas próprias conchas SNES universais, feitas com um plástico de alta qualidade. Essas conchas obviamente custam mais, mas quando você as tem em mãos, elas oferecem uma sensação agradável de “resistente”, como os cartuchos originais. Isso justificou o custo extra aos nossos olhos. Além disso, essas conchas de alta qualidade também trazem um toque único ao lançamento do Yo-Yo Shuriken: elas só estão disponíveis na cor vermelha. Embora eu tenha ficado surpreso no início, agora acho muito legal, pois é um aceno aos olhos vermelhos brilhantes dos inúmeros robôs inimigos no jogo! Aqui estão as fotos dessas conchas (frente / verso):

 

É claro que o escudo do cartucho também precisa de uma etiqueta com o nome do jogo aplicado nele, mas veremos essa etapa na próxima seção. Para finalizar esse resumo do processo de montagem da PCB, aqui está um problema que a Catskull enfrentou ao fazer a primeira unidade:

“A única coisa é que as PCBs SNES têm seus componentes na parte traseira (virada para longe de você quando está no console). Então, em todas essas fotos, estou trabalhando na parte traseira do PCB. O primeiro eu acidentalmente conectei para trás no console porque eu não tinha em uma concha, e fritou os componentes na PCB!”

Tornando-se físico: fazendo caixas e manual

Ter uma PCB é apenas o primeiro passo para uma liberação completa do cartucho. Esses PCBs precisam ser alojados em conchas, com uma etiqueta limpa, e embalados em uma bela caixa de papelão com manual. Enquanto Catskull estava ocupado projetando e montando manualmente os cartuchos, eu mesmo desenhei a etiqueta do cartucho, o manual e a caixa de papelão.

Arte da capa

Estou longe de ser artista. Mas um dos prazeres do projeto amador/homebrew é fazer o máximo de coisas possíveis! Então eu abracei totalmente o lado “amador” deste projeto, e eu mesmo decidi desenhar a arte secreta! Comecei rabiscando no papel:

Então eu digitalizei este doodle e eu redesenhá-lo no computador usando um programa de desenho vetorial:

 

Uma vez que a arte secreta foi feita, usei-a para projetar a caixa de papelão, o manual e a etiqueta do cartucho. A versão final de todos esses elementos é impressa profissionalmente nos EUA. Mas durante a fase de design, eu tive que imprimir os protótipos com meus próprios meios!

Manual

Para o manual, usei como referência lançamentos de jogos comerciais dos anos 90, a fim de produzir algo o mais autêntico possível. Mas fizemos algum compromisso, pois queríamos produzir uma versão única para todos os países (sem variantes dos EUA/Japão/Europa como antigamente). O resultado final é uma mistura de estilo de design americano e europeu dos anos 90. Por exemplo, a maioria dos lançamentos dos EUA tinha caixas pretas e manuais, enquanto os europeus usavam um fundo colorido. Aqui estão exemplos de páginas do manual:

  

Caixa

Para a caixa de papelão, usei também um mix de design europeu e americano, com a mesma cor do manual. Tive que imprimir protótipos com meios próprios para ter certeza de que o tamanho estava certo. Para o manual, eu poderia facilmente imprimi-lo em minha própria impressora. Mas para a caixa, usava um tamanho de papel A3. Também tive que imprimir a caixa em papelão para poder construí-la. Então fui a uma gráfica local no meu bairro para imprimir a caixa em uma folha de papelão A3. Depois voltei para casa para construí-lo. Tive que fazer várias versões antes de obter o tamanho exato de um jogo SNES original dos anos 90, mas finalmente consegui. Aqui está uma imagem do último protótipo de caixa:

 

Uma vez que o protótipo da caixa foi concluído e validado por Catskull e eu, encontramos um fornecedor nos EUA que poderia construí-los usando materiais profissionais. Ficamos muito felizes em encontrar um fornecedor que pudesse imprimir as caixas em um material de papelão próximo aos da década de 90. Se você abrir uma caixa Yo-Yo Shuriken, verá que o interior é cinza/marrom, como os lançamentos dos anos 90, e não branco como a maioria das ações de papelão do varejo. Cada caixa é realmente impressa e montada à mão nos EUA pelo nosso fornecedorr (uma operação de dois homens), que as envia já montadas para a Catskull. Catskull então adiciona no manual e no cartucho, para obter a versão física final de Yo-Yo Shuriken que você pode ver aqui:

Palavras finais

No final, com todos esses passos, fazer Yo-Yo Shuriken levou quase 2 anos de trabalho duro! Espero que tenham gostado de ler este artigo. Foi uma jornada e tanto para mim, e estou feliz em compartilhá-lo online com a esperança de que ele inspire e motive outros desenvolvedores a fazer novos jogos SNES!

Se você quiser jogar Yo-Yo Shuriken em seu próprio console, ou simplesmente apoiar meu trabalho, você pode comprar o belo lançamento de cartucho encaixotado diretamente da Catskul Games:
https://catskullgames.com/yo-yo-shuriken

Se você preferir jogá-lo em emuladores, você pode comprar a versão ROM a partir daqui:
https://drludos.itch.io/yo-yo-shuriken

Se você gosta do meu trabalho e pode pagar, você pode me apoiar financeiramente no Patreon. Meus jogos geralmente acabam sendo lançados como freeware online, enquanto alguns deles também são vendidos em cartuchos reais. Ao me apoiar no Patreon, você também terá um acesso exclusivo às versões beta dos meus jogos, e até mesmo aos vários protótipos que crio (incluindo projetos cancelados):
https://www.patreon.com/drludos

Se você simplesmente quiser ser notificado sobre meus últimos lançamentos de jogos e artigos, você pode se inscrever no meu boletim informativo (eu só o uso para anunciar lançamentos de jogos e artigos, exceto cerca de um e-mail a cada 1-2 meses no máximo).


Artigo Original