Gráficos Avançados e Definição de Tiles
O MSX é uma máquina de tiles. Dominar a criação dinâmica de padrões é o segredo para jogos fluidos e interfaces ricas.
1. O Conceito de Tile em CrossScript
Antes de mergulhar na sintaxe, vale lembrar que você não precisa desenhar tiles digitando bytes. A IDE tem dois editores dedicados que geram esses valores para você:
- Tile Editor — desenha um único padrão 8×8 (pixel a pixel) e copia o
TILECREATEpronto. - Screen Editor — monta cenários inteiros (32×24) e exporta o array para
TILEMAPLOAD.
Ainda assim, entender a estrutura por baixo desses editores é essencial — é o que este capítulo cobre.
Diferente do BASIC tradicional onde usamos strings complexas para definir caracteres, no CrossScript tratamos o hardware como ele é: um conjunto de 8 bytes que definem uma matriz 8x8 de pixels.
Cada bit em um byte representa um pixel na tela: • Bit em 1: Cor de frente (Foreground). • Bit em 0: Cor de fundo (Background).
2. O Comando TILECREATE
O comando TILECREATE permite definir o padrão visual de um tile diretamente no código, linha por linha. É a forma mais legível de desenhar caracteres customizados.
Sintaxe:
TILECREATE index, L1, L2, L3, L4, L5, L6, L7, L8
• index: O número do tile na VRAM (0 a 255). • L1 a L8: Valores numéricos (0-255 ou hexadecimais) representando cada linha horizontal do tile.
DIGITE E VEJA
Criando um Personagem
Vamos criar um pequeno "herói" e colocá-lo na tela.
' Define o padrão do tile 128 (um pequeno boneco)
TILECREATE 128, $3C, $3C, $18, $3C, $7E, $18, $24, $24
SCREEN 1
COLOR 15, 1, 1
CLS
' Desenha o tile 128 na posição (10, 10)
TILE 10, 10, 128
3. O Comando TILEMAPLOAD
Quando precisamos carregar muitos tiles de uma vez (como um conjunto completo de fontes ou um cenário), usar TILECREATE para cada um seria exaustivo. Para isso, usamos o TILEMAPLOAD.
Este comando lê dados de um array (vetor) e os injeta na memória de vídeo de forma otimizada.
Sintaxe:
TILEMAPLOAD inicio, quantidade, array_origem
⌨ DIGITE E VEJA
Carregando um Conjunto de Blocos
Neste exemplo, definimos dados para 2 tiles em um array e os carregamos de uma vez.
USES SCREEN 1, TILES
SCREEN 1
CLS
DIM blocos(15) AS BYTE
DIM i AS BYTE
' Dados do Tile 1 (Bloco Sólido)
blocos(0) = $FF : blocos(1) = $FF : blocos(2) = $FF : blocos(3) = $FF
blocos(4) = $FF : blocos(5) = $FF : blocos(6) = $FF : blocos(7) = $FF
' Dados do Tile 2 (Bloco de Tijolos)
blocos(8) = $FF : blocos(9) = $80 : blocos(10) = $80 : blocos(11) = $FF
blocos(12) = $01 : blocos(13) = $01 : blocos(14) = $01 : blocos(15) = $FF
' Carrega os 2 tiles na VRAM a partir do índice 128
TILEMAPLOAD 128, 2, blocos
' Desenha uma pequena parede na primeira linha
FOR i = 0 TO 5
TILE i, 0, 129
NEXT i
⚠ ATENÇÃO — ORDEM IMPORTA
Sempre defina tiles depois de SCREEN e CLS. O comando SCREEN recarrega a fonte padrão do BIOS na tabela de padrões da VRAM, sobrescrevendo qualquer TILECREATE/TILEMAPLOAD feito antes. Se você chamar TILEMAPLOAD antes do SCREEN, seus tiles serão apagados e você verá apenas os glifos da fonte original.
4. Loops e Atualização Parcial
Uma técnica poderosa é usar loops para gerar padrões matemáticos ou atualizar partes específicas do cenário.
🧪 EXPERIMENTE
Animação de Barra de Progresso
Podemos "redesenhar" um tile em tempo real para criar efeitos.
USES SCREEN 1, TILES
SCREEN 1
CLS
DIM nivel AS BYTE
TILE 15, 10, 150 ' Posiciona o tile 150 no centro
FOR nivel = 0 TO 7
' Cria um efeito de preenchimento de baixo para cima
TILECREATE 150, 0, 0, 0, 0, 0, 0, 0, $FF
' (Aqui você variaria os bytes para animar)
' Aguarda um pouco (exemplo conceitual)
NEXT nivel
DICA
Organização de Dados
Ao usar TILEMAPLOAD, organize seu array em múltiplos de 8. O CrossScript calculará automaticamente os offsets para você, garantindo a maior velocidade de transferência para a VRAM.
5. Diferença entre TILE e TILECREATE
- TILECREATE: Altera a aparência de um número. (Ex: Faz o número 65 parecer uma árvore).
- TILE: Coloca esse número em uma posição da tela. (Ex: Desenha a "árvore" na coordenada X, Y).
✓ Otimização: Sempre defina seus padrões de tiles no início do programa ou durante transições de fase para evitar flicker na tela.
6. Referência Rápida de Comandos
| Comando | Sintaxe | Parâmetros | Caso de Uso |
|---|---|---|---|
| TILECREATE | TILECREATE idx, L1..L8 | idx: 0-255<br>L1..L8: 8 bytes | Definir visual de um único caractere ou sprite. |
| TILECOLOR | TILECOLOR grupo, frente, fundo | grupo: MSX1 por grupo; em SCREEN 5 é ignorado<br>frente/fundo: cores 0-15 | Define as cores usadas no próximo TILECREATE. |
| TILETRANSPARENT | TILETRANSPARENT ON/OFF | ON: cor 0 recorta o tile<br>OFF: cópia opaca | Objetos em SCREEN 5 com contorno estilo sprite. |
| TILEMAPLOAD | TILEMAPLOAD ini, qnt, arr | ini: Início VRAM<br>qnt: Total tiles<br>arr: Array origem | Carregamento em massa de fontes ou cenários (tilesets). |
Resumo de Parâmetros
• idx / ini: Endereço lógico na tabela de padrões da VRAM.
• L1..L8: Cada valor representa uma linha de 8 pixels (MSB na esquerda).
• arr: Deve ser um ARRAY OF BYTE com tamanho mínimo de qnt * 8.
7. Além do MSX 1: SCREEN 2 e MSX 2.0
Uma dúvida comum é se esses conceitos se aplicam a outros modos de tela. A resposta é sim, mas com evoluções interessantes sobre como a VRAM é gerenciada.
SCREEN 2: O Poder das Três Zonas
No modo SCREEN 2, o MSX divide a VRAM em três áreas de 256 padrões cada:
- Zona 0 (Superior): Linhas 0 a 7.
- Zona 1 (Central): Linhas 8 a 15.
- Zona 2 (Inferior): Linhas 16 a 23.
O TILEMAPLOAD permite carregar até os 768 padrões de uma vez (índices 0-767).
⌨ EXEMPLO COMPLETO: SCREEN 2
USES SCREEN 2, TILES
SCREEN 2
CLS
DIM dados(7) AS BYTE
DIM i AS BYTE
' Padrão 65 na Zona 0 (Superior)
TILECREATE 65, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
' Padrão 65 na Zona 1 (Central) via TILEMAPLOAD (65 + 256 = 321)
FOR i = 0 TO 7
dados(i) = $AA
NEXT i
TILEMAPLOAD 321, 1, dados
TILE 0, 0, 65 ' Bloco sólido no topo
TILE 0, 10, 65 ' Padrão listrado no meio
SCREEN 5: Tiles Coloridos por Blitter (MSX 2)
Em SCREEN 5, que é um modo bitmap, o MSX 2 não tem uma tabela de nomes de tiles como o SCREEN 1 ou o SCREEN 2. O CrossScript resolve isso criando um cache oculto de tiles na VRAM e usando o VDP Command Processor do V9938 para copiar cada bloco 8×8 para a tela.
Na prática, para você, a ideia continua familiar:
TILECOLORescolhe a cor de frente e a cor de fundo do próximo tile.TILECREATEdesenha o padrão 8×8 no cache oculto.TILEcopia esse padrão para a tela, em coordenadas de tile: coluna 0..31, linha 0..25.TILETRANSPARENT ON/OFFdecide se a cor 0 será tratada como recorte.
Tamanho dos Dados por Tile (8x8):
- SCREEN 5: 32 bytes (4 bits/pixel)
- SCREEN 6: 16 bytes (2 bits/pixel)
- SCREEN 7/8: 64 bytes (8 bits/pixel)
DICA
Transparência em SCREEN 5
Use TILETRANSPARENT OFF para fundos sólidos, como céu, chão e parede. É o modo mais rápido. Use TILETRANSPARENT ON antes de criar árvores, pedras, inimigos ou objetos com contorno irregular. Nesse modo, pixels de cor 0 no tile não apagam o fundo: eles deixam aparecer o que já estava atrás.
⌨ DIGITE E VEJA
Programa 14.1 — Montanhas e árvores recortadas em SCREEN 5
Digite o programa inteiro: a primeira parte cria os tiles e a segunda desenha o cenário. Rode numa máquina MSX 2 ou superior (a IDE troca a máquina sozinha ao apertar RUN; no emulador avulso, escolha MSX 2).
' Cenario com TILES em SCREEN 5 (MSX 2)
' O fundo usa tiles opacos. As arvores usam cor 0 transparente.
USES SCREEN 5, TILES
SCREEN 5
COLOR 15, 1, 1
CLS
DIM col AS BYTE
DIM row AS BYTE
' --- Tiles opacos: fundos e montanhas ---
TILETRANSPARENT OFF
' Tile 1: ceu azul claro (padrao vazio = so cor de fundo)
TILECOLOR 0, 7, 7
TILECREATE 1, $00,$00,$00,$00,$00,$00,$00,$00
' Tile 2: topo da montanha (branca sobre o ceu)
TILECOLOR 0, 15, 7
TILECREATE 2, $01,$03,$07,$0F,$1F,$3F,$7F,$FF
' Tile 3: corpo da montanha
TILECREATE 3, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
' Tile 4: grama
TILECOLOR 0, 12, 12
TILECREATE 4, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
' --- Tiles transparentes: objetos recortados ---
TILETRANSPARENT ON
' Tile 5: tronco. A cor 0 fica vazada.
TILECOLOR 0, 9, 0
TILECREATE 5, $18,$18,$18,$18,$18,$18,$18,$18
' Tile 6: copa. A cor 0 deixa a montanha aparecer.
TILECOLOR 0, 2, 0
TILECREATE 6, $18,$3C,$7E,$FF,$FF,$7E,$3C,$18
' --- Desenhando o cenario ---
' Ceu
FOR row = 0 TO 15
FOR col = 0 TO 31
TILE col, row, 1
NEXT col
NEXT row
' Montanhas
FOR col = 0 TO 31
TILE col, 16, 2
TILE col, 17, 3
TILE col, 18, 3
NEXT col
' Chao
FOR col = 0 TO 31
TILE col, 19, 4
TILE col, 20, 4
NEXT col
' Arvores: copa e tronco recortados sobre a montanha
TILE 5, 17, 6
TILE 5, 18, 5
TILE 24, 17, 6
TILE 24, 18, 5
Fim: GOTO Fim
TELA ESPERADA
Céu azul claro, montanhas brancas, grama verde e duas árvores
As árvores não aparecem dentro de um quadrado colorido. O contorno fica recortado, como se o objeto fosse um sprite, porque os pixels de cor 0 não são copiados pelo blitter.
⚠ ATENÇÃO
Em SCREEN 5, o TILE usa coordenadas de tile, não pixels: TILE 10, 12, 6 desenha na coluna 10 e linha 12, ou seja, aproximadamente no pixel X=80, Y=96. Para este primeiro suporte, prefira TILECREATE com 8 bytes de padrão; TILEMAPLOAD continua sendo a melhor opção para carregamento em massa nos modos clássicos de tile do MSX 1.
8. Limites e Capacidades de Hardware
| Modo | Limite de Padrões | Profundidade de Cor | Comportamento VRAM |
|---|---|---|---|
| SCREEN 1 | 256 únicos | 2 cores por bloco 8x8 | Tabela de Nomes + Padrões fixa. |
| SCREEN 2 | 768 únicos | 2 cores por LINHA 8x1 | 3 tabelas de padrões separadas. |
| SCREEN 5 | 256 (Cache) | 16 cores por pixel | Armazenado em Page 1 ou superior. |
| SCREEN 8 | 256 (Cache) | 256 cores por pixel | Usa 128KB de VRAM intensamente. |
NOTA TÉCNICA
Em máquinas MSX 2 ou superiores, o uso de TILEMAPLOAD aproveita os comandos de processamento paralelo do VDP (Blitter) para carregar tilesets inteiros em milissegundos.
⚠ ATENÇÃO No MSX 1, sobrescrever tiles abaixo de 32 pode apagar símbolos de controle. No MSX 2, o limite de 256 padrões no "cache" do CrossScript é virtual; você pode aumentá-lo configurando o banco de VRAM via software.
Efeitos direto nos desenhos dos blocos
Estes comandos alteram o desenho de um bloco (tile) na memória de vídeo. Todas as casas da tela que usam aquele bloco mudam juntas — é assim que se faz água correndo, esteiras e explosões sem mexer no mapa.
TILEROLL — girar o desenho
TILEROLL bloco, direcao, pontos desloca o desenho do bloco com volta (o que sai por um lado entra pelo outro). Direção: 0 esquerda, 1 direita, 2 cima, 3 baixo.
WHILE 1
TILEROLL 65, 0, 1 ' a "água" anda 1 ponto para a esquerda
WAIT
WEND
TILEFX — efeitos prontos
TILEFX bloco, efeito [, parametro]
| Efeito | O que faz | Parâmetro |
|---|---|---|
| 0 | Inverte (negativo) | — |
| 1 | Espelha na horizontal | — |
| 2 | Espelha na vertical | — |
| 3 | Preenche todo o bloco | — |
| 4 | Apaga o bloco | — |
| 5 | Dissolve | máscara de pontos |
| 6 | Explode | etapa de 0 a 4 |
| 7 | Ruído aleatório | semente |
BLOCKMOVE — mover um objeto de 2×2 blocos
BLOCKMOVE origem, trabalho, direcao, subponto desenha um objeto de 16×16 pontos (4 blocos) deslocado de 0 a 7 pontos, sem volta. origem é um array de 4 BYTEs com os blocos originais (nunca alterados) e trabalho outro array de 4 BYTEs com os blocos que recebem o resultado. Com isso um objeto de cenário anda ponto a ponto mesmo em telas de blocos.
SCENERY — desenhar a tela inteira de uma vez
SCENERY(mapa) copia para a tela um array com o número do bloco de cada casa (32×24). Em SCREEN 5 o mesmo comando desenha os blocos no bitmap. SCENERYRLE(mapa) faz o mesmo com o mapa comprimido (repetições), economizando cartucho; ainda não funciona em SCREEN 5, 7 e 8.