Versión HTML por Nacho Cabanes
En el mercado existen varios tipos de tarjetas de vídeo: HGC, MDA, CGA, EGA, VGA y Super-VGA. Las cuatro primeras no las vamos a estudiar porque ya están obsoletas y la última porque es demasiado complicada para nuestros propósitos. Respecto a por qué hemos escogido el modo 13h de la VGA para realizar los programas y no otros modos con más resolución como el 0Eh (640x200), el 10h (640x350) o el 12h (640x480), pues sencillo, por el número de colores, estos tres modos que hemos nombrado, tienen un máximo de 16 colores simultáneos en pantalla y como ya hemos dicho, el modo 13h cuenta con 256 colores, y preferimos tener más colores en pantalla a consta de perder resolución y que los gráficos queden un poco 'bastos'. Además otra ventaja adicional de este modo es la organización de su memoria de vídeo, que es muy sencilla como veremos más adelante. :)
Algunos lenguajes LAN como C y Pascal suministran unos controladores e instrucciones especiales para trabajar en modo gráfico, pero nosotros en la medida de lo posible evitaremos el uso de estos servicios, ya que además de tener que cargar con los controladores gráficos (dígase BGI o como sea) suelen ser bastante lentos. Nosotros nos haremos las rutinas para todo aquello que necesitemos, estas rutinas, utilizarán instrucciones LAN para el manejo de la memoria, como MEM, ABSOLUTE y MOVE. Cuando el factor tiempo sea muy importante, utilizaremos rutinas en ensamblador para acelerar los procesos. :)
Empecemos con este modo de vídeo tan supersticioso. ;) Lo primero que hay que hacer al trabajar en modo gráfico es inicializar el modo de vídeo, para ello utilizaremos una función proporcionada por la interrupción BIOS de vídeo 10h, esta función es la 00h y sus parámetros son los siguientes:
Int 10h
ah= 00h
al= modo de vídeo a inicilizar
En nuestro caso la rutina en Asm sería:
mov ah,00
mov al,13h
int 10h
Cuando estudiamos la organización de la memoria de la familia 80x86, ya vimos que las tarjetas EGA/VGA disponían de un segmento de 64 kb para representar su imagen (A000), esta zona forma parte de la VRAM (Vídeo RAM) y es la zona de memoria de donde la tarjeta gráfica lee los datos para convertirlos en imágenes, es decir, cuando nosotros queremos visualizar algo en la pantalla no tratamos directamente con el monitor, si no que trabajamos con una zona de memoria y a partir de ahí, la VGA se encarga automáticamente de 'dibujar' las imágenes. :)
Hemos dicho que esa zona de memoria es de 64 Kb entonces, ¿Cómo se explica que algunas tarjetas VGA consten de una memoria de 256 kb ?, pues bien, ante la imposibilidad de trabajar con ese estrecho margen de 64 kb, los fabricantes de tarjetas se decidieron por utilizar los que se llaman Bit-planes de 64 kb cada uno (256 kb en total), que se 'esconden' detrás de esos 64 kb visibles y direccionables, aumentando la memoria disponible pero complicando mucho la electrónica del sistema de vídeo, en algunos modos de vídeo (los de 16 colores) se hace imprescindible trabajar directamente con los bit-planes, pero en este modo no es así... :)
Como ya dijimos al principio, una de las ventajas de trabajar en el modo 13h es la organización de la memoria de vídeo. En este modo cada punto en pantalla se representa por un byte que indica el color de ese punto, por lo tanto con 8 bits se pueden codificar 256 valores diferentes, de ahí viene el número de colores de este modo de vídeo. La resolución gráfica de este modo es de 320x200, cada línea de pantalla se compone de 320 puntos o bytes y en total habrá 200 líneas, todas estas líneas se suceden unas a otras de modo lineal a través de ese segmento de 64 kb situado en la dirección A000, ocupando un total de 64000 bytes. Sabiendo esto, si nosotros nos definimos una tabla de 64000 bytes y la situamos en esa zona de memoria con la claúsula Pascal absolute...:
Pantalla:Array[1..64000] of byte Absolute $A000:0000;
tendremos una variable definida justo 'encima' de la memoria de vídeo y cualquier cambio que hagamos sobre dicha variable se reflejará inmediatamente en pantalla. Para escribir un punto en pantalla de color C, en las coordenadas X,Y únicamente tendremos que calcular la posición en dicha tabla donde escribir el color. Debido a la disposición lineal que dijimos antes, esta será y*320+x, es decir, el número de línea por 320 más el número de columna, en Pascal nos quedaría:
Pantalla[Y*320+X]:=C (*Visualiza un punto de color C en coordenadas X,Y*)
En C no podemos poner cualquier valor, en la tarjeta VGA todos los colores (256) que se pueden representar en pantalla en un momento determinado, se guardan en una estructura conocida como tabla de colores o paleta, pero en este momento no vamos a explicar su funcionamiento, eso será en la lección 2.
El método anterior para representar un punto utiliza la técnica de acceso directo a memoria (no confundir con la DMA), para lograr sus propósitos podríamos haber tenido el mismo resultado si hubiésemos utilizado la instrucción MEM, que se utiliza para referenciar una posición de memoria.
MEM[$A000:Y*320+X]:=C (*Visualiza un punto de color C en coordenadas X,Y*)
Existen otros métodos para representar puntos en pantalla. La interrupción de vídeo BIOS 10h, además de la función 00h ya explicada, proporciona otras muchas funciones para trabajar en modo gráfico, una de ellas es la función 0Ch, que se encarga de poner un punto en pantalla. Para ver los parámetros de la función consulta los fuentes del programa Puntos.
Cuando estudiamos la división en niveles de nuestro ordenador, vimos que había un factor llamado overhead, que indicaba el tiempo que se tardaba en pasar de un nivel a otro, pues bien , en el programa de demostración apreciaréis ese factor, y os daréis cuenta de que el utilizar las funciones BIOS para dibujar es bastante más lento que el utilizar la técnica de acceso directo a memoria. :) Luego moraleja, no utilicéis las funciones BIOS al trabajar con gráficos, cuando tengáis prisa. Su uso lo restringiremos a tareas, como inicializar el modo de vídeo y tal vez, para trabajar con la paleta.
Podéis ejecutar ahora el programa PUNTOS que demuestra y compara las dos técnicas que he explicado para representar puntos en pantalla. Para los que no hayáis trabajado en modo gráfico, lo podéis considerar el 'Hola mundo' de la programación de videojuegos. ;)
Pulse F2 para ejecutar el programa PUNTOS - Posibilidad no disponible en la versión HTML-.
Como veis es muy sencillo poner un punto en pantalla. Algunos diréis, - pues vaya un punto y que hago yo con eso- , pues como supongo que sabréis ;) os diré que una línea se compone de puntos, un círculo también y lo más importante un sprite también. ;)
Nosotros no nos vamos a parar a explicar cómo sacar una línea por pantalla, porque aunque os parezca mentira, no se suelen utilizar en la programación de videojuegos, salvo en los llamados juegos vectoriales. En vez de eso para que veáis que un punto es importante, lo que vamos a hacer es sacar una imagen por pantalla. :)
Una imagen no es más que muchos puntos de colores que están dispuestos de tal manera que forman algo que nosotros reconocemos. El problema al representar una imagen, es que ésta, no suele venir en el formato con que se organiza la memoria (formato crudo), es decir, 200 líneas de 320 puntos cada una. Las imágenes vienen en unos determinados formatos gráficos, que suelen utilizar técnicas de compresión para ahorrar espacio de almacenamiento, (digase PCX algoritmo RLE, GIF algoritmo LZW...) así que antes de representar la imagen hay que convertirla al formato que utiliza la memoria.
El formato gráfico PCX lo veremos en el capítulo 2 y los ficheros GIF en el capítulo 3. Ahora os explicaré cómo conseguir una imagen en formato crudo (o RAW, o CAP, o PIC o como queráis llamarlo), para poder representar la imagen en pantalla moviéndola directamente a la memoria de vídeo. :)
Para obtener las imágenes crudas, nosotros utilizamos el programa de dibujo Animator 2d de Autodesk , (versión básica no la profesional). En este programa la última imagen que se ha visualizado se almacena en el directorio AAT con el nombre AATEMP2.PIC, este fichero es casi la imagen en crudo. Os explicaré de qué se compone este fichero...
El fichero AATEMP2.PIC tiene que tener un tamaño de 64800 bytes, si no es así, tenéis otra versión de Animator que no es la mía y no creo que lo siguiente se cumpla para vosotros. Los primeros 32 bytes del fichero son una cabecera que pone Animator a la imagen, los siguientes 768 son la paleta del dibujo, que como ya os he dicho no os voy a explicar ahora, ;) el resto 64000 son la imagen en crudo, si os fijáis, su tamaño coincide con el área visible del segmento de vídeo 320x200 = 64000.
Como supongo que sabréis y si no para eso estoy yo, ;) un segmento tiene una longitud de 65536 bytes, pero los últimos 1536 bytes del mismo no se representan en pantalla, luego 64000 son justo lo que se 'lleva' la VGA al monitor.
Si no tenéis la herramienta Animator, no importa, en otros muchos programas de dibujo también se puede trabajar con las imágenes en crudo, sólo tenéis que saber como descomponer la imagen, pero sabiendo que el tamaño es de 64000 bytes y que ésta se suele almacenar al final, lo tenéis más fácil. De todos modos os he proporcionado un Aatemp2.pic, para que veáis cómo visualizar una imagen. Ejecuta y consulta cuando puedas, los fuentes del programa IMAGEN para ver cómo visualizar una ídem. ;)
Pulsa F2 para ejecutar el programa IMAGEN - Posibilidad no disponible en la versión HTML-.
Aprovecho para dar las gracias a Juan Antonio Ubeda Torres, nuestro grafista en Hormigator, por realizar esta pantalla, también quiero dedicar el programa a Cristobal Saraiba Bello por hacer de cartero para mi en Sakery BBS. ¿Alguien más quiere saludar? ..... No pues seguimos ;)
Cuando consultéis los fuentes os daréis cuenta de que la imagen, no la llevo a pantalla punto a punto sino que utilizo la instrucción LAN Move que mueve bloques de bytes. Como ya os dije, en la medida que no necesitemos mucha velocidad, utilizaremos instrucciones LAN, pero cuando no sea así, utilizaremos rutinas en ensamblador para, en este caso llevarnos punto a punto la imagen a la memoria de vídeo, que aunque pueda parecer un método más lento es un 'pelín' mas rápido. :)
Bueno con esto ya acaba el primer capítulo dedicado al modo 13h,
en las próximas lecciones ya empezaremos a trabajar con los sprites
y la paleta, para poder empezar a hacer animaciones, scrolling y diversos
efectos gráficos, cuanto antes posible. A que estáis impacientes
por leer estos temas, ;) pues yo estoy impaciente por explicároslos.
Un saludo. :)