|
|
|
Hasta el momento
para colocar texto en la pantalla solo utilizábamos las funciones
que nos proporcionaba nuestro compilador.
Ahora veremos como colocar texto en modo gráfico. Podemos colocar texto normal, en negrita, sombreado, cursiva, etc., sin el uso de la BIOS, ni funciones del compilador. El método que veremos se basa en la lectura de los caracteres que hay almacenados en la memoria ROM, pero como veremos más adelante, también los podremos cargar de un archivo utilizando fuentes de 8x16 (los archivos *.fnt que ocupan 4096 bytes=8*16*256). Y como veremos y hemos dicho antes, a estas les podremos aplicar diferentes efectos. La tabla de caracteres se encuentra el la posición F000:FA6A, aquí es donde comienza la descripción de los 256 caracteres. Cada uno esta representado mediante 8 bytes. Cada byte es el patrón o mascara de una fila. Por ejemplo, si tenemos la letra 'A', sus 8 bytes serían 56, 108, 198, 198, 254, 198,198, y 0, como se muestra en la figura:
Para descomponer los diferentes bits de un byte, es decir para saber si va un pixel o no, lo que haremos será utilizar la operación lógica “>>”. Lo que hace esta operación es rotar un bit n posiciones a la derecha (lo cual corresponde a una división), así si queremos saber que valor hay en el bit número 3 de menor peso del número 53 (empezando por el de más a la derecha), haremos la siguiente operación: 53 AND (256 SHR 3) Esto nos dará un 1 o por el contrario, un cero, depende de si dicho bit esta encendido o apagado. Ahora crearemos nuestra primera rutina, la cual colocará solo un carácter en la pantalla. Pero para esto necesitamos un puntero a la tabla de caracteres de la ROM: unsigned char *Font8x8=(unsigned char *) 0xF000FA6E; De esta forma utilizando el puntero Font8x8, podremos acceder a cualquiera de los 256 caracteres disponibles. Para poder representar estos bytes adecuadamente
en la pantalla, tendremos que irnos a la posición correspondiente
de las 256 e ir descomponiendo todos los bits de cada byte, e ir
dibujando sólo los que den 1, a medida que cambiemos de byte, aumentaremos
la posicion Y en uno, ya que es el que corresponde a una línea más
abajo en pantalla. Veamos como queda:
Para dibujar una cadena entera, lo que haremos será, antes de entrar en el bucle encargado de dibujarnos el carácter obtener el tamaño de la cadena. En C eso lo podemos hacer mediante la función strlen(). Como sabemos el tamaño de la cadena,
sólo tendremos que ir dibujando carácter a carácter,
teniendo en cuenta que tendremos que aumentar en 8 la X cada vez que dibujemos
un carácter.
Si queremos hacerlo con cursiva,
lo único que tendremos que hacer es ir desplazando X en n-1 posiciones
cada vez, de manera que cuando Y sea igual 8, n sea igual 1, o sea, a X
le sumaremos 0 y así quedará como estaba, vamos
a ver esto con más detalle, la siguiente función coloca texto
en cursiva:
Si lo que queremos es dibujar con sombra,
la función necesitará dos valores; el color del texto
y el color de la sombra. Ahora lo único que deberemos hacer
es dibujar con la función encargada de escribir un texto que vimos
antes, Write8x8().
También podríamos crear texto
en negrita, esto es muy simple. Veamos:
Normalmente el tamaño de 8x8 se nos hace demasiado pequeño para los modos SVGA que se usan hoy en día (como mínimo 640x480). Existen otro tipo diferente de letras, estas son el doble de altas que las anteriores. Estos tipos de fuentes pueden ser cargadas desde unos archivos de extensión *.fnt. Estos archivos contienen varios tipos diferentes de fuentes que podrán ser retocadas con alguno de los muchos diferentes tipos de programas que hay para esto, así que se hacen ideales para utilizar en juegos, demos, etc. Estos archivos no son nada más que caracteres de tamaño 8x16 almacenados de la misma forma que los de 8x8, pero en vez de estar en memoria, estos se encuentran en un archivo. Los primeros 16 bytes de estos archivos corresponderán al carácter 0 de la tabla ASCII, y así recorriendo todas sus posiciones hasta llegar al byte número 4096 (256*16). La forma de trabajar con estas, no difiere en nada con las anteriores (8x8), pero ahora deberemos de tener en cuenta que son fuentes de 16 pixeles de alto en vez de 8. Para trabajar con estos archivos crearemos un nuevo tipo de dato: typedef unsigned char t_font[4096]; De esta forma cuando queramos cargar alguna fuente en especial, simplemente crearemos una variable del tipo t_font. Una rutina que cargue estos archivos puede
ser la siguiente:
La función para escribir cadenas
de texto, pero utilizando caracteres de 8x16 es análoga a la que
se hizo para las de 8x8. Ojo que la función tambien necesita como
parámetro una variable de tipo t_font. Veamos entonces como nos
quedaría esta función:
Las demás funciones para trabajar con fuentes de 8x16, al igual que todas las rutinas que ya vimos, las podrán encontrar en una librería llamada write.h
Ejemplos Librería gráfica: vgalib.h
|