8.0 KiB
< Voltar | Sumário | Adiante >
🎨 Periférico GFX (Sistema Gráfico)
1. Visão Geral
O periférico GFX é responsável pela geração de imagem no PROMETEU.
Ele modela um hardware gráfico simples, inspirado em consoles clássicos (SNES, CPS-2, Neo-Geo), priorizando:
- determinismo
- baixo custo computacional
- didática
- portabilidade
O GFX não é uma GPU moderna.
Ele é um dispositivo explícito, baseado em:
- framebuffer
- tilemaps
- banks de tiles
- sprites por prioridade
- composição por ordem de desenho
2. Resolução e Framebuffer
Resolução base
- 320 × 180 pixels
- proporção próxima de 16:9
- escalável pelo host (nearest-neighbor)
Formato de pixel
- RGB565
- 5 bits Red
- 6 bits Green
- 5 bits Blue
- sem canal alpha
Transparência é feita por color key.
3. Double Buffering
O GFX mantém dois buffers:
- Back Buffer — onde o frame é construído
- Front Buffer — onde o frame é exibido
Fluxo por frame:
- O sistema desenha no back buffer
- Chama
present() - Buffers são trocados
- O host exibe o front buffer
Isso garante:
- ausência de tearing
- sincronização clara por frame
- comportamento determinístico
4. Estrutura Gráfica do PROMETEU
O mundo gráfico é composto por:
- Até 16 Tile Banks
- 4 Tile Layers (scrolláveis)
- 1 HUD Layer (fixa, sempre por cima)
- Sprites com prioridade entre layers
4.1 Tile Banks
- Existem até 16 banks
- Cada bank tem tamanho fixo de tile:
- 8×8, 16×16 ou 32×32
- Um bank é uma biblioteca de gráficos:
- ambiente
- personagens
- UI
- efeitos
4.2 Layers
- Existem:
- 4 Tile Layers
- 1 HUD Layer
- Cada layer aponta para um único bank
- Sprites podem usar qualquer bank
- HUD:
- não scrolla
- prioridade máxima
- geralmente usa tiles 8×8
5. Modelo Interno de uma Game Layer
Uma Game Layer não é um bitmap de pixels.
Ela é composta por:
- Um Tilemap lógico (índices de tiles)
- Um Cache de Borda (janela de tiles visíveis)
- Um Offset de Scroll
Estrutura:
bank_idtile_sizetilemap(matriz grande)scroll_x,scroll_ycache_origin_x,cache_origin_ycache_tiles[w][h]
6. Tilemap Lógico
O tilemap representa o mundo:
Cada célula contém:
tile_idflip_xflip_ypriority(opcional)palette_id(opcional)
O tilemap pode ser muito maior que a tela.
7. Cache de Borda (Tile Cache)
O cache é uma janela de tiles ao redor da câmera.
Exemplo:
- Tela: 320×180
- Tiles 16×16 → 20×12 visíveis
- Cache: 22×14 (margem de 1 tile)
Ele guarda os tiles já resolvidos a partir do tilemap.
8. Atualização do Cache
A cada frame:
- Calcular:
tile_x = scroll_x / tile_sizetile_y = scroll_y / tile_sizeoffset_x = scroll_x % tile_sizeoffset_y = scroll_y % tile_size
- Se
tile_xmudou:
- Avança
cache_origin_x - Recarrega apenas a nova coluna
- Se
tile_ymudou:
- Avança
cache_origin_y - Recarrega apenas a nova linha
Somente uma linha e/ou coluna é atualizada por frame.
9. Cache como Ring Buffer
O cache é circular:
- Não move dados fisicamente
- Apenas move índices lógicos
Acesso:
real_x = (cache_origin_x + logical_x) % cache_widthreal_y = (cache_origin_y + logical_y) % cache_height
10. Projeção para o Back Buffer
Para cada frame:
- Para cada Game Layer, em ordem:
- Rasterizar tiles visíveis do cache
- Aplicar scroll, flip e transparência
- Escrever no back buffer
- Desenhar sprites:
- Com prioridade entre layers
- Ordem de desenho define profundidade
- Desenhar HUD layer por último
11. Ordem de Desenho e Prioridade
- Não existe Z-buffer
- Não existe sorting automático
- Quem desenha depois fica na frente
Ordem base:
- Game Layer 0
- Game Layer 1
- Game Layer 2
- Game Layer 3
- Sprites (por prioridade entre layers)
- HUD Layer
12. Transparência (Color Key)
- Um valor RGB565 é reservado como TRANSPARENT_KEY
- Pixels com essa cor não são desenhados
if src == TRANSPARENT_KEY:
skip
else:
draw
13. Color Math (Blending Discreto)
Inspirado no SNES.
Modos oficiais:
BLEND_NONEBLEND_HALFBLEND_HALF_PLUSBLEND_HALF_MINUSBLEND_FULL
Sem alpha contínuo.
Sem blending arbitrário.
Tudo é:
- inteiro
- barato
- determinístico
14. Onde o Blend é Aplicado
- O blend ocorre durante o desenho
- O resultado vai direto para o back buffer
- Não existe composição posterior automática
15. O que o GFX NÃO suporta
Por design:
- Alpha contínuo
- RGBA framebuffer
- Shader
- Pipeline moderno de GPU
- HDR
- Gamma correction
16. Regra de Performance
- Layers:
- só atualizam borda ao cruzar tile
- nunca redesenham mundo inteiro
- Rasterização:
- sempre por frame, só área visível
- Sprites:
- sempre redesenhados por frame
17. PostFX Especial — Fade (Scene e HUD)
O PROMETEU suporta fade gradual como um PostFX especial, com dois controles independentes:
- Scene Fade: afeta toda a cena (Tile Layers 0–3 + Sprites)
- HUD Fade: afeta apenas o HUD Layer (sempre composto por último)
O fade é implementado sem alpha contínuo por pixel e sem floats. Ele usa um nível inteiro discreto (0..31), que na prática produz um resultado visual “quase contínuo” em 320×180 pixel art.
17.1 Representação do Fade
Cada fade é representado por:
fade_level: u8no intervalo [0..31]0→ totalmente substituído pela cor de fade31→ totalmente visível (sem fade)
fade_color: RGB565- cor para a qual a imagem será misturada
Registradores:
SCENE_FADE_LEVEL(0..31)SCENE_FADE_COLOR(RGB565)HUD_FADE_LEVEL(0..31)HUD_FADE_COLOR(RGB565)
Casos comuns:
- Fade-out:
fade_color = BLACK - Flash/teleporte:
fade_color = WHITE - Efeitos especiais: qualquer cor RGB565
17.2 Operação de Fade (Mistura com Cor Arbitrária)
Para cada pixel RGB565 src e cor de fade fc, o pixel final dst é calculado por canal.
- Extrair componentes:
src_r5,src_g6,src_b5fc_r5,fc_g6,fc_b5
- Aplicar mistura inteira:
src_weight = fade_level // 0..31
fc_weight = 31 - fade_level
r5 = (src_r5 * src_weight + fc_r5 * fc_weight) / 31
g6 = (src_g6 * src_weight + fc_g6 * fc_weight) / 31
b5 = (src_b5 * src_weight + fc_b5 * fc_weight) / 31
src_r5,src_g6,src_b5fc_r5,fc_g6,fc_b5
- Reempacotar:
dst = pack_rgb565(r5, g6, b5)
Observações:
- Operação determinística
- Somente inteiros
- Pode ser otimizada via LUT
17.3 Ordem de Aplicação no Frame
A composição do frame segue esta ordem:
- Rasterizar Tile Layers 0–3 → Back Buffer
- Rasterizar Sprites conforme prioridade
- (Opcional) Pipeline extra (Emission/Light/Glow etc.)
- Aplicar Scene Fade usando:
SCENE_FADE_LEVELSCENE_FADE_COLOR
- Rasterizar HUD Layer
- Aplicar HUD Fade usando:
HUD_FADE_LEVELHUD_FADE_COLOR
present()
Regras:
- Scene Fade nunca afeta HUD
- HUD Fade nunca afeta a cena
17.4 Casos de Uso
-
Troca de HUD:
- diminuir
HUD_FADE_LEVELaté 0 - trocar HUD/tilemap
- aumentar
HUD_FADE_LEVELaté 31
- diminuir
-
Troca de área:
- diminuir
SCENE_FADE_LEVELaté 0 - trocar cenário
- aumentar
SCENE_FADE_LEVELaté 31
- diminuir
-
Flash / dano / teleporte:
- usar
fade_color = WHITEou outra cor temática
- usar
18. Resumo
O GFX do PROMETEU é simples por escolha, não por limitação.
- Framebuffer RGB565 com double buffer
- Color key para transparência
- Blending discreto estilo SNES
- Até 16 tile banks
- 4 Tile Layers + 1 HUD
- Layer = tilemap + cache + scroll
- Projeção rasterizada por frame
- Profundidade definida por ordem de desenho