Revistas en papel
 Commodore World Nº50
Anterior
Menú
Logotipo

AMIGA WORLD

FICHEROS IFF DESDE BASIC

Por Fernando Marcos

Es el formato
estándar de
ficheros en
el Amiga. Se
llama
Interleaved
File Format,
o, como lo
conoce todo
el mundo,
IFF. Su
diseño
permite,
entre otras
cosas, que
todos los
programas
del Amiga
sean
compatibles
entre si.

¿Quién no se ha tropezado en algún momento de su vida con el Amiga con uno de esos encantadores ficheros que son como un dios intocable al que no podemos ni mencionar, ni abrir, esos ficheros llamados IFF? ¿Quién no le ha escupido alguna vez a Deluxe Paint cuando le ha arrojado uno de esos farragosos mensajes diciendo "IFF File is Mangled", o sea, que todo un trabajo de meses se ha perdido porque se grabó mal una cabecera?

Mencionaré el triple problema del grafista un poco serio que trabaja con AmigaBasic (casi todos, vaya): primero, Deluxe Paint no escribe ficheros en formato reconocible por el Basic. Segundo, el Basic no escribe ficheros reconocibles por Deluxe Paint. Tercero, el ObjEdit no es un intento fallido de programa generador de gráficos... es mucho peor. Pero, vaya, esto es lo que hay. O más bien lo que había. Con los programas que aparecen en este artículo podrás hacer que se hablen Deluxe Paint (o cualquier generador de gráficos IFF, es decir, todos) y el Basic. Lógicamente, como no se puede modificar el programa Deluxe Paint, hay que desarrollar los programas en Basic.


Estructura de los IFF

¿Quién no se lo ha preguntado? Bien, los ficheros IFF son una especie de "contenedores de ficheros". Me explico. Un fichero IFF es un fichero secuencial (lo cual es lógico, porque no hace falta para nada que sea aleatorio), que a su vez contiene otros ficheros más pequeños dentro de sí mismo, cada uno de los cuales contiene un tipo de información.

Según el tipo de IFF, sus ficheros internos, llamados "chunks", son diferentes (la traducción de chunk es algo así como "bloque" o "trozo", pero lo dejaremos en inglés). Los chunks se identifican siempre por cuatro bytes, que suelen corresponder a una abreviatura en ASCII. Gracias a los chunks, si un programa necesita un gráfico, pero no le interesa la información sobre el color o la animación de ese gráfico puede saltarse el chunk correspondiente sin peligro. En los ficheros de gráficos, que son los que vamos a estudiar en este artículo, se utiliza el tipo de ficheros IFF llamados ILBM (Interleaved Bit Map). Este es el formato que utilizan todos los programas de gráficos que se precien de serlo.


Paso a paso

Coge tu sistema operativo favorito (digamos el Workbench) y conecta el ordenador. Cuando estés en el Workbench propiamente dicho (entorno de ratón), abre un CLI, para poder pedirle al ordenador que haga un par de cositas. Una vez que el CLI esté abierto, dimensiónalo a toda pantalla con el gadget de tamaño (esquina inferior derecha). Localiza un disco donde tengas algún fichero IFF, concretamente del tipo ILBM (Deluxe Paint, Graphicaft, etc) y teclea:

   TYPE ?

Aparecerá una sere de palabras indicando las posibles opciones del comando. Cambia el disco por el de gráficos y teclea el nombre del fichero en cuestión, seguido de "OPT H", para obtener un volcado hexadecimal. El cuadro de la figura 1 es un ejemplo de Deluxe Paint para que puedas estudiarlo sobre la marcha.

   DIBUJO OPT H
   DIBUJO OPT H > PRT: (si tienes impresora)

Pulsa RETURN. En la pantalla debería aparecer un volcado hexadecimal de lo que contiene el fichero. A la izquierda en hexadecimal y a la derecha en caracteres ASCII. Los bytes que no tienen representación en este formato aparecen como puntos. Puedes parar el listado pulsando la barra de espacios o el botón derecho del ratón.

Vamos a ver byte a byte lo que contiene el fichero. Nada más empezar hay cuatro letras, "FORM" (la cabecera del chunk), que indican que están trabajando con un fichero IFF, aunque todavía no sabes de qué tipo es. Los cuatro bytes que siguen indican la longitud total de este trozo del fichero. En realidad, FORM es un chunk, que contiene a su vez todos los chunks del fichero. Por tanto, la longitud de FORM representa la longitud total del fichero menos los ocho primeros bytes. Para calcular la longitud de un chunk, se hace lo siguiente:

   Primer byte multiplicado por 16777216
   Segundo byte multiplicado por 65536
   Tercer byte multiplicado por 256
   Cuarto byte tal cual

Ahora suma todos estos valores. SI entras en el chunk FORM verás que contiene varios chunks a su vez. El primero es el identificador ILBM, que indica que el fichero contiene gráficos. Dado que ILBM no es un chunk, sino una información colocada por convención, lleva una longitud detrás. Lo que sí que encontrarás en otro chunk: el BMHD, abreviatura de Bit Map Header (Cabecera del Bit Map).

Este chunk SIEMPRE debe aparecer, ya que contiene información sobre el ancho, el alto, el número de planos y otros datos del dibujo. Si calculas su longitud verás que es de veinte bytes, que se distribuyen así:

   2 bytes: Ancho de la imagen
   2 bytes: Alto de la imagen
   2 bytes: Posición X original dentro de la pantalla
   2 bytes: Posición Y original
   1 byte: Número de planos
   1 byte: Tipo de enmascaramiento (relación con el fondo)
   1 byte: Tipo de compresión (ver más adelante)
   1 byte: Byte vacío, sin usar. Debe ser cero.
   2 bytes: Color transparente. Suele ser cero.
   1 byte: Proporción X
   1 byte: Proporción Y. Similar al ASPECT del Basic.
   2 bytes: Ancho de la pantalla original.
   2 bytes: Alto de la pantalla original. Es el tamaño del SCREEN del que se tomó el dibujo.
   
   Total 20 bytes

Veamos qué es esta parafernalia de bytes. Mira el listado que sacaste antes (o el de la figura 1) y comprueba si coincide con estos cálculos. Observa el chunk BMHD. Le siguen cuatro bytes que tienen al final un $14 (20 en decimal) de momento la longitud coincide con los veinte bytes previstos.

Los dos bytes que siguen son $0140 y $00C8, que son respectivamente 320 y 200 en decimal. Este es el tamaño original del dibujo, y según parece, ocupaba toda la pantalal (si era de 320x200, claro). Ahora vienen las coordenadas originales del dibujo, representadas en palabras de 16 bits. Bien, aparecen los bytes $0000 y $0000, que si no me equivoco son 0 en decimal. Esto significa que el dibujo comenzaba en las coordenadas (0,0), es decir, en la esquina superior izquierda. Ahora viene el número de planos que contenía el dibujo, en un solo byte. $05 es cinco planos, calculando, 2 elevado a 5 son 32 colores. Todo esto coincide con un típico dibujo de Deluxe Paint.

0000:  464F524D  0000136A  494C424D  424D4844  FORM...jILBMBMHD
0010:  00000014  014000C8  00000000  05020100  .....@..........
0020:  00000A0B  014000C8  434D4150  00000060  .....@..CMAP...'
0030:  000000E0  C0A0E000  00A00000  D08000F0  ................
0040:  E00080F0  00008000  00B06000  D0D000A0  ..........'.....
0050:  F00070C0  0000F070  00F0C000  E0C00080  ..p....p........
0060:  602000E0  5020A050  20F0C0A0  30303040  ` ..P .P ...000@
0070:  40405050  50606060  70707080  80809090  @@PPP``'ppp.....
0080:  90A0A0A0  C0C0C0D0  D0D0E0E0  E0F0F0F0  ................
0090:  44505056  00000068  00000000  00000000  DPPV...h........
00A0:  01680000  014000C8  0002005A  00040000  .h...@.....Z....
00B0:  00040000  00040000  00000000  00000000  ................
00C0:  00000000  00000000  00000000  00000000  ................
00D0:  00000000  00000000  00000000  00010002  ................
00E0:  00000000  00000000  00000000  00010002  ................
00F0:  00000000  00000000  00000000  00010002  ................
0100:  43524E47  00000008  00000AAA  0001141F  CRNG............
0110:  43524E47  00000008  00000AAA  00010307  CRNG............
0120:  43524E47  00000008  00000AAA  00010000  CRNG............
0130:  43524E47  00000008  00000AAA  00010000  CRNG............
0140:  424F4459  00001229  D900D900  D900D900  BODY...)........
0150:  D900D900  D900D900  D900D900  D900D900  ................
0160:  D900D900  D900D900  D900D900  D900D900  ................
0170:  D900D900  D900D900  D900D900  D900D900  ................
0180:  D900D900  D900D900  D900D900  D900D900  ................
0190:  D900D900  D900D900  D900D900  D900D900  ................
01A0:  D900D900  D900D900  D900D900  D900D900  ................
01B0:  D900D900  D900D900  D900D900  D900D900  ................
01C0:  D900D900  D900D900  D900D900  D900D900  ................
FIGURA 1: Ejemplo de fichero IFF, en volcado hexadecimal

Lo siguiente que viene es el enmascaramiento. Hay cuatro tipos de enmascaramiento:

   0: No enmascaramiento.
   1: La máscara se incluye con la imagen.
   2: Partes de la imagen son transparentes.
   3: Indica un tipo de máscara especial ("lasso")

El enmascaramiento te dice si un pixel hay que copiarlo o no a su destino, creando efectos de ocultamiento .Si el byte de enmascaramiento es cero, el enmascaramiento no existe, y todo el dibujo aparece tal y como es. Si el byte es 1, en el dibujo, además de incluir la información sobre éste, se incluirá una información extra sobre cómo está codificado el enmascaramiento. Si es 2, uno de los colores del dibujo será transparente. Si colocas ese dibujo encima de otro, verás a través de las zonas de ese color transparente el dibujo que haya debajo.

Si el byte es 3, la cosa se complica. Este es un enmascaramiento poco empleado, pero realmente espectacular.

Bueno, en nuestro ejemplo el byte de enmascaramiento del dibujo que tenemos entre manos es dos, por lo que algunas partes del dibujo serán transparentes. Ya veremos más tarde qué colores serán transparentes.

Ahora viene en un byte el formato de compresión empleado. Si está a cero, la información no está comprimida, pero si no es cero, se identifica con el tipo de compresión empleada. La compresión de ficheros se utiliza para ahorrar espacio en el disco. La más común es la conocida por "CmpByteRun1", farragoso nombre de la rutina creada por Electronic Arts para comprimir información. Más adelante explicaré en qué consiste.

Nuestro gráfico en particular está comprimido. Muy bien. Ahora viene un byte, que siempre está a cero. Todavía no tiene utilización, pero está ahí por si alguien lo necesita. Ahora, en dieciséis bits se indica cuál es el color que será transparente en nuestro dibujo. Los bytes contienen el valor cero, y, por tanto, ese será el color el transparente (el color 0 de la paleta). Por último, se incluyen dos bytes que indican la proporción entre X e Y en este dibujo. Así es posible obtener conversiones de formato sin que el dibujo quede aplastado. Incluso se pueden transferir a otros ordenadores... Por fin vienen dos palabras de dieciséis bits que indican el tamaño del SCREEN de donde se obtuvo el dibujo. Verás que vuelve a ser 320x200. COnclusiones: el dibujo (comprimido) es una pantalla completa tomada de una pantalla de 320x200, en 32 colores. No está mal para empezar...


Colores

Bien, en un dibujo también hay que definir los colores. Para eso hay otro chunk particular que encontrarás a continuación el CMAP. El formato de los colores cambia bastante entre el Basic y los IFF. Aquí los colores son el nibble alto de un byte. Cada color se define por tres bytes consecutivos. Y el rango de colores varía entre cero y quince. por tanto, un color que sea roja=6, verde=4 y azul=14 sería:

   $60 $40 $E0

El número de colores se conoce de antes (viene en el Chunk BMHD). Por tanto, habrá que comprobar que el número de colroes esté bien. Para ello, se toma la longitud del chunk (como al principio), y se divide entre tres, para obtener el número de colores. si no coincide, el fichero está corrupto ("mangled" dice el Deluxe Paint...). Bien, en el ejemplo la pantalla es de 32 colores. Y el chunk indica una longitud de $60 bytes, es decir, 96 bytes. A tres bytes por color, 96/3 da los 32 colores supuestos. En realidad, no es necesario efectuar esta comprobación, porque no creo que nadie tenga la mala uva de poner a propósito chunks cambiados para protegerlos, pero ya se sabe...

Ahora vienen una serie de chunks no-estándar que no afectan al resultado final. Hay uno particular de Deluxe Paint, llamado DPPV, y luego toro que contiene la definición del ciclo de colores, llamado CRNG (Color Range). Tampoco interesan. El siguiente chunk sí que interesa: se llama BODY, y contiene la información gráfica propiamente dicha. Aquí es donde van los planos del dibujo que forman la imagen. Su estructura se explica en el siguiente punto.

Ahora que has terminado de ver cómo es una cabecera tipica ILBM, podrás estudiar algunos de los puntos que no se explicaron antes.


Compresión

El byte de compresión indica el método de compresión utilizado. Normalmente es cero o uno, cero para no-compresión, y uno para CmpByteRun. Si tú mismo te crear un formato de compresión eficaz, no hay problema para que le asignes, por ejemplo, el número dos y grabes con él tus dibujos favoritos... pero no esperes que luego Deluxe Paint lo reconozca.

Bien, vamos a ver el formato del dibujo. Recuerda que la pantalla del Amiga está formada por varios planos que codifican los colores. Por tanto, habrá que cargar cada plano. Lo más lógico hubiera sido grabar plano tras plano, para que quede en la memoria de forma secuencial. Aunque éste sea el método más cómodo, no se emplea porque tiene un inconveniente: Si se estropea parte de un fichero, no se pueden cargar los planos que hay detrás del error, por lo que el dibujo queda desfigurado. ¿Qué es lo que se hace entonces?

Muy fácil, se graba fila por fila la pantalla completa, con sus cinco planos, en este formato:

   Línea 0, plano 0
   Línea 0, plano 1
   Línea 0, plano 2, etc., hasta terminar todos los planos.
   Línea 1, plano 0
   Línea 1, plano 1.

Y así hasta el final. La ventaja de este método es que si ocurre un error de disco, el dibujo será recuperable hasta la línea donde aparezca el error, porque esa información ya está en pantalla. En la práctica, cargamos 40 bytes si la pantalla es de 320 puntos horizontales (80 si es de 640), lo colocamos en el plano 0, cargamos otros 40, los colocamos en el plano 1, y así hasta el final. El problema viene cuando el fichero es´ta comprimido. En este caso, se comprime CADA FILA antes de grabarla a disco. Para ello, se lee el primer byte de la fila, (n) y se actúa de este modo:

   Si n está entre 0 y 127, se lee el siguiente byte del disco y se copian literalmente
   los n + 1 bytes siguientes a memoria.
   Si n está entre -1 y -127 se lee el siguiente byte y se copia -n + 1 veces en la memoria.
   Si n es -128, no se hace nada.

Una vez terminada esta descompresión parcial se lee otro byte N y se vuelve a repetir la operación hasta se termine con toda la fila. Luego se comienza con el siguiente plano de esa fila, hasta terminar con todos los planos y pasar a la siguiente fila.


Programas en Basic

Admito que leer las cabeceras IFF a mano es una labor incluso divertida, pero cuando se llevan unas cuantas cabeceras leídas, el trabajillo empieza a cansar notablemente. Estaba yo ya harto de hacerlo cuando recordé (una vez más) que para eso se diseñaron los ordenadores. El resultado ha sido la rutina IFF-DUMP. Esta rutina deja al desnudo cualquier fichero ILBM que se le pase por delante. Al ejecutarla pide el nombre del fichero, y la salida por pantalla o por impresora. Nos dará toda la información que hasta ahroa hemos obtenido a mano, incluido un listado de todos los colores empleados.

El segundo programa se llama IFF-VIEW. Permite tomar cualquier fichero gráfico ILBM (menos los que sean HAM) y mostarlo en pantalla, cualquiera que sea su formato interno (comprimido o no comprimido). Pero hace algo más: de la pantalla obtenida se pueden "recortar" pedazos y luego grabarlos a disco en formato MOB, para utilizarlos después en otros programas.

Su funcionamiento es muy sencillo: al arrancar pide el nombre del fichero ILBM. Después lee sus cabeceras y genera un screen y un window que se ajusten a su formato. Esto es sencillo conociendo el formato de la pantalla del Amiga (hay una explicación completa en el artículo "Conoce mejor a tu Amiga", publicado en el número 48 página 35). Si no lo has leído (no sabes lo que te pierdes), lo que se hace en realidad es "escribir" la pantalla meidante POKEs directos a memoria. Aquí surge una pequeña pega.


Otro combate ganado

El Amiga me dio otra sorpresa de las suyas mientras escribía estos programas. Creé una pantalla de 320x200 en 32 colores, para trabajar con ella directamente a base de POKEs. Quise poner el primer byte de cada plano encendido, para probar. Así que calculé la longitud de la pantalla en bytes (40 bytes por fila por 200 filas = 8000 bytes), y luego deduje la posición del resto de los planos a partir de ahí. Si el primer plano estaba en la posición 20000, el segundo estaría en la 28000, el tercero en la 36000, etc. Hice un POKE al primer plano, al segundo, etc. Y todo iba bien. Pero al llegar al quinto plano, al hacer POKE todo se me fue a la porra.

Como al principio, fue porque supuse que los planos eran consecutivos en memoria, pero en realidad no era así .No me quedaba más remedio que dejarlo para otro momento. Pero se me ocurrió ver si los vectores que había a continuación apuntaban a los otros planos. ¡Eureka!, así es. Los vectores 19022, 19026, 19030, 19034 y 19038 apuntan a los planos de una pantalla de 32 colores.

Lo que más interesa del programa es su habilidad para crear MOBs que se puedan cargar con enorme facilidad desde Basic. Y con muy poco esfuerzo pueden convertirse en sprites. Bien, vamos a ver cómo se hace.

Primero, carga el dibujo. Cuando la zona que te interese esté en pantalla, pulsa ESC y espera a oír el beep que indique que se ha terminado de cargar esa línea de pantalla. Ahora, con el ratón, apunta a la esquina superior izquierda del dibujo, y, con el botón pulsado, muévelo hasta la otra esquina. Verás cómo la zona de dibujo que quieres "llevarte" se pone en inverso. Suelta el botón. Si no te gusta la toma, la puedes repetir cuantas veces quieras. Cuando estés contento, pulsa la barra de espacios y el programa te pedirá un nombre de fichero. Se grabará en formato MOB. Para cargarlo, nada más fácil que teclear en tu programa estas líneas.

   OPEN "nombre" FOR INPUT AS 1
   OBJECT.SHAPE NoObjeto,INPUT$(LOF(1),1)
   CLOSE 1

Y ya está. Ahora lo puedes colocar en pantalla con OBJECT.X y OBJECT.Y, moverlo, encenderlo, apagarlo, etc. Además, carga a GRAN velocidad. Dado que esta toma de objetos (sobre todo si la pantalla es de muchos colores y los objetos van a ser muy grandes) puede ocupar muchísima memoria, es recomendable hacer un CLEAR antes de cargar el programa, para dejar memoria disponible.

De todas formas, he incluido una pequeña ayuda. Si después de seleccionar la zona que quieres tomar deseas ver la memoria que va a ocupar, pulsa HELP. Aparecerá en la esquina superior izquierda el número de bytes aproximados que va a ocupar. Y ten en cuenta, claro, que un objeto de 32 colores debe ser representado en un screen de 32 colores, y que la paleta NO va en la definición del mob, por lo que debes definirla de nuevo "a mano" en el programa que crees.

El último programa se llama IFF-TRANSFER, y sirve para pasar una pantalla estándar del Basic a fichero IFF: Genera un fichero de 640x256 de alto, a cuatro colores, Recuerda además que lo hacen en formato no-comprimido, para aumentar la velocidad.

Bien, ya sabes cómo son los ficheros IFF por dentro. Ahora sigue investigando por tu cuenta... ¡Hay mucho que ver!

LISTADO 1

Programa IFF.DUMP
 
'Raiders of the lost IFF.                                                    .339
'  Lector de cabeceras IFF. Rev 2.46                                         .799
'  F.Marcos 1988.   Hola QE2!!                                               .638
 
SUB DEC (t$) STATIC                                                          .372
PRINT#1, ((ABC(LEFT$(t$,1)))*256)+(ASC(RIGHT$(t$,1)))                        .291
END SUB                                                                      .214
 
 
CLS:INPUT "Nombre del fichero";a$                                            .446
INPUT "(P)antalla o (I)mpresora [P]:",d$                                     .106
IF d$="" OR UCASE$(d$)="P" THEN de$="SCRN:"                                  .290
IF UCASE$(d$)="I" THEN de$="PRT:"                                            . 44
 
IF de$="" THEN PRINT "Periferico incorrecto, asumido PANTALLA.":de$="SCRN:"  .807
 
OPEN a$ FOR INPUT AS 2                                                       .714
n=4:GOSUB Fread                                                              .765
IF z$<>"FORM" THEN    'Fichero no IFF                                        .309
PRINT "El fichero "a$" no es IFF."                                           .433
CLOSE:END                                                                    .404
END IF                                                                       .654
n=4:GOSUB Fread       'Longitud del chunk                                    .310
n=4:GOSUB Fread       'Tipo de fichero.                                      .648
IF z$<>"ILBM" THEN    'No son graficos.                                      .  5
PRINT "El fichero "a$" no es de graficos."                                   .381
CLOSE:END                                                                    .404
END IF                                                                       .654
OPEN de$ FOR OUTPUT AS 1                                                     .530
PRINT#1,"Fichero: "a$:PRINT#1,STRING$(50,"=")                                .877
 
MoreChunks:                                                                  .301
n=4:GOSUB Fread       'Busca otro chunk.                                     .674
IF z$="BMHD" THEN BMHD                                                       .450
IF z$="CMAP" THEN CMAP                                                       .657
IF z$="BODY" THEN CLOSE:END                                                  .470
 
PRINT#1, "Cabecera no estandar: ";:COLOR 0,1:PRINT#1, z$;                    .838
COLOR 1,0:PRINT#~1,"":PRINT#1,STRING$(30,"-")                                .648
GOSUB ChunkSize       'Saltarse esos V bytes.                                . 32
n=V:GOSUB Fread                                                              .390
GOTO MoreChunks                                                              . 87
 
CLOSE:END                                                                    .404
 
 
Fread:                'Lee N bytes del fichero.                              .182
'Devuelve en Z$                                                              . 57
z$=INPUT$(n,2)                                                               .400
RETURN                                                                       .357
 
BMHD:                 'Decodifica cabecera BMHD.                             .984
COLOR 0,1:PRINT#1, "Chunk BMHD encontrado -->"                               . 89
COLOR 1,0                                                                    .496
n=4:GOSUB Fread       'Se salta la longitud del Chunk                        .806
n=2:GOSUB Fread                                                              .958
PRINT#1,"-->  Ancho:            ";:Dec z$                                    .165
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  Alto:            ";:Dec z$                                    .749
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  Origen X:        ";:Dec z$                                    .476
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  Origen Y:        ";:Dec z$                                    .483
n=1:GOSUB Fread:n$=CHR$(0)+z$                                                .120
PRINT#1, "-->  No. Planos:      ";:Dec n$                                    .712
IF ASC(z$)=6 THEN PRINT#1, TAB(20)"(Pantalla HAM)"                           .921
n=1:GOSUB Fread:z$=CHR$(0)+z$                                                .960
PRINT#1, "-->  Enmascaramiento: ";:Dec z$                                    .974
n=1:GOSUB Fread:n$=CHR$(0)+z$                                                .120
PRINT#1, "-->  Compresion:      ";:Dec n$                                    .939
IF ASC(z$)=0 THEN PRINT#1, TAB(20)"(Ninguna.)"                               .532
IF ASC(z$)=1 THEN PRINT#1, TAB(20)"(cmpByteRun1)"                            .240
IF ASC(z$)>1 THEN PRINT#1, TAB(20)"(Sistema no estandar.)"                   .322
n=1:GOSUB Fread:n$=CHR$(0)+z$                                                .120
PRINT#1, "-->  Byte Cero (0):   ";:Dec n$                                    .946
IF ASC(z$)<>0 THEN PRINT#1, TAB(20)"(Este byte deberia ser cero)"            .880
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  C. Transparente: ";:Dec z$                                    .153
n=1:GOSUB Fread:z$=CHR$(0)+z$                                                .960
PRINT#1, "-->  Prop X:          ";:Dec z$                                    .531
n=1:GOSUB Fread:z$=CHR$(0)+Z$                                                .960
PRINT#1, "-->  Prop Y:          ";:Dec z$                                    .874
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  Ancho Screen:    ";:Dec z$                                    .130
n=2:GOSUB Fread                                                              .958
PRINT#1, "-->  Alto Screen:     ";:Dec z$                                    .730
PRINT#1, "------------------------------Fin Chunk BMHD"                      .358
GOTO MoreChunks                                                              . 87
 
CMAP:       'Decodifica los colores.                                         .970
GOSUB ChunkSize        'lee la longitud.                                     .902
v=v/3                  'numero de colores...                                 . 38
 
COLOR 0,1:PRINT#1, "Chunk CMAP encontrado -->";:COLOR 1,0                    .306
PRINT#1,""                                                                   . 44
PRINT#1, "Color","Rojo","Verde","Azul"                                       . 45
FOR a=1 TO v                                                                 .707
PRINT#1, "Palette"a":",                                                      .906
FOR zz=1 TO 3                                                                .742
n=1:GOSUB Fread                                                              .555
PRINT#|, ASC(z$)/16,                                                         .593
NEXT                                                                         . 61
PRINT#1,""                                                                   . 44
NEXT                                                                         . 61
PRINT#1, "-------------------------------Fin Chunk CMAP"                     .367
GOTO MoreChunks                                                              . 87
 
ChunkSize:            'Calcula la longitud                                   .904
'del siguiente Chunk.                                                        .175
n=1:GOSUB Fread:v1=ASC(z$)*16777216&                                         . 23
n=1:GOSUB Fread:V2=ASC(z$)*65536&                                            .825
n=1:GOSUB Fread:V3=ASC(z$)*256                                               .743
n=1:GOSUB Fread:V4=ASC(z$)                                                   .605
v=v1+v2+v3+v4                                                                .205
RETURN                                                                       .357
 
Numero de lineas: 101

LISTADO 2

Programa: IFF.VIEW
 
'Raiders of the lost IFF.                                                    .339
'   Rutina para cargar ficheros IFF Rev 3.2   1                              .770
'   Con compresion (CmpByteRun1) o                                           .247
'   sin compresion.                                                          .400
'  F.Marcos 1988.   Hola QE2!                                                .629
 
DEFINT a-Z                                                                   .433
DIM Pal!(2,32)                                                               .847
SUB Conv(n) STATIC                                                           .514
SHARED Cn                                                                    .309
IF n=>128 THEN Cn=-128+(n AND 127) ELSE Cn=n                                 .616
END SUB                                                                      .214
 
SUB Fread (n%) STATIC                                                        .647
SHARED Z$                                                                    .918
Z$=INPUT$(n%,1)                                                              . 62
END SUB                                                                      .214
 
SUB ChunkSize STATIC                                                         .248
SHARED CZ,Z$                                                                 .798
Fread 1:v1=ASC(Z$)*16777216&                                                 .332
Fread 1:v2=ASC(Z$)*65536&                                                    .756
Fread 1:v3=ASC(Z$)*256                                                       .836
Fread 1:v4=ASC(Z$)                                                           .221
CZ=v1+v2+v3+v4                                                               .106
END SUB                                                                      .214
 
SUB ReadByt STATIC                                                           .552
SHARED BY                                                                    .113
BY=ASC(INPUT$(1,1))                                                          .952
END SUB                                                                      .214
 
SUB ReadWord STATIC                                                          .718
SHARED WD                                                                    .995
WD=(ASC(INPUT$(1,1))*256)+ASC(INPUT$(1,1))                                   .133
END SUB                                                                      .214
 
SUB BMHD STATIC                                                              .704
SHARED ScX,ScY,an,Al,Pl,com,BY,WD                                            .126
Fread 4                                                                      .731
CALL ReadWord:an=WD                                                          .998
CALL ReadWord:Al=WD                                                          .829
Fread 4                                                                      .731
CALL ReadByt:Pl=BY                                                           .582
Fread 1                                                                      .710
CALL ReadByt:com=BY                                                          .260
Fread 5                                                                      .738
CALL ReadWord:ScX=WD                                                         .569
CALL ReadWord:ScY=WD                                                         .972
WHILE ScX/8<>INT(ScX/8):ScX=ScX+1:WEND                                       .154
IF ((ScX/8) AND 1)=1 THEN ScX=ScX+8                                          .195
END SUB                                                                      .214
 
SUB CMAP STATIC                                                              .605
SHARED CZ,Pal!()                                                             .648
ChunkSize                                                                    .211
C1=CZ/3     'Numero de colores                                               .927
FOR a=0 TO c1-1                                                              .709
Pal!(0,a)=(ASC(INPUT$(1,1))/240)                                             .805
Pal!(1,a)=(ASC(INPUT$(1,1))/240)                                             .806
Pal!(2,a)=(ASC(INPUT$(1,1))/240)                                             .807
NEXT                                                                         . 61
END SUB                                                                      .214
 
SUB Cursor STATIC                                                            .213
SHARED x1,y1,x2,y2                                                           .845
AREA (x1,y1):AREA (x2,y1)                                                    . 65
AREA (x2,y2):AREA (x1,y2)                                                    . 58
AREAFILL 1                                                                   .333
END SUB                                                                      .214
 
INPUT "Fichero ILBM;",pic$                                                   .953
OPEN pic$ FOR INPUT AS 1                                                     .107
Fread 4:IF Z$<>"FORM" THEN PRINT "NO IFF":CLOSE END                          .511
Fread 4                                                                      .731
Fread 4:IF Z$<>"ILBM" THEN PRINT "NO ILBM":CLOSE:END                         .886
GetChunks:                                                                   .804
Fread 4                                                                      .731
IF Z$="CMAP" THEN PRINT "CMAP":CALL CMAP:GOTO GetChunks                      . 78
IF Z$="BMHD" THEN PRINT "BMHD":CALL BMHD:GOTO GetChunks                      . 51
IF Z$="BODY" THEN GOTO BODY                                                  .258
PRINT Z$                                                                     .621
ChunkSize                                                                    .211
Fread CZ                                                                     .488
GOTO GetChunks                                                               .785
 
BODY:          'Abre Screen y carga dibujo.                                  .858
IF an>ScX OR A1>ScY THEN                                                     .325
PRINT "Pantalla mas grande que Screen. No puedo cargar..."                   .751
CLOSE:END                                                                    .404
END IF                                                                       .654
Fread 4                                                                      .731
IF ScX=320 AND ScY<=256 THEN mode=1                                          .349
IF ScX=320 AND ScY>256 THEN mode=3                                           .322
IF ScX=640 AND ScY<=256 THEN mode=2                                          .349
IF ScX=640 AND ScY>256 THEN mode=4                                           .475
IF com=1 THEN Compressed                                                     .657
IF com>1 THEN PRINT "Formato de compresion desconocido:"com:CLOSE:END        .170
 
SCREEN 2,ScX,ScY,P1,mode                                                     .266
WINDOW 3,,,0,2                                                               .628
FOR a=0 TO 2^Pl-1                                                            .597
PALETTE a,Pal!(0,a),Pal!(1,a),Pal!(2,a)                                      . 20
NEXT                                                                         . 61
SCRP=19022                                                                   .324
DIM Plane$(Pl-1)                                                             .826
FOR a=0 TO Pl-1                                                              . 45
Plane&(a)=PEEKL(SCRP+(a*4))                                                  .146
NEXT                                                                         . 61
FOR y=0 to Al-1                                                              .171
IF INKEY$=CHR$(27) THEN CLOSE:GOTO Grab                                      .364
FOR p=0 TO Pl-1                                                              .780
FOR a=0 TO ((an/8)-1) STEP 2                                                 .252
Fread 1:v1&=ASC(Z$)*256                                                      .488
Fread 1:v2&=ASC(Z$)                                                          .536
POKEW Plane&(p)+a+(y$(an/8)),v1&+v2&                                         .572
NEXT                                                                         . 61
NEXT                                                                         . 61
NEXT                                                                         . 61
CLOSE:GOTO Grab                                                              .389
 
Compressed:           'Lee ficheros en                                       .504
'formato comprimido                                                          .532
'CmpByteRun1   (EOA)                                                         .522
 
SCREEN 2,ScX,ScY,Pl,mode                                                     .266
WINDOW 3,,,0,2                                                               .628
FOR a=0 TO 2^Pl-1                                                            .597
PALETTE a,Pal!(0,a),Pal!(1,a),Pal!(2,a)                                      . 20
NEXT                                                                         . 61
SCRP=19022                                                                   .324
DIM Plane&(PI-1)                                                             .826
FOR a=0 TO Pl-1                                                              . 45
Plane&(a)=PEEKL(SCRP+(4*A))                                                  .524
NEXT                                                                         . 61
FOR y=0 TO Al-1                                                              .171
IF INKEY$=CHR$(27) THEN CLOSE:GOTO Grab                                      .364
FOR p=0 TO Pl-1                                                              .780
xp=0                                                                         .282
WHILE Xp=0 THEN                                                              .183
CM=CM+1:IF Xp+CM>an/8 THEN Er=1:CLOSE:END                                    .833
FOR zz=1 TO CM                                                               .523
CALL ReadByt:POKE Plane&(p)+Xp+(y*(ScX/8)),BY                                .350
xp=Xp+1                                                                      .865
NEXT                                                                         . 61
END IF                                                                       .654
 
 
IF Cn=>-127 AND Cn<=-1 THEN                                                  . 23
CM=-CM+1:IF Xp+CM>an/8 THEN Er=2:CLOSE:END                                   .546
ReadByt                                                                      .227
FOR zz=1 TO CM                                                               .523
POKE Plane&(p)+Xp+(y*(ScX/8)),BY                                             . 46
Xp=Xp+1                                                                      .865
NEXT                                                                         . 61
END IF                                                                       .654
WEND                                                                         . 89
NEXT                                                                         . 61
NEXT                                                                         . 61
 
Grab:        'Aqui tomamos un pedazo de                                      .271
'de la pantalla y la grabamos                                                .829
'en formato GET.                                                             .978
 
CLOSE                                                                        .533
WINDOW 3                                                                     . 39
BEEP                                                                         .260
x1=0:y1=0:x2=0:y2=0                                                          . 18
WHILE MOUSE(0)<>0:WEND                                                       .435
MouseLoop:                                                                   .614
IF MOUSE(0)=0 THEN MouseLoop                                                 .181
x1=MOUSE(1)                                                                  .135
y1=MOUSE(2)                                                                  .233
xa=x1:ya=y1                                                                  .723
x2=x1:y2=y1                                                                  .434
Cursor                                                                       .476
ClickLoop:                                                                   .405
IF MOUSE(0)=0 THEN ExitLoop                                                  .637
xn=MOUSE(1)                                                                  .562
yn=MOUSE(2)                                                                  .660
IF xa=xn AND ya=yn THEN ClickLoop                                            .400
Cursor                                                                       .476
xa=xn:ya=yn                                                                  .560
x2=xn:y2=yn                                                                  .271
Cursor                                                                       .476
GOTO ClickLoop                                                               .728
ExitLoop:                                                                    .575
 
LM=3+INT((x2-x1+16)/16)*(y2-y1+1)*Pl                                         .563
WaitForComm:                                                                 .830
a$=INKEY$                                                                    .878
IF a$=" " THEN GOTO GrabIt                                                   .490
IF a$=CHR$(139) THEN LOCATE 1,1:PRINT LM*2                                   .363
IF MOUSE(0)<>0 THEN x2=xn:y2=yn:CALL Cursor:GOTO MouseLoop                   . 62
GOTO WaitForComm                                                             . 61
 
GrabIt:        'Carga dibujo...                                              . 71
 
Cursor                                                                       .476
DIM pic%(LM)                                                                 .774
GET (x1,y1)-(x2,y2),pic%                                                     .686
WINDOW 1                                                                     . 25
INPUT "Nombre:",nam$                                                         .551
OPEN nam$ FOR OUTPUT AS 1                                                    .906
PRINT#1,MKL$(0);                                                             .350
PRINT#1,MKL$(0);                                                             .350
PRINT#1,MKI$(0);MKI$(pic%(2));                                               .482
PRINT#1,MKI$(0);MKI$(pic%(0));                                               .675
PRINT#1,MKI$(0);MKI$(pic%(1));                                               . 79
PRINT#1,MKI$(24);                                                            .464
PRINT#1,MKI$(2^Pl-1);                                                        .281
PRINT#1,MKI$(0);                                                             . 50
FOR i=3 TO LM-1                                                              .183
PRINT#|,MKI$(pic%(i));                                                       .859
NEXT                                                                         . 61
CLOSE                                                                        .533
WINDOW CLOSE 3:SCREEN CLOSE 2                                                .821
ERASE pic%                                                                   .825
PRINT "Terminado!"                                                           .738
INPUT "Mas Objetos";an$                                                      .403
IF an$="s" OR an$="S" THEN GOTO Grab                                         .187
CLOSE                                                                        .533
WINDOW CLOSE 3                                                               .238
SCREEN CLOSE 2                                                               .858
END                                                                          .992
 
Numero de lineas: 207

LISTADO 3

Programa: IFF.TRANSFER
 
'Raiders of the lost IFF,                                                    .339
'   Trnasfer de Basic a IFf, Rev 1.23                                        .600
'   Este programa genera un fichero                                          . 56
'   IFF con la pantalla Basic.                                               .616
'   (en formato no comprimido.)                                              .336
'  F.Marcos 1988. Hola QE2!                                                  .712
 
SNapshot:                                                                    .369
SUB WriteLw (LWord&) STATIC                                                  .371
SHARED b1,b2,b3,b4                                                           .153
st$=HEX$(LWord&)                                                             .624
st$=LEFT$("00000000",8-LEN(st$))+st$                                         .998
b1=VAL("&H"+LEFT$(st$,2))                                                    .878
b2=VAL("&H"+MID$(st$,3,2))                                                   . 59
b3=VAL("&H"+MID$(st$,5,2))                                                   . 74
b4=VAL("&H"+RIGHT$(st$,2))                                                   .370
PRINT#1,CHR$(b1)CHR$(b2)CHR$(b3)CHR$(b4);                                    .322
END SUB                                                                      .214
 
SUB WriteWd (Word&) STATIC                                                   .572
SHARED w1,w2                                                                 .618
st$=HEX$(Word&)                                                              .209
st$=LEFT$("0000",4-LEN(st$))+st$                                             .475
W1=VAL("&H"+LEFT$(st$,2))                                                    .593
w2=VAL("&H"+RIGHT$(st$,2))                                                   .638
PRINT#1,CHR$(w1)CHR$(w2);                                                    .274
END SUB                                                                      .214
 
SUB WriteBt (Byte%) STATIC                                                   .513
PRINT#1,CHR$(Byte%);                                                         .436
END SUB                                                                      .214
 
INPUT "Nombre";nam$                                                          .331
OPEN nam$ FOR OUTPUT AS 1                                                    .906
PRINT#|,"FORM";       'Identificador IFF.                                    .696
WriteLw 41020&        'Longitud total.                                       .631
PRINT#1,"ILBM";       'Identificador de gráficos.                            .307
 
PRINT#1,"BMHD";       'Chunk BMHD...                                         .167
WriteLw 20&                                                                  .583
WriteWd 640&          'Escribe ancho de la pantalla                          .413
WriteWd 256&          '   "    alto   "     "   (PAL)                        .889
WriteWd 0&            'Posicion X                                            .859
WriteWd 0&            'Posicion Y                                            .866
WriteBt 2             'Planos                                                .122
WriteBt 0             'Enmascaramiento.                                      .444
WriteBt 0             'Compresion.                                           .804
WriteBt 0             'Byte a cero.                                          .745
WriteWd 0&            'Color Transparente.                                   . 20
WriteBt 10            'Proporcion X                                          .616
WriteBt 11            'Proporcion Y                                          .390
WriteWd 640&          'Ancho Screen.                                         .289
WriteWd 256&          'Alto Screen.                                          .362
 
PRINT#1,"CMAP";       'Chunk CMAP....                                        .996
WriteLw 12&                                                                  .338
WriteBt 0             'Color 0 (azul)                                        .737
WriteBt 0                                                                    .329
WriteBt 192                                                                  .626
 
WriteBt 192           'Color 1 (blanco)                                      .  7
WriteBt 192                                                                  .626
WriteBt 192                                                                  .626
 
WriteBt 0             'Color 2 (negro)                                       .966
WriteBt 0                                                                    .329
WriteBt 0                                                                    .329
 
WriteBt 192           'Color 3 (naranja)                                     . 45
WriteBt 80                                                                   . 34
WriteBt 32                                                                   .802
 
PRINT#1,"BODY";       'Chunk BODY....                                        .890
WriteLw 40960&                                                               .528
Plane(0)=PEEKL(19022)                                                        .511
Plane(1)=PEEKL(19026)                                                        .474
FOR y=0 TO 255                                                               .897
FOR Pl=0 TO 1                                                                .917
FOR x=0 TO 79                                                                .918
PRINT#1,CHR$(PEEK(Plane(P1)+x+(80*y)));                                      .128
NEXT                                                                         . 61
NEXT                                                                         . 61
POKE Plane(0)+80*y,170                                                       .287
NEXT                                                                         . 61
CLOSE                                                                        .533
END                                                                          .992
 
Numero de lineas: 76

Envía esta página web a un amigo:
Esta opción está desactivada temporalmente, rogamos disculpen las molestias

Volver a la página anterior

Al menú principal