Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


Curso de Pascal. Ampliación 2: Gráficos sin BGI (5)

Escribir texto

Hay dos formas de escribir texto:

Una, que no vamos a tratar, consiste en definir nuestra propias letras, o saber dónde está la definición de las que trae el ordenador, para mirar esa zona de memoria, analizarla y escribir las letras pixel a pixel.

Otra más sencilla, aunque menos versátil, es con la orden "write" igual que hacíamos en modo texto. Para ello, basta usar la unidad CRT pero indicando   DirectVideo := false   con lo que la escritura pasa a través de la BIOS, en vez de hacerse directamente en la memoria de pantalla. Así conseguimos que se pueda enviar a la pantalla gráfica.  Veremos un ejemplo al final del tema, en el ejemplo de Scroll.


Finalmente, para copiar zonas de memoria podemos utilizar move, que tiene el formato   move (org, dest, cuanto)   Esto no nos sirve directamente para zonas rectangulares de la pantalla, porque el origen debe ser una sóla zona contigua, lo que no ocurre en un rectángulo, pero podemos evitarlo copiando fila a fila con un bucle.

¿Y cómo se usa?  Pues vamos a ver un ejemplillo, aprovechando que en nuestro modo de pantalla cada byte se corresponde con un pixel, para hacer un Scroll (desplazamiento) de parte de la pantalla, para que aparezca un texto:

 {--------------------------}
 {  Ejemplo en Pascal:      }
 {                          }
 {    Scroll sencillo en la }
 {    parte inferior de la  }
 {    pantalla              }
 {    GRB5.PAS              }
 {                          }
 {  Este fuente procede de  }
 {  CUPAS, curso de Pascal  }
 {  por Nacho Cabanes       }
 {                          }
 {  Comprobado con:         }
 {    - Turbo Pascal 7.0    }
 {    - Tmt Pascal Lt 1.01  }
 {--------------------------}

 Uses
   Crt, dos;

 Const
   Fila = 23;   { Fila (-1) en la que se escribe el mensaje (base 0) }

 Var
   pixel, LetraActual : Byte;  { Para bucles }
   regs: registers;            { Para interrupciones (ModoPantalla) }
   tecla: char;                { Para absorber la tecla que se pulse }

 procedure ModoPantalla( modo: byte );       { Cambia a un modo dado }
 begin
   regs.ah := 0;               { Función 0 }
   regs.al := modo;            { El modo indicado }
   intr($10,regs);             { Interrupción de video }
 end;

 procedure Retrace;            { Espera el barrido de la pantalla }
 begin
   repeat until (port[$3da] and 8) = 8;
   repeat until (port[$3da] and 8) <> 8;
 end;

 Procedure Mueve;          { Desplaza el texto a la izqda un pixel }
 Var
   LineaAct : Word;        { La línea que se está moviendo }
 begin
                     { Desplaza las 8 líneas 1 pixel hacia la izqda }
   For LineaAct := (Fila * 8) to (Fila * 8) + 7 DO
     Move(Mem[$A000 : LineaAct * 320 + 1], Mem[$A000 : LineaAct * 320], 319);
                           { Borra los pixels del final }
   For LineaAct := (Fila * 8) to (Fila * 8) + 7 DO
     Mem[$A000 : LineaAct * 320 + 319] := 0;
 end;

 procedure ScrollInferior(mensaje:string); { Esto es lo importante }
 begin
   ModoPantalla($13);          { Modo Mcga/Vga 320x200x256 }
   DirectVideo := False;       { Para escribir texto en modo gráfico }
   GotoXY(1, Fila + 1);        { Vamos a la posición }
   repeat
   For LetraActual := 1 to Length(Mensaje) do      { Para cada letra }
   begin
     For pixel := 1 to 8 do               { Los 8 pixels de ancho }
     begin
       Mueve;                             { Mueve el letrero }
       Retrace;                           { Espera al barrido }
       if keypressed then exit;           { Si se pulsa tecla: fuera }
     end;
     GotoXY(40, Fila+1);                  { En la posición adecuada }
     Write(Mensaje[LetraActual]);         { Se escribe la sgte letra }
   end;
   until keypressed;
 end;

 begin
   ScrollInferior('Esto es un  - S C R O L L -                ');
   tecla := readkey;                  { Vacía el buffer del teclado }
   ModoPantalla(3);                   { Vuelve a modo texto }
 end.
  


 

Una recomendación final: en vuestros programas (si es que los haceis X-D ) no se os ocurra copiar el procedimiento "linea", "modopantalla" y similares cada vez.  Lo más cómodo es crear una unidad, meter nuestros procedimientos y funciones relacionados con los gráficos y acceder a ella cuando nos interese.

Así además, si encontrais otro procedimiento más rápido para dibujar líneas (los hay, si trabajamos en ensamblador, por ejemplo) o cualquier otra mejora, todos los programas la tendrán sólo con recompilar.