
-------------------------------------------
     Tutorial de programacin grfica
              Por: F.A.C.
    ----------------------------------
                Nmero #4
           Pantallas Virtuales
-------------------------------------------


Pues s, acabo de "subir" el tutorial #3 al servidor y debido a que no
tengo nada mejor que hacer (bueno, s tengo), pues decid empezar a
escribir el cuarto ShiTorial. A ver si esta vez lo termino a tiempo :)


Si tienen dudas, preguntas, sugerencias, ideas o correcciones,
escrbanme a:

                        Alfonso Alba Cadena
           E-Mail:      ganzo@galia.fc.uaslp.mx
           Telfono:    (48) 13-34-71



Tambin escriban si quieren recibir los tutoriales cada vez que salgan
por e-mail. Y si no, pues los pueden conseguir en:

              ftp://galia.fc.uaslp.mx/pub/tutorial


Bueno... vamos a lo que vinimos...



PANTALLAS VIRTUALES... QUE SON Y PARA QUE SIRVEN???


          Si ya han visto algn demo o algn juego comercial, entonces
          habrn notado que se hacen muchas animaciones y efectos y ni
          siquiera se ve el menor parpadeo en la pantalla.

          Si hicieron el ltimo ejercicio del tutorial #1, (ese en el
          que haba que mover un cuadrado), entonces habrn visto que
          el estar dibujando y borrando una figura no produce precisamente
          un efecto de movimiento suave, sino que la figura parpadea
          constantemente e incluso algunas veces no se ve parte de ella.

          Todo ese parpadeo es producido por los constantes cambios que
          se hacen en la pantalla en el momento en que se est dibujando.

          En el segundo tutorial vimos cmo usar el retrazado vertical para
          sincronizar un poco nuestro programa con la pantalla, pero
          supongamos que tenemos que dibujar una pantalla con un fondo muy
          complejo y encima de ese fondo tenemos que dibujar varias
          figuras animadas. El tiempo de retrazado vertical no sera
          suficiente como para dibujar toda la pantalla, por lo tanto,
          el procedimiento VRetrace pierde su utilidad.

          No sera excelente que el usuario viera cmo dibujamos el fondo
          y luego las figuras una por una y luego borramos la pantalla
          para volver a dibujar el fondo?

          Pues NO! Es HORRIBLE! Lo ideal sera que todo se dibujara tan
          rpidamente que aparente que el fondo NUNCA se borra y que
          aparente que las figuras estn realmente en movimiento.

          Pero el CPU y en especial la memoria de video, no son tan rpidos
          como para lograr esto, por lo que tenemos que hacer un pequeo
          truco.

          Qu tal si en lugar de dibujar el fondo y las figuras en la
          pantalla, las dibujamos en algn otro lugar, y luego simplemente
          copiamos todo a la pantalla real, una vez que todo ha sido
          dibujado???  Y mientras el espectador admira la impresionante
          escena, nosotros estamos dibujando el siguiente cuadro en nuestra
          "pantalla virtual", pero el espectador NO LO VE hasta que
          copiemos toda la escena a la pantalla real.

          Copiar una pantalla de un lugar a otro significa mover 64000 bytes
          de una zona de la memoria a otra. Esto es MUCHO ms rpido que
          calcular y dibujar una pantalla compleja.


ENTONCES, QUE ES UNA PANTALLA VIRTUAL???

          Una pantalla virtual es simplemente una zona de memoria (en este
          caso, de 64000 bytes) que funciona como la memoria real de la
          VGA. Nosotros podemos dibujar puntos, lneas y crculos en nuestra
          pantalla virtual, la nica diferencia es que NADA de lo que
          dibujemos en la pantalla virtual es VISIBLE. Es decir que nosotros
          podemos dibujar una escena que tarde 1 segundo en dibujarse y luego
          simplemente copiamos los 64000 bytes de la pantalla virtual a la
          memoria de la VGA, lo cual tarda solamente un instante.

          Para el espectador, la pantalla se dibuj en ese instante,
          aunque realmente no fu as. Adems, mientras el usuario est
          viendo la pantalla VGA, nosotros podemos estar calculando ms
          pantallas virtuales sin modificar lo que REALMENTE se est viendo.


COMO SE HACE UNA PANTALLA VIRTUAL???

        Bueno, ya que la pantalla tiene 64000 bytes, necesitamos reservar
        una zona de memoria de ese tamao. Eso lo podemos hacer con un
        arreglo:

                var Virtual : array[1..64000] of byte;

        Pero desafortunadamente, el Pascal solamente utiliza 64 Kb para
        las variables del programa, por lo que si hacemos lo anterior,
        nos quedaramos sin memoria para ms variables. Por lo tanto,
        tendremos que usar punteros para acceder al "heap":

                  type TVirtual = array[1..64000] of byte;
                       PTVirtual = ^TVirtual;

                  var Virtual : PTVirtual;


        NOTA: En la realidad, no se puede usar la palabra Virtual como
              nombre de variable porque es una palabra reservada del
              Turbo Pascal (para definir mtodos virtuales), pero la
              estaremos usando en el tutorial para saber que estamos
              hablando de una pantalla virtual.


        Ahora la variable Virtual es un apuntador a nuestra pantalla
        virtual. Pero antes de usar la pantalla virtual, necesitamos
        reservar la memoria que va a usar:

                 Virtual := new(PTVirtual);


        Y antes de que termine nuestro programa, tenemos que liberar
        la memoria utilizada por la pantalla virtual:

                 dispose(Virtual);


        Adems, puesto que muchas de las funciones de dibujo utilizan
        el segmento de la pantalla VGA ($A000), tambin necesitaremos
        el segmento de nuestra pantalla virtual. La funcin Seg() del
        Pascal nos devuelve el segmento de la direccion donde se
        encuentra una variable, en este caso, Virtual^.

               var VirSeg : word;
               ...
               VirSeg := Seg(Virtual^);


        Y eso es todo lo que necesitamos para crear una pantalla virtual.
        Los siguientes dos procedimientos se usan para crear y destruir
        una pantalla virtual:


----------------------------------------------------------------------------

     type TVirtual = array[1..64000] of byte;
          PTVirtual = ^TVirtual;

     { El tipo TVirtual solamente se utiliza para crear el tipo PTVirtual
       el cual es un apuntador a un bloque de 64000 bytes en el "heap" }


     procedure SetupVirtual(var Vscr : PTVirtual; var Vseg : word);
     { Este procedimiento inicializa una pantalla virtual }
     begin
          Vscr := new(PTVirtual); { crea la pantalla virtual }
          Vseg := Seg(Vscr);      { y obtiene su segmento }
     end;


     procedure ShutDownVirtual(var Vscr : PTVirtual);
     begin
          dispose(Vscr);  { destruye la pantalla virtual }
          Vscr := nil;
     end;

----------------------------------------------------------------------------

     Como pueden ver, los procedimientos son muy sencillos. La forma
     de usarlos es la siguiente:


     var Virtual : PTVirtual; { Apuntador a la pantalla virtual }
         VirSeg : word;       { Segmento de p.v. }

     begin
          SetupVirtual(Virtual, VirSeg);  { crea una pantalla virtual }

          ....  { aqui va el programa }

          ShutDownVirtual(Virtual);  { destruye la pantalla virtual }
     end.



COMO DIBUJAR EN LA PANTALLA VIRTUAL:


     Esa es la parte fcil. Recuerdan que en TODOS los procedimientos de
     dibujo usbamos el segmento de la memoria de video ($A000) para
     acceder a la pantalla???

     Bueno, pues lo nico que hay que hacer es utilizar ahora el segmento
     de nuestra pantalla virtual. Por ejemplo, para dibujar el pxel que
     est en las coordenadas (x, y) hacemos lo siguiente:

          (suponiendo que VirSeg es el segmento de la p. virtual)

          Mem[VirSeg:320*y+x] := color;


     Y eso es todo. Ahora lo nico que tenemos que hacer es modificar los
     procedimientos de dibujo para que tambin puedan dibujar en una
     pantalla virtual. Esto lo podemos hacer aadiendo un parmetro en
     cada procedimiento que especifique el segmento de memoria en donde
     se quiere dibujar. Por ejemplo, el procedimiento PutPixel podra
     quedar as:


            procedure PutPixel(x, y : word; color : byte; where : word);
            begin
                 Mem[where:320*y+x] := color;
            end;


     Si queremos dibujar un pxel en nuestra pantalla virtual, entonces
     escribimos:

                PutPixel(160, 100, 1, VirSeg);


     Si queremos dibujar un pxel directamente en la pantalla VGA,
     escribimos:

                PutPixel(160, 100, 1, VGA);


     En la nueva unidad MODE_13.PAS ya se han modificado todos los
     procedimientos de dibujo para permitir que se dibuje tambin en una
     pantalla virtual, por lo tanto, los nuevos procedimientos YA NO
     son compatibles con los anteriores. La nica diferencia es que
     ahora tenemos que especificar EN DONDE se va a dibujar.


COMO COPIAMOS UNA PANTALLA VIRTUAL A LA PANTALLA VGA:

     Esto tambin es muy fcil. De hecho, el Turbo Pascal tiene una
     instruccin que mueve bloques de memoria de un lugar a otro.

     La instruccin tiene la siguiente sintaxis:

        Move(var Fuente, Destino; N : word);


     Y lo que hace es mover un bloque de memoria de N bytes desde Fuente
     hasta Destino.

     Fuente y Destino son los apuntadores al primer byte de la pantalla
     virtual y/o la pantalla VGA.

     Esos apuntadores los podemos obtener referenciando al primer pxel
     de la pantalla, de la siguiente forma:

        Mem[VGA:0] == primer pxel de la pantalla VGA
        Mem[VirSeg:0] == primer pxel de la pantalla virtual


     Fjense que N es un parmetro de tipo word, lo que significa que
     podemos mover hasta 64 Kb con una sola instruccin, lo cual es
     perfecto porque nosotros queremos mover 64000 bytes :)


     Por lo tanto, si queremos copiar una pantalla virtual en la VGA,
     escribimos:

                Move(Mem[VirScr:0], Mem[VGA:0], 64000);

     Incluso podemos hacer un procedimiento generalizado para mover
     los 64000 bytes de un lugar a otro, tomando como parmetro
     solamente los segmentos fuente y destino:


          procedure CopyScreen(fuente, destino : word);
          begin
               Move(Mem[fuente:0], Mem[destino:0], 64000);
          end;


     Ahora podemos escribir algo como:

           CopyScreen(VirSeg, VGA);
           CopyScreen(VGA, VirSeg);


     Solo asegrense de que la pantalla virtual ya ha sido inicializada.


     El programa de ejemplo VIRTUAL.PAS muestra un bloque en movimiento
     usando tres tcnicas diferentes.

     La primera vez, simplemente se borra y se vuelve a dibujar el bloque.

     La segunda vez, se inserta un VRetrace antes de mover el bloque.

     La tercera vez, se borra y se dibuja el bloque en una pantalla virtual,
     luego se espera al retrazado vertical y entonces se copia la pantalla
     virtual a la VGA.

     Ejecuten el programa y vean la diferencia que se obtiene con una
     pantalla virtual. Obviamente, es un poco ms lento cuando se usa una
     PV, ya que se copia TODA la pantalla virtual a la VGA por cada cuadro,
     pero esto elimina casi por completo el parpadeo.

     La segunda vez que se dibuja el bloque, parece ser que una parte del
     bloque parpadea y la otra no. Esto es porque el retrazado vertical no
     dura lo suficiente como para dibujar un bloque tan grande. Por lo
     tanto, esta tcnica solo funciona con objetos pequeos.

     Prueben a cambiar el tamao del bloque y ejecuten el programa.
     Haganlo primero con un bloque pequeo (como de 10*10 pxels) y
     luego haganlo con un bloque grande (unos 60*60 pxels). Vern que
     sin importar el tamao del bloque, la tcnica de la pantalla virtual
     se ejecuta suavemente.


EL FORMATO PCX:

   Habr algunas veces que en lugar de dibujar la pantalla utilizando
   instrucciones de lneas y crculos, simplemente quieran cargar una
   imagen desde un archivo. Existen MUCHOS formatos de archivos de
   imgenes, entre los que estn .BMP, .GIF, .PCX, .TIF. .TGA, .JPG y
   muchos otros. De hecho, hasta ahora no he visto ningn programa que
   pueda abrir todos los formatos que conozco (sin inclur los que NO
   conozco). Pero vamos a centrarnos en un formato en especial. El PCX.


   Porqu el formato PCX ???

   Bueno, simplemente porque es uno de los formatos ms sencillos que
   existen. Probablemente el ms sencillo es el formato RAW, que simplemente
   almacena los bytes de datos sin ningn tipo de encabezado ni compresin,
   y al final del archivo, se almacena la paleta. Sin embargo, ese formato
   tiene varias desventajas, como el gran tamao de los archivos que se
   generan y una gran incompatibilidad entre diversos programas y sistemas
   que lo utilizan.

   El siguiente formato ms sencillo es el BMP, sin embargo, es un formato
   proveniente de Windows y nuestros programas estn orientados a DOS, lo
   cual, en realidad no es ningn problema. El problema es que la mayora
   de los archivos BMP no utiilzan ningn tipo de compresin y ocupan mucho
   espacio en el disco, adems, existen muchas utilidades de programacin
   para DOS que yo utilizo que no trabajan con el formato BMP.


   Por si les interesa, aqu hay algunas utilidades muy buenas:

       - NeoPaint .- Programa de dibujo de bitmaps para DOS.
       - VGATools .- Librera de funciones para TurboPascal para VGA.
       - Image Alchemy .- Convierte entre MUCHOS formatos de imgenes.
       - Cubic Player .- Reproduce archivos de msica (MOD, XM, S3M, etc...)
       - FastTracker II .- El MEJOR programa para componer msica MOD y XM
       - MIDAS .- Libreras de funciones para reproducir MUSICA en TP7.

   Estos programas y MUCHOS otros los pueden conseguir en:

         ftp.cdrom.com/pub/demos

   Adems de programas, pueden encontrar MILES de demos, canciones,
   samples e instrumentos, imgenes, documentos sobre programacin y
   cdigo fuente de algunos demos.

   Hmmmm... tal vez suba algunos de estos archivos al FTP de Galia para
   que todos puedan bajarlos, si les interesa, hganmelo saber.


   Bueno... despus del comercial...


   El formato PCX utiliza un tipo de compresin muy sencillo llamado
   RLE (Run Length Encoding), el cual simplemente consiste en dos bytes,
   el primero indica el nmero de veces que se debe repetir el segundo byte.

   El formato es el siguiente:


   Primero el encabezado. El encabezado tiene una longitud de 128 bytes,
   los cuales tienen las siguientes funciones:

   byte 0      - Identificacin (El valor 10 significa ZSoft)
   byte 1      - Versin
   byte 2      - Tipo de compresin
   byte 3      - Nmero de bits por pxel. (En nuestro caso, 8)
   byte 4      - X min (2 bytes).
   byte 6      - Y min (2 bytes).
   byte 8      - X max (2 bytes).
   byte 9      - Y max (2 bytes).
   byte 12     - Resolucin horizontal (2 bytes).
   byte 14     - Resolucin vertical (2 bytes).
   byte 16     - Datos para la paleta de 16 colores (48 bytes)
   byte 64     - Reservado
   byte 65     - Nmero de planos de color
   byte 66     - Bytes por lnea (2 bytes)
   byte 68     - 1 = Color, 2 = Escala de grises (2 bytes)
   byte 70     - Reservados (58 bytes)


   *NOTA: (2 bytes) significa la longitud del dato en el encabezado.
          NO significa que el valor de ese dato sea 2.

   *NOTA: El tamao real de la imagen se obtiene con los bytes 4 a 9.


   Eso hace el encabezado. Pero no se preocupen por aprenderse todo lo
   anterior porque NO LO VAMOS A UTILIZAR. Lo que quiero decir, es que
   lo anterior simplemente es conocimiento cultural. Lo nico que podramos
   utilizar del encabezado es el tamao de la imagen, pero no lo vamos a
   hacer. En nuestro procedimiento para cargar PCX, vamos a suponer lo
   siguiente:

        1.- Que nuestra imagen tiene 256 colores.

        2.- Que el tamao de la IMAGEN, (Y DEL ARCHIVO) ocupa menos
            de 64 Kb. Esto es porque vamos a almacenar la imagen en una
            pantalla virtual y tal vez en un arreglo, y ninguno de los
            dos puede ocupar ms de 64 Kb.

        3.- Que conocemos las dimensiones de la imagen, tanto en X como
            en Y.

        4.- Que la mquina tiene suficiente memoria para cargar una o
            ms imgenes Y adems para crear una o ms pantallas virtuales.


   Bueno... ya que todo ha quedado claro como el chocolate, vamos a ver
   cmo cargar la imagen PCX.

   Inmediatamente despus del encabezado, siguen los datos de la imagen,
   los cuales se interpretan de la siguiente forma:

   Empezando despus del encabezado de 128 bytes, leemos un byte.

   Si los dos bits ms significativos valen cero, entonces el byte
   es un byte de datos y simplemente lo almacenamos en la memoria.

   Si los dos bits ms significativos valen uno, entonces el byte
   es un contador que indica el nmero de veces que se repite el
   siguiente byte.


   Para comprobar los dos bits ms significativos, usamos los siguiente:

   if ((N and $C0) = $C0) then { los bits estn activados }
                          else { los bits estn desactivados }

   En el caso de que los bits superiores estn activos, entonces usamos
   ese byte como contador, pero DESACTIVANDO los dos bits superiores, ya
   que stos solo sirven para indicar que el byte que lemos es un contador.

   Para desactivar los dos bits superiores solamente hacemos la operacin
   lgica AND del byte que lemos con el valor $3F.


   Todo lo anterior, en Pascal se dice as:


        read(Archivo, dato);
        if ((dato and $C0) = $C0)
        then
        begin
             contador := dato and $3F;
             read(Archivo, dato);
             for i := 1 to contador do
             begin
                  Imagen^[pos] := dato;
                  inc(pos);
             end;
        end
        else
        begin
             Imagen^[pos] := dato;
             inc(pos);
        end;


   En el procedimiento anterior, se asume que Imagen es un apuntador a
   un arreglo de bytes lo suficientemente grande como para almacenar
   nuestra imagen. Y la variable pos es simplemente el ndice del byte
   que se est leyendo en ese momento. Recuerden que la imagen NO debe
   de ser mayor de 64 Kbytes.


   Al final del archivo, los ltimos 768 bytes representan las entradas de
   la paleta de colores. Estas entradas estn en el formato RGB con
   valores de 0 a 255, es decir que debemos dividir entre 4 todos los
   bytes de informacin de la paleta para obtener valores de 0 a 63.


   Esto se puede hacer de la siguiente forma:


        seek(archivo, filesize(archivo) - 768);
        for i := 0 to 255 do
        begin
             read(archivo, r, g, b);
             r := r div 4;
             g := g div 4;
             b := b div 4;
             SetPalette(i, r, g, b);
        end;


   As de fcil.

   El procedimiento para cargar PCX's se encuentra ya en la unidad
   MODE_13.PAS y tiene la siguiente sintaxis:


   LoadPCX(archivo : string; where, dimX, dimY,
           OffX, OffY : word; pal : TPalette);


   donde:  archivo es el nombre del archivo PCX (incluyendo ruta de acceso)
           where   es la pantalla virtual (puede ser VGA) donde se va a
                   visualizar la imagen.
           dimX, dimY son las dimensiones de la imagen en pxels.
           OffX, OffY es la posicin en la pantalla donde se va a mostrar
                      la imagen. Se refieren a la esquina superior izquierda.
           pal es la paleta en donde se va a almacenar la paleta del archivo.


   Como pueden ver, en vez de almacenar la imagen en un arreglo, la
   cargamos directamente en una pantalla virtual. Esto es porque la mayora
   de las veces no se desea almacenar la imagen, sino solamente mostrarla.

   Si queremos almacenar la imagen en un arreglo, podemos usar la funcin
   GetPixel.


   Ejemplo: { de cmo cargar una imagen }


           var MiPaleta : TPalette;

           begin
                SetMode13;
                LoadPCX('miimagen.pcx', VGA, 320, 200, 0, 0, MiPaleta);
                SetPalette(MiPaleta);
                readkey;
                SetTextMode;
           end;


   El ejemplo anterior carga la imagen del archivo 'miimagen.pcx'
   directamente a la pantalla. La imagen debe tener una dimensin de
   320 * 200, por lo tanto, ocupa TODA la pantalla, y es por eso que
   la mostramos en (0, 0). Si hubiramos usado otra posicin para la
   imgen, como por ejemplo:

           LoadPCX('miimagen.pcx', VGA, 320, 200, 100, 100, MiPaleta);

   Entonces la esquina superior izquierda de la imagen quedara en la
   posicin (100, 100), lo que significa que la imagen no cabra en
   la pantalla y lo que veramos seran pedazos de imagen por toda la
   pantalla. As que tengan cuidado de dnde colocan su imagen.

   Recuerden que:

             OffX + DimX debe ser menor que 320
             OffY + DimY debe ser menor que 200


   El programa de ejemplo PCX1.pas simplemente carga una imagen que ha
   sido escaneada y la muestra en la pantalla. Se han omitido los comentarios
   debido a que el procedimiento LoadPCX es la que hace todo el trabajo.

   Recuerden que LoadPCX se encuentra en Mode_13.pas


   Bsicamente, esto es toda la teora referente a pantallas virtuales
   y archivos PCX. Lo dems es prctica y EXPERIMENTACION. Si encuentran
   un programa de ejemplo llamado EFECTO1.PAS junto con este tutorial,
   es porque SI tuve tiempo de hacerlo :).

   Espero que lo encuentren, porque ah viene cmo utilizar conjuntamente
   los archivos PCX, las pantallas virtuales y los arreglos precalculados.

   La idea bsica es esta:

      1.- Se usan dos arreglos precalculados como matrices de
          transformacin para una imagen. Se usa un arreglo para
          transformar las coordenadas X, y otro arreglo para
          transformar las coordenadas Y.

      2.- Se carga la imagen desde un archivo PCX a una pantalla
          virtual y de ah de pasa a un arreglo.

      3.- Se borra la pantalla virtual :)

      4.- Se vuelve a dibujar la imagen desde el arreglo en el que
          se guard, PERO obteniendo las coordenadas con las matrices
          de transformacin.

      5.- Nos movemos un poco dentro de la matriz de transformacin
          y repetimos desde el paso 4. De esta forma, la imgen se
          estar deformando contnuamente.


      El programa EFECTO1.PAS cuenta con una gran DEFICIENCIA de
      comentarios. No tengo tiempo de co-mentarles todo el programa
      as que tendrn que deducirlo ustedes mismos. Si tienen alguna
      duda, mndenme un e-mail con las preguntas que tengan y la
      parte del programa a la que se refieren.


      Quiero hacer notar que este programa surgi de LA EXPERIMENTACION.
      Nadie les va a decir cmo obtener una matriz de transformacin,
      excepto para algunos efectos como llamas y lentes, pero cuando
      quieran inventar algn efecto extrao, tendrn que experimentar.

      Prueben a experimentar todo lo que quieran con este programa.
      Aqu hay algunas ideas:

           - Alteren la matriz de transformacin. Eso se hace cambiando
             funciones y constantes en el procedimiento SetTransMatrix.

           - Alteren las ecuaciones que hacen el desplazamiento en la
             matriz de transformacin, es decir, las que modifican a
             xp y yp.

           - Usen mas de una matriz de transformacin.

           - Expriman su cerebro y usen todo lo que saben sobre
             trigonometra, geometra, ptica, etc. Aunque no lo
             crean, esas cosas funcionan.


CONCLUSIONES:


             - Creo que despus de haber visto el programa anterior,
               no necesitamos conclusiones. Lo importante aqu es
               usar todo lo que saben. Es decir, ustedes pueden dibujar
               pxels, crculos, lneas, pueden rotar la paleta, pueden
               mostrar imgenes PCX y pueden eliminar cualquier parpadeo.
               Bien, pues ahora hagan TODO ESO al mismo tiempo.

               Aqu hay algunas cosas que pueden hacer:


               1.- Traten de obtener una imagen de un fractal. Les
                   recomiendo un "plasma" o el mar de Mandelbrot.
                   Conviertan la imagen a PCX (con algn programa
                   comercial) y muestrenla en su programa. Ahora hagan
                   rotaciones de paleta y vean los resultados. Algunos
                   plasmas se ven realmente bien.

                   Existe un programa llamado FractInt que genera
                   fractales de TODO tipo. Pueden obtener un nmero
                   infinito de plasmas, mandelbrots y julias.

                   Interesados, comunquense conmigo.


               2.- Ya vimos una forma de "desaparecer" una imagen de la
                   pantalla, recuerdan? Lo llamamos FadeOut y lo que
                   haca era oscurecer poco a poco la pantalla.
                   Bueno, ahora utilicen lneas y crculos para borrar
                   la pantalla de una forma ms interesante.
                   Podran empezar dibujando un crculo en el centro de
                   radio 1 y de color negro e ir incrementando el radio.


               3.- Una modificacin del efecto anterior:

                   Vayan dibujando crculos con centro en (160,100) cada
                   vez de radio mayor, pero en lugar de dibujarlos de
                   color negro, tomen el color de los puntos de OTRA
                   imgen que esta en una pantalla virtual. La idea
                   principal es esta:

                   PutPixel(x, y, GetPixel(x, y, VirSeg), VGA);


               4.- Otra modificacin del efecto anterior:

                   En lugar de crculos (que son muy lentos), utilicen
                   lneas verticales, horizontales, diagonales, bloques,
                   rectngulos o cualquier otra cosa.


EJERCICIOS: (Vean las conclusiones)


Bueno, este ha sido el cuarto tutorial y creo que tengo tiempo para otro
ms antes de vacaciones. An no quiero entrar al tema de las tres
dimensiones porque eso nos llevara 3 o 4 tutoriales. Las ideas que tengo
para el siguiente tutorial son:

     a) Cmo hacer scroll de pantalla completa y letreros.
     b) Usar todo lo que hemos visto para hacer un micro-demo.
     c) No hacer ningn tutorial (hasta despus de vacaciones).


Dganme cul opcin prefieren. Si no recibo ninguna idea, voy a tomar el
inciso a) por default, si es que tengo tiempo. Si no tengo tiempo ser
el inciso c).


RIMAS DE LA SEMANA: (no tienen que imprimir esta parte)


      - "Today I didn't even have to use my A.K.,
         I gotta say it was a good day"

         Por: Ice Cube


      - "Go get yourself some toilet paper cause your lyrics is butt!"
        (no recuerdo la otra lnea pero esa es excelente)

        Por: Phife Dawg


      - "I know where I'm from, not dum diddie dum
         from the base motherland, the place of the drum"

        Por: Chuck D


      - "I'm the king of rock, there is none higher
         sucker MC's should call me sire
         To burn my kingdom you must use fire
         I won't stop rockin till I retire"

         Un clsico, por: DMC


ANUNCIO: (este tutorial se est haciendo muy comercial :( )

         - Algn interesado en msica MOD, S3M, XM, IT ??? Necesito
           conseguir / intercambiar samples, instrumentos, canciones, etc.

         (Si no saben de qu estoy hablando, simplemente busquen
          "Computer generated music / MOD Format" en el Yahoo)


Eso es todo por esta semana.

----------------------------- CORTAR AQUI ----------------------------------
