Como dispositivos como o Game Boy Advance atingem sua taxa de quadros?

31

Projetei meu próprio dispositivo portátil de jogo baseado em um microcontrolador AVR e em um pequeno monitor OLED.

Comecei com uma tela monocromática de 128x64 pixels e posso desenhar confortavelmente mais de 60 quadros por segundo.

Recentemente, reformulei-o para usar um RGB OLED de 128x128 pixels sem realmente pensar muito apenas para descobrir que só conseguia atingir cerca de 4 FPS. Após algumas reflexões e cuidadosas refatorações, posso chegar a ~ 12fps se não me importo muito em fazer outra coisa!

Minha pergunta é: como um dispositivo como o GBA (Game Boy Advance) atingiu uma taxa de quadros de quase 60fps? Pensei em ter um 'processador gráfico' separado, mas percebi que ainda estaria com um gargalo ao transferir os dados da tela para isso.

Também me perguntei sobre o uso da interface paralela vestigial de 8 bits que a maioria dessas telas costuma ter, o que pode gerar uma velocidade de 8x, exceto que os MCUs modernos não tendem a ter interfaces paralelas de hardware, como fazem para serial e bit- bater provavelmente consumirá muito do ganho de velocidade.

Que outras opções existem?

Atualmente, estou usando um ATmega1284P conectado a um controlador OLED SSD1306 via USART-SPI. Essa é a versão monocromática.

A tela colorida era um SSD1351, não originalmente conectado ao hardware SPI. Eu não estava convencido de que isso faria diferença suficiente , é muito lento no geral

Sei que posso obter MCUs mais rápidos, mas quero saber que outras opções posso explorar - o processador GBA é muito mais lento que o meu 1284!

MalphasWats
fonte
6
"Eu ainda estaria com um gargalo ao transferir os dados da tela para isso". O DSI possui quatro faixas de até 1,2 Gbits / s. Deixo o resto dos cálculos para você.
Oldfart
1
Assim como qualquer gráfico em qualquer dispositivo de videogame, há memória que lida com gráficos. De acordo com este site, há um local de endereço para gráficos, som etc. As instruções seriam armazenadas lá. Supondo que não haja muitos dados que criariam conflitos com o tempo de desempenho, eles executariam essas instruções para carregar os dados gráficos com facilidade.
KingDuken
5
comprar a tela sem o controlador nele e fazer o seu próprio controlador
old_timer
4
@immibis: Quase certamente algum controlador terrível baseado em I2C ou SPI. Coisas hobbyistas estão cheias de coisas lentas e caras demais, quando você pode obter uma tela de iPhone de mais de 400 dpi por US $ 20 por causa de economias de escala.
R ..
6
@R .. Eu só quero ressaltar que a razão para esses controladores amadores é que eles podem interagir com quase qualquer processador, já que você faz parecer que eles são inúteis. Você não seria capaz de fazer interface com a tela do iPhone com facilidade, se é que o faria. Provavelmente, ele se conecta a um processador gráfico dedicado e talvez personalizado.
user253751

Respostas:

64

Outras respostas cobrem sua pergunta muito bem em um nível abstrato (hardware), mas, tendo uma experiência real com o GBA em particular, achei que uma explicação mais detalhada pode valer a pena.

O GBA tinha muitos modos e configurações de desenho que podiam ser usados ​​para controlar como o processador gráfico interpretava a RAM de vídeo, mas uma coisa era inevitável: a taxa de quadros. O processador gráfico estava desenhando na tela em um loop constante quase (mais sobre isso abaixo). (Este é provavelmente o bit mais relevante para sua pergunta.)

Ele traçaria uma linha de cada vez, fazendo um intervalo muito curto entre cada uma. Depois de desenhar a última linha do quadro, uma pausa seria aproximadamente igual ao tempo necessário para desenhar 30 linhas. Então comece de novo. O tempo de cada linha e o tempo de cada quadro foram todos pré-determinados e gravados em pedra. De várias maneiras, o processador gráfico era realmente o mestre desse sistema e você precisava escrever seus jogos em torno do comportamento dele, porque continuaria fazendo o que fazia, estando você pronto ou não.

Aproximadamente 75-80% das vezes estava ativamente pressionando a tela. Quais taxas de quadros você poderia obter se estivesse fazendo o mesmo?

Também em 80% do tempo a CPU tinha que processar a entrada do usuário, calcular o estado do jogo e carregar sprites / tiles em áreas da VRAM que estavam fora da tela (ou pelo menos não incluídas na linha atual que está sendo desenhada).

Os 20% entre os quadros, era tudo o que a CPU precisava ajustar as configurações de vídeo ou RAM que impactariam todo o próximo quadro.

No final de cada linha, o processador gráfico envia uma interrupção de sincronização de linha para a CPU. Essa interrupção pode ser usada para ajustar as configurações em alguns sprites ou em algumas camadas de fundo (é assim que você pode obter um efeito como um refletor cônico, alterando o tamanho e a localização de uma das máscaras retangulares entre cada linha desenhada. No que diz respeito ao hardware, todas essas regiões são retangulares.). Você precisa ter cuidado para manter essas atualizações pequenas e concluir antes que o processador gráfico comece a desenhar a próxima linha ou obtenha resultados feios. Qualquer tempo gasto no processamento dessas interrupções também reduz os 80% do tempo de processamento da CPU ...

Para jogos que tiraram o máximo proveito deste sistema, nem a CPU nem o processador gráfico deram uma pausa real; cada um estava perseguindo o outro em volta do loop, atualizando o que o outro não estava vendo no momento.

Mr.Mindor
fonte
5
Bem-vindo e bem colocado.
Mindwin
2
Alguns sistemas "mais recentes", como o Nintendo DS, contornaram a limitação fixa da taxa de quadros, adicionando o registro VCOUNT para atrasar o próximo quadro por um período configurável (geralmente para ajudar na sincronização de jogos multiplayer).
forest
21

O principal recurso de todos os consoles de jogos que os distinguiam dos PCs antigos e praticamente de todos os computadores domésticos (1) eram sprites de hardware .

O guia de programação GBA vinculado mostra como eles funcionam do ponto de vista do processador principal. Os bitmaps que representam jogador, plano de fundo, inimigos etc. são carregados em uma área da memória. Outra área de memória especifica a localização dos sprites. Portanto, em vez de ter que reescrever toda a RAM de vídeo em todos os quadros, o que requer muitas instruções, o processador precisa apenas atualizar a localização dos sprites.

O processador de vídeo pode trabalhar pixel por pixel para determinar qual sprite desenhar nesse ponto.

No entanto, isso requer RAM de porta dupla compartilhada entre os dois, e acho que no GBA o processador de vídeo está no mesmo chip que o ARM principal e o processador Z80 secundário.

(1) Exceção notável: Amiga

pjc50
fonte
Apenas um detalhe - os primeiros jogos de arcade tinham sprites em uma ROM associada ao processador gráfico, não uma RAM de porta dupla. Não tenho idéia se esse também foi o caso dos primeiros consoles, embora certamente pudesse ter sido feito dessa maneira.
21418 TimWescott
@ TimWescott, o GBA tinha vários modos de desenho e não tenho experiência com a maioria deles, então isso pode não ser universalmente verdadeiro, mas não acho que nenhum desses modos tenha acesso direto às ROMs (no cartucho): normalmente todos os os dados lado a lado / sprite / paleta tiveram que ser transferidos da ROM para a memória de vídeo e o processador gráfico trabalhou nele a partir daí.
Mr.Mindor
@ Mr.Mindor Desculpe se eu não estava claro - não estou fingindo ter conhecimento sobre como o GB ou GBA fizeram isso. Eu estava apenas comentando sobre os primeiros jogos de arcade da Nintendo no final dos anos 70 e início dos anos 80, que todos nós imaginávamos como eles fizeram isso.
TimWescott
@ TimWescott: Eu acho que o mesmo aconteceu com o NES, embora a ROM em questão estivesse localizada nos Game Paks.
Supercat
19

"Minha pergunta é: como um dispositivo como o GBA atingiu uma taxa de quadros de quase 60fps?"

Para responder apenas à pergunta, eles fizeram isso com um processador gráfico. Tenho certeza de que o Game Boy usou gráficos de sprite. Em um nível superior, isso significa que o processador gráfico carrega coisas como a imagem de um plano de fundo, uma imagem de Mario e uma imagem de Princess Peach, etc. Em seguida, o processador principal emite comandos como "mostrar o deslocamento de fundo dessa muito em x e y, sobreponha a imagem 3 do Mario nesta posição x, y "etc. etc. Portanto, o processador principal não se preocupa absolutamente positivamente com o desenho de cada pixel, e o processador gráfico não se preocupa positivamente em calcular o estado do jogos. Cada um é otimizado para o que precisa fazer, e o resultado é um bom jogo de vídeo sem usar muito poder de computação.

TimWescott
fonte
7
Chamar isso de "processador gráfico" exagera o que faz, sugerindo que é algum tipo de CPU própria. É apenas um controlador de vídeo, que é basicamente um tipo complicado de sequenciador. Ao contar pixels horizontais e verticais, ele busca dados de título e / ou sprite, coloca-os nos registros de deslocamento e combina a saída dos registros de deslocamento em um pixel de saída. Não é capaz de executar um programa como um processador gráfico "GPU" real.
Ross Ridge
14

O GBA tinha um processador bastante lento. O ARM7 é muito bom; eles apenas correram devagar e deram quase nenhum recurso.

Há uma razão pela qual muitos jogos da Nintendo naquele momento e antes eram side-scrollers. HARDWARE. Tudo é feito em hardware. Você tinha várias camadas de blocos, mais um ou mais sprites, e o hardware fez todo o trabalho para extrair pixels dessas tabelas e direcionar a exibição.

Você constrói o bloco configurado na frente e, em seguida, tinha uma memória pequena que era um mapa de bloco. Deseja que o ladrilho inferior esquerdo seja o ladrilho 7? Você coloca um 7 nesse local da memória. Deseja que o próximo bloco seja o bloco 19? No conjunto de blocos, você coloca 19 lá e assim por diante para cada camada que você ativou. Para o sprite, basta definir o endereço x / y. Você também pode fazer a escala e a rotação definindo alguns registros e o hardware cuida do resto.

O modo 7, se bem me lembro, era um modo de pixel, mas era como uma placa de vídeo tradicional em que você coloca bytes que cobrem a cor de um pixel e o hardware cuida da atualização do vídeo. Eu acho que você pode jogar pingue-pongue ou, pelo menos, quando tiver um novo quadro, pode jogá-lo, mas não me lembro direito. Novamente, o processador estava com um clock insuficiente para aquele dia e idade e não tinha muitos recursos rápidos. Então, enquanto alguns jogos eram no modo 7, muitos eram side-scrollers baseados em blocos ...

Se você deseja uma solução com alta taxa de quadros, é necessário projetá-la. Você não pode simplesmente pegar qualquer tela antiga que encontrar e conversar com ela via SPI ou I²C ou algo assim. Coloque pelo menos um buffer de quadro na frente dele, idealmente dois, e tenha controle de linha e coluna, se possível, sobre essa exibição.

Alguns monitores que eu suspeito que você está comprando têm um controlador com o qual você está realmente conversando. Se você quiser um desempenho do tipo GBA / console, crie / implemente o controlador. Ou você compra / constrói com um chip de GPU / vídeo / blob lógico e usa HDMI ou outra interface comum em um monitor de estoque.

Só porque uma bicicleta tem pneus, uma corrente e engrenagens não significa que ela pode ir tão rápido quanto uma motocicleta. Você precisa projetar o sistema para atender às suas necessidades de desempenho, de ponta a ponta. Você pode colocar a roda da bicicleta naquela motocicleta, mas ela não funcionará como desejado; todos os componentes precisam fazer parte do design geral.

Asteróides também funcionavam dessa maneira; precisava apenas de um 6502. Os gráficos vetoriais foram feitos com lógica separada; o 6502 enviou uma minúscula seqüência de dados ao controlador de gráficos vetoriais, que usava uma ROM e esses dados para fazer a plotagem xy do feixe ez, ligar / desligar ... o processador que computa o jogo. Hoje, é claro, o vídeo é tratado por centenas, senão milhares, de processadores separados do processador principal ...

old_timer
fonte
Eu juro que me lembro do mode7 sendo enganado pelo marketing como uma resposta ao "hyper mode" da Sega ou algo assim ... talvez "Super FX?" en.wikipedia.org/wiki/Mode_7
Caleb Jay
coranac.com/tonc/text/bitmaps.htm#sec-modes Talvez eu tenha me lembrado errado Talvez esteja pensando no modo 5 ou em um dos modos de bitmap, existem alguns modos de mosaico com modos ou modos de sprites e bitmap / framebuffer . talvez haja um 7. não sabia sobre o que você vinculou, mas é bom saber.
22618 Old_timer
hmm lendo mais no modo 7 e não é apenas um modo. De qualquer forma, o GBA possui modos de bloco e bitmap mais lentos, pois você é responsável por cada pixel em que os modos de bloco de um byte no mapa de blocos produzem muitos pixels. Eles também alavancaram o tamanho dos barramentos (largura) e a velocidade da memória, além de um cache de pipeline de rom para ajudar a obter coisas (instruções) da rom um pouco mais rápido. Mas desde o primeiro dia, você estava lutando para que o software fosse executado a uma taxa decente e, felizmente, a lógica cuidou da maior parte do trabalho de vídeo.
old_timer
se você observar os monitores que está comprando, que possuem essas interfaces paralelas de 8 bits ou 4 bits ou spi ou i2c, estão no seu caminho para o desempenho, deseje a exibição bruta sem esses controladores e poderá controlar como a exibição é gerenciada , crie um framebuffer ou dois para poder executar ping / pong e uma interface rápida do seu cpu para o framebuffer. supondo que você comece com uma exibição rápida o suficiente em primeiro lugar.
old_timer
7

como um dispositivo como o GBA atingiu uma taxa de quadros de quase 60fps?

Hardware.

Possui memória gráfica, que pode ou não compartilhar o mesmo barramento que a memória de programa / dados ... mas o mais importante é que ele possui um processador gráfico que lê a memória 60 vezes por segundo e envia os dados para o LCD usando um interface otimizada, projetada para fazer isso com eficiência.

Você pode fazer o mesmo com qualquer microcontrolador moderno equipado com um periférico de "interface LCD", por exemplo, o LPC4330, embora isso possa ser um exagero. Claro que você precisará de um painel LCD compatível.

Com os modernos microcontroladores rápidos (por exemplo, ARM e AVR) e uma tela tão pequena, você provavelmente não precisará de sprites ou de um piscar de olhos para acelerar as operações gráficas. Com um AVR de 8 bits, pode ser lento.

Mas não importa o processador, bater com força na interface do monitor será uma droga.

Acredito que o Atari 2600 tenha usado o processador de bits para enviar a imagem para a TV. Isso é um pouco obsoleto.

peufeu
fonte
Até o 2600 tinha sprites de hardware, embora um número muito limitado (dois jogadores e duas balas, eu acho)
pjc50
2
@ pjc50, o Atari 2600 espécie de sprites de hardware tiveram. Como todas as outras partes do subsistema gráfico, eles eram objetos unidimensionais. Se o programador quisesse algo diferente de um conjunto de linhas verticais, o programa precisava atualizar os sprites após cada linha ser desenhada na tela.
Mark
1
@ Mark: O 2600 definitivamente tinha sprites de hardware. O hardware controlava apenas o posicionamento horizontal, mas os sprites no 2600 permitiram que os jogos produzissem jogos muito mais coloridos do que qualquer um de seus concorrentes.
Supercat