El sistema gráfico de la SNES es uno de los más avanzados de su época, con capacidades únicas que permiten efectos visuales impresionantes.
La SNES tiene 8 modos gráficos principales que determinan cómo se organizan los fondos y sprites.
Modo | Fondos | BPP | Colores | Uso Típico |
---|---|---|---|---|
0 | 4 fondos | 2bpp | 16 (4 paletas) | Interfaces, texto |
1 | BG1:4bpp, BG2:4bpp, BG3:2bpp | Mixto | BG1/2:16, BG3:4 | Juegos con profundidad |
3 | BG1:8bpp, BG2:4bpp | Mixto | BG1:256, BG2:16 | Gráficos detallados |
7 | 1 fondo | 8bpp | 256 | Full-screen imágenes |
; Configurar Modo 1 con prioridad para BG3 lda #$09 ; %00001001 ; Bit 0-2: Modo 1 ; Bit 3: BG3 prioridad alta sta $2105 ; Registro BGMODE
Los tiles son bloques de 8x8 o 16x16 píxeles que forman los elementos gráficos básicos.
2bpp (16 colores): - Cada píxel usa 2 bits (4 colores por paleta) - 16 bytes por tile (8x8) 4bpp (16 colores): - Cada píxel usa 4 bits (16 colores) - 32 bytes por tile (8x8) 8bpp (256 colores): - Cada píxel usa 8 bits - 64 bytes por tile (8x8)
; Cargar tileset en VRAM $0000 LoadTileset: lda #$80 ; VRAM incremento +1 después de $2119 sta $2115 lda #$00 ; Dirección VRAM $0000 sta $2116 lda #$00 sta $2117 ; Configurar DMA lda #$01 ; Banco de datos sta $4304 lda #$18 ; Puerto $2118 (VRAM data) sta $4301 ldx #tileset_data ; Dirección fuente stx $4302 ldx #$2000 ; Tamaño: 8KB stx $4305 lda #$01 ; Modo 1 (transferencia de bytes) sta $4300 lda #$01 ; Iniciar DMA canal 1 sta $420B
La SNES usa paletas de 16 colores (15-bit RGB) compartidas entre fondos y sprites.
Formato de color (2 bytes por color): Bit 0-4: Azul (0-31) Bit 5-9: Verde (0-31) Bit 10-14: Rojo (0-31) Bit 15: Sin uso
; Cargar paleta en CGRAM LoadPalette: stz $2121 ; Empezar en entrada 0 de CGRAM ; Configurar DMA lda #$02 ; Banco de datos sta $4304 lda #$22 ; Puerto $2122 (CGRAM data) sta $4301 ldx #palette_data ; Dirección fuente stx $4302 ldx #$0020 ; 32 bytes (16 colores) stx $4305 lda #$00 ; Modo 0 (transferencia de bytes) sta $4300 lda #$01 ; Iniciar DMA canal 1 sta $420B
; Paleta de 16 colores (32 bytes) palette_data: .dw $0000, $7FFF, $1CE7, $027F ; Gris, blanco, rojo, azul ; ... más colores
Cada fondo tiene sus propios registros de control:
Registro | Fondo | Propósito |
---|---|---|
$2107-$210A | BG1-BG4 | Configuración de tiles (SC) |
$210B-$210C | BG1/BG2, BG3/BG4 | Asignación de bloques de tiles (NBA) |
$210D-$2114 | BG1-BG4 | Scroll (HOFS, VOFS) |
; Configurar BG1 en Modo 1 lda #%00001001 ; Tamaño tilemap 32x32, tiles en $0000 sta $2107 ; BG1SC lda #$01 ; Tiles de BG1 en $1000 sta $210B ; BG12NBA ; Cargar tilemap LoadTilemap: lda #$80 ; VRAM incremento +1 sta $2115 ldx #$1000 ; Dirección VRAM del tilemap stx $2116 ; Configurar DMA lda #$02 ; Banco de datos sta $4304 lda #$18 ; Puerto $2118 sta $4301 ldx #tilemap_data stx $4302 ldx #$0800 ; 32x32 tiles = 2048 bytes stx $4305 lda #$01 ; Modo 1 sta $4300 lda #$01 ; DMA canal 1 sta $420B
Cada entrada de tilemap son 2 bytes: Byte bajo: Bit 0-9: Número de tile Bit 10: Flip horizontal Bit 11: Flip vertical Byte alto: Bit 0-2: Paleta (0-7) Bit 3: Prioridad Bit 4-7: Sin uso
; Scroll paralaje UpdateParallax: lda scroll_x lsr a ; BG1: velocidad completa sta $210D ; BG1HOFS lsr a ; BG2: mitad de velocidad sta $210F ; BG2HOFS lsr a ; BG3: cuarto de velocidad sta $2111 ; BG3HOFS
; Configurar Modo 7 lda #$07 sta $2105 ; BGMODE ; Matriz de transformación ; A = $211B (16-bit), D = $211E (16-bit) ; B = $211C (16-bit), C = $211F (16-bit) ; X = $211D (16-bit), Y = $2120 (16-bit) ; Rotación 45 grados (valores aproximados) lda #$00B6 ; cos(45) ≈ 0.707 ≈ $B6/$100 sta $211B lda #$00B6 sta $211C lda #$FF4A ; -sin(45) ≈ -0.707 ≈ $FF4A sta $211D lda #$00B6 sta $211E ; Centro en (128,112) lda #$0080 sta $211F ; Center X sta $2120 ; Center Y
; Configurar HDMA para cambiar paleta en scanline SetupHDMA: lda #$02 ; Canal HDMA 2 sta $4300 ; Modo indirecto lda #$32 ; Puerto $2132 (CGRAM data) sta $4301 ldx #hdma_table stx $4302 lda #$02 ; Banco de datos sta $4304 lda #$04 ; Habilitar HDMA canal 2 sta $420C ; Tabla HDMA hdma_table: .db $20 ; 32 líneas .db $00, $00 ; Color 0: negro .db $40 ; 64 líneas .db $1F, $00 ; Color 0: rojo .db $00 ; Terminar
Organización recomendada: $0000-$1FFF: Tiles de BG1 (4KB) $2000-$3FFF: Tiles de BG2 (4KB) $4000-$5FFF: Tiles de Sprites (4KB) $6000-$7FFF: Tilemaps (8KB)
Consejo: Compartir paletas entre fondos y sprites cuando sea posible para maximizar el uso de colores.
; Configurar modo gráfico con 3 fondos SetupLayers: lda #$09 ; Modo 1, BG3 prioridad alta sta $2105 ; BG1: Capa principal (16x16 tiles) lda #%00010001 ; Tilemap en $1000, 32x32 sta $2107 lda #$01 ; Tiles en $0000 sta $210B ; BG2: Capa de nubes (8x8 tiles) lda #%00000010 ; Tilemap en $2000, 32x32 sta $2108 lda #$02 ; Tiles en $2000 sta $210B ; BG3: Interfaz (8x8 tiles) lda #%00000011 ; Tilemap en $3000, 32x32 sta $2109 lda #$03 ; Tiles en $3000 sta $210C
; Efecto de fade out FadeOut: ldx #$10 ; 16 pasos FadeLoop: phx jsr WaitVBlank ; Oscurecer todos los colores ldy #$00 sty $2121 ; Empezar en color 0 ColorLoop: lda $213B ; Leer CGRAM pha lda $213B ply ; Reducir componentes RGB dey dey ; Escribir nuevo color sty $2122 cpy #$200 ; 256 colores (512 bytes) bne ColorLoop plx dex bne FadeLoop