domingo, 11 de marzo de 2012

Scroll

Otra prueba que quería hacer antes de ponerme a ordenar el código y montar las librerías finales (o casi finales) es la del scroll de pantalla. De momento he probado con scroll horizontal repitiendo la misma pantalla de forma infinita.

Teoría del scroll


Para generar el scroll hay que crear dos buffers del tamaño de la pantalla y pintarlos uno detrás de otro, al llegar al final, reseteamos la posición de memoria inicial donde pintamos y volvemos al principio.

Arduino mega cuenta con un espacio reservado de 64K de memoria externa, de la posición 0x2200 a la 0xFFFF. El shield que estoy utilizando, MegaRAM, tiene bloques de 32K y pueden utilizarse 2 simultáneos consiguiendo un total de memoria de 56K aproximadamente. El buffer que estoy utilizando es de 29952B (208x144), si utilizo 2 buffers, necesito 59904B (58.5K). No cabe. Y si utilizo un bloque de memoria para cada buffer no puedo hacer scroll ya que los datos no serían contiguos en memoria.

Solución 1:

Dividir la pantalla en 2 de forma horizontal, colocar los datos de la parte superior en un bloque de memoria y los datos de la parte inferior en el otro bloque. Cuando empieza el render de lineas activas hay que activar el primer bloque de memoria y al llegar a la mitad de lineas hay que activar el segundo bloque.

División en 2 bloques

Solución 2:

Quitar dos columnas de tiles (16px) del buffer. Esto tiene 4 ventajas, la primera es el ahorro de memoria:

192 * 144 = 27648B = 27K
27 * 2 = 54K

54K caben en un bloque de 56K. Otra ventaja es que ahora tendré un aspecto de pantalla de 4:3:

144 * 4 / 3 = 192

La tercera es que al quitar 16px gano 64 ciclos de reloj o 4us para liberar CPU. Cada pixel tarda 4 ciclos:

16 * 4 = 64 ciclos
64 / 16 = 4us

Y la cuarta ventaja es que con esta resolución me acerco más a los márgenes de seguridad. Si el ancho máximo que podía conseguir era de 208 y el margen es del 90%:

208 * 90 / 100 = 187.2px

Sigo estando fuera de márgenes pero había que buscarle algo bueno a perder resolución.

De entre las 2 soluciones de momento me quedo con la segunda. Si quisiese más resolución tendría que cambiar el cristal de la placa Arduino Mega por uno más rápido, por ejemplo, con 20MHz tendría 260px, pero mi intención es la de no modificar la electrónica básica de Arduino. Además, necesitaría más RAM y estaría en las mismas.

52us * 20MHz = 1040ciclos
1040 / 4 = 260

El siguiente video muestra el scroll de la opción 2:





Esta vez he subido el código con los 2 ejemplos, está en la pestaña de descargas.


2 comentarios:

  1. Hombre tibu, te he encontrado por casualidad, que grandes tus inventos,eres un romantico.Muy interesante,cuando contruyas una consola en 3d ya podemos hacer algo :p aunque a ti eso de los 8 bits te va mas.

    Pedro

    ResponderEliminar
    Respuestas
    1. Que tal Pedro tio! Gracias por el comentario, lo de la consola 3D de momento va a ser que no, jejeje. Lo que intento hacer es emular todos los chips de una consola de 8 bits en un solo microcontrolador. O por lo menos demostrar que se puede pintar en color y animar sprites. Creo que es interesante poder conocer como un pequeño chip puede llegar a generar imágenes en una pantalla por medio de pulsos eléctricos.
      A ver si retomo otra vez el blog y avanzo un poco que lo tengo paradísimo.
      Bueno, a ver si nos vemos un día de estos, no?

      Eliminar