¿Cómo se logró un desplazamiento tan suave en juegos como Super Mario y Commander Keen?

Escribí el motor de gráficos para la versión para PC de Golden Axe (lanzado antes de Commander Keen, creo). El adaptador EGA / VGA tenía una característica genial que era esencialmente parte del cambio de página. Puede establecer la dirección de pantalla en cualquier valor de 32 bits que desee. Y la tarjeta de video se envolvería al buscar píxeles.

La mayoría de los adaptadores EGA / VGA tenían más de 64K. Tenían 128K, o 256K, pero solo los abordó en 4 planos de 64K cada uno. En modeX (crédito Mr. Abrash para eso), tenía un modo plano 320 × 200 en 256 colores, donde podía acceder a 4 píxeles secuenciales a través de una dirección de 1 byte. Sí, eso es 32 bits de color (4 planos de profundidad), en un solo byte. Entonces el direccionamiento era exactamente 80 bytes por 200 líneas de escaneo. O 16,000 bytes de espacio de direcciones en una tarjeta de 256K, que le brinda cuatro pantallas más algo extra para jugar.

Creo que Golden Axe usó dos pantallas para pasar la página y una para borrar el sprite. Y el resto se utilizó para almacenar sprites comprimidos. Los rectángulos sucios rastrearon qué áreas de la pantalla necesitaban actualizarse.

Así que de vuelta al desplazamiento. Tres pantallas movidas a través de la memoria. Supongamos que cambia de página entre 0x0000 y 0x4000. Mantiene una copia del fondo sin sprites (para borrar), a 0x8000. La pantalla que se muestra actualmente es de 0x4000 y desea desplazarse hacia arriba.

1. Restas 80 bytes de tu siguiente búfer de trama, que era 0x0000 y ahora es 0xFFA0.
2, resta 80 bytes de su dirección de pantalla de fondo limpio (que utiliza para borrar sprites).
3. Representa la línea superior de la pantalla de fondo.
4. Agregue la línea superior a la lista de rectángulos sucios de su pantalla a la que va a procesar.
5. Utiliza la lista de rectángulos sucios para borrar todos los sprites en movimiento desde la última vez que renderizaste en esta superficie. Luego borra la lista.
6. Representa todos los sprites en esta superficie, agregándolos a la lista sucia de rect para este marco.
7. Dices la interrupción vertical en blanco, estás listo para mostrar
dirección 0xffa0.

Hace todo lo anterior en 16.6 milisegundos, en una CPU de 8Mhz.

El modo plano le dio algunas ventajas, ya que para borrar los sprites, podría hacerlo cuatro píxeles a la vez, moviéndolo de la memoria de la pantalla a la memoria de la pantalla en este modo plano.

Hay algunas dificultades para realizar un seguimiento de la memoria de sprites, ya que también tiene que moverse, ya que las pantallas pueden desplazarse por toda la memoria.

Para el comandante Keen, una buena introducción es el libro Masters of Doom. La idea era minimizar el número de píxeles dibujados reutilizando el fondo que no cambió y haciendo operaciones orientadas a bloques.

Aún más interesante es el libro escrito por Bob Pape sobre cómo escribir R-Type para Z80: está detrás de usted (www.bizzley.com). Aquí obtienes trucos de desplazamiento aún más suaves, incluido el movimiento de paralaje en un procesador muy antiguo y débil, en aproximadamente 32 kb.

La idea general es reutilizar tanto como sea posible y volver a dibujar lo menos posible. Estos trucos ya no son necesarios hoy en día, pero solían ahorrar mucho en máquinas antiguas y decodificadores. No vería tales trucos necesarios en máquinas> 1GHz.

Dos técnicas de optimización diferentes:

1 – Truco de hardware EGA
2 – algoritmo “actualización de mosaico adaptativo”

La mayoría de las veces las personas (y el libro “Master of Doom”) se refieren solo a la segunda, pero la primera fue la optimización real, la segunda fue solo una optimización posterior al paso para acelerar aún más la rasterización de la pantalla.

Truco de hardware EGA
Esta es la gran innovación.
El hardware EGA proporcionó dos características que permitieron el desplazamiento suave:

feat.A – El búfer de pantalla podría ser ligeramente más ancho que la pantalla y arbitrariamente alto, sujeto a limitaciones de memoria de video.

feat.B – La posición dentro de este búfer desde el que se dibujó la pantalla podría compensarse con incrementos de un píxel, ya sea horizontal o verticalmente.

Carmack utilizó estas capacidades para crear un búfer que era 64 píxeles más ancho y más alto que la pantalla, dejando espacio para una fila y columna de mosaicos adicionales en el búfer fuera del borde de la pantalla. Utilizó las capacidades de desplazamiento de la tarjeta para permitir que la pantalla se deslice a través del búfer para un desplazamiento suave, lo que revelaría parcialmente las fichas adicionales.
El desplazamiento se limitaba al tamaño del búfer y el desplazamiento adicional se ajustaba para mostrar datos del otro lado del búfer. Entonces, para desplazarse a través de un nivel completo, cuando el desplazamiento equivalía a un azulejo completo, el código de Carmack luego dibujaría la siguiente fila de azulejos desde el nivel en el búfer, justo fuera del borde de la pantalla, listo para mostrarse cuando el desplazamiento continuaba en esa dirección

actualización de mosaico adaptativo
Fue solo una optimización posterior hecha por Carmack para acelerar aún más su código. Básicamente, el código no redibujó el búfer de pantalla todo el tiempo, solo las cosas que realmente cambiaron de posición fueron los mosaicos (es decir, sprites)

De hecho, difícil de lograr, pero fue posible.

Eche un vistazo a este enlace, lo guiará a cómo se creó esta física
http://www.explodingrabbit.com/f

Si tienes otra consulta, búscame.

Sinceramente,

José Eduardo Terán