|
Programación
de librerías
ILBM 4ª
Parte
FICHEROS
PARA EL PROGRAMADOR
|
Hemos
llegado al final. En este capítulo vamos a desarrollar los últimos
ficheros de cabecera (¿cuántos llevamos?) y un par de ejemplos
de uso de ilbm.library
|
Tenemos tres,
los dos primeros para programas C:
- "ilbmbase.h"
es una versión de "ilbmbase.i", el fichero que creamos
en el capítulo 2 y que contiene la definición de la Base
de la librería.
- "ilbm.h"
contiene los modelos de estructuras, constantes y variables, necesarias
para la lectura y escritura de ficheros IFF-ILBM, usando funciones de
nuestra run-time. Ambos ficheros deben instalarse en el directorio ":incluse/"
del compilador. Para ello pueden crear dentro de este un subdirectorio
"/iff/" y copiarlos en él.
El tercero
es para Ensamblador:
- "ilbm.i"
es el equivalente de ilbm.h en formato estándar de Commodore
(los usuarios de Devpac pueden obtener a partir de él uno en
el formato especial que puede utilizar este ensamblador). El fichero
presenta una pequeña diferencia con su colega para lenguaje C,
en la macro encargarda de calcular el tamaño total de un fichero
ILBM. En la versión C esta macro se utiliza sin argumentos mientras
que en Ensamblador se le pasa como argumento la variable 2ilbmsz"
(declarada también en ilbm.i).
Ejemplos:
En C
- ilbmsz = TotalSize()
- TOTALSIZE
ilbmsz Instale ilbm.i en su ensamblador de la misma forma que los ficheros
anteriores.
Y ahora vamos
a ver un par de ejemplos de uso de la librería. Naturalmente
son programas sencillos, pero pueden servir de "esqueleto"
sobre los que crear sus propias aplicaciones.
USANDO ILBM.LIBRARY
Tenemos dos
programas: "VerILBM.c" y "SalvarILBM.s". Ambos ejecutables
sólo desde Shell/CLI.
-
"VerILBM.c" es un lector/visualizador en C. Pasándole
como argumento el nombre de un fichero, lo lee y muestra en su propia
pantalla. Tal y como esta puede visualizar ficheros que contengas gráficos
en alta o baja resolución y entrelazado en ambos modos. Debido
a las limitaciones de esta primera versión de la librería,
no sirve para ver gráficos en HAM o Halfbrite -para ello debe
crear sus propias funciones de programa, si quiere intentarlo..- ni
gráficos que contengan algún tipo de máscara. El
programa empieza abriendo las librerías del sistema que necesita
y, claro, también la nuestra -como verán, la apertura
se hace de la misma forma-. A continuación abre el fichero indicando
que queremos acceder a él sólo para leerlo. Y ahora empieza
el baile. Para ver el fichero hay que disponer de alguno de los elementos
de soporte gráfico del Amiga. En nuestro caso vamos a utilizar
uno de Intuition, concretamente una pantalla de tipo CUSTOMSCREEN sin
bara de título (SCREENQUIET). Lo que el programa no sabe es la
resolución, profundidad y modo que deberá tener ésta
para ajustarse al gráfico. Para averiguarlo contamos con los
datos que nos facilita el propio fichero ILBM en sus chunks BMHD y CAMG.
La lectura de BMHD, que nos dará las dimensiones y profundidad,
se efectúa mediante una llamada a la función "GetBMHeader()".
Esta nos devuelve un puntero a los datos del chunk para que a través
de él obtengamos los que nos interesan. A continuación
averiguamos el modo gráfico contenido en CAMG, letendo el chunk
con "GetGfxMode()". COn los datos proporcionados por estas
dos funciones, el programa abre la pantallam lista para reicbir el gráfico
pero... antes necesita conocer su paleta de colores -si no queremos
utilizar la que el Amiga inicializa por defecto y con la que nuestra
obra de arte puede aparecer irreconocible-. Para averiguar que colores
componen la paleta, utilizaremos la función "GetColMap()"
que lee el chunk que la contiene:CMAP. Una vez obtenida la cargamos
en los registros de color mediante la función "LoadRGB4()"
de la "graphics.library". Y ya sólo falta leer el gráfico
propiamente dicho, que está contenido en el chunk BODY y visualizarlo
en la pantalla. Esto -y alguna cosilla más, como la descompresión
si es necesaria- lo conseguimos llamando a la función "DisplayData()".
Llegados a este punto, el porgrama hace una pausa para dejarnos ver
el gráfico y finaliza cerrando pantalla, fichero y librerías.
- "SalvarILBM.s"
es un escritor de ILBMs en Ensamblador, muy elemental. Dándote
el nombre de un fichero -por ejemplo, SalvarILBM ram:test- dibuja un
gráfico (bastante tonto) y lo salva en formato ILBM con compresión.
Como es normal comienza abriendo las librerias necesarias. Tras esto
abre una pantalla en baja resolución y sobre ella una ventana
del mismo tamaño -ambas sin bordes y barra de título-.
Hecho esto pinta su dibujo e inmediatamente empieza a salvarlo. Para
ello abre un fichero con el nombre que especifique en la llamada al
programa y modo de acceso escritura. El primer chunk a escribir es FORM
y para esto el programa llama a la función "PutILBM()".
Tras este escribe BMHD con las dimensiones, tipo de compresión,
etc, usando la función "PutBMHeader()". La paleta de
colores la salva llamando a "PutColMap()", la función
encargada de escribir CMAP. Lo mismo hace con el modo gráfico,
escribiendo el chunk CAMG con la llamada correspondiente a "PutGfxMode()".
El orden en que el porgrama escribe estos chunks es el mismo que usa
"Deluxe Paint III", aunque en sus propios programas puede
emplear el que quiera, siempre que BMHD vaya inmediatamente antes que
los otros dos. Para terminar, se salva el dibujo llamando a la función
"SaveData()", encargada de escribir el chunk BODY. Una característica
de los ficheros IFF en general y de los ILBM en particular, es que la
cantidad de datos salvados en cada chunk debe ser par (por ejemplo 200
bytes, no 201 ni 199). En el caso de los ILBM generados con Amiga el
único chunk que puede no cumplir este requisito es BODY, debido
al algoritmo de compresión. Para comprobar si el chunk contendrá
un número par de bytes el programa pide ayuda a la macro "ODD_SIZE"
definida en "ilbm.i" (si escribe en C utilizad su hermana
"OddSize()" de "ilbm.h"). Si el resultado de la
macro es impar -por casualidad en este ejemplo sí que lo es-
el programa escribe un byte extra al final del chunk. Si han leído
los comentarios al respecto en "ilbm.i/ilbm.h" verán
en el tamaño de BODY -no se suma al tamaño devuelto por
"SaveData()-, pero sí hay que tenerle muy presente a la
hora de calcular el tamaño total de fichero. Para esto nuestro
ejemplo utiliza la macro "TOTALSIZE" (ver apartado sobre los
ficheros de cabecera). Una vez obtenido la función encargada
de escribirlo es "PutILBMSize()".
Una vez completada
la escritura el programa hace una pequeña pausa para que de tiempo
a ver su magnífico dibujo y, una vez transcurrida, cierra el
fichero y los demás elementos del sistema, terminando su ejecución.
Una vez compilado o ensamblado cada programa, hay que enlazarlos con
la librería explorable "ilbm.lib" creada en el capítulo
anterior. Para ayudalres en esta tarea disponen de los ficheros "VerILBM.lnk"
y "SalvarILBM.ink", que pueden utilizar en la forma habitual:
blink with VerILBM.lnk o blink with SalvarILBM.lnk. Sobre este último
fichero e enlace debo hacer una advertencia: como verán utiliza
el código de inicio "AStartup.obj". Este código
no es usado por Devpac, pero como el programa está escrito para
ser ensamblado con otros paquetes sin que de problemas, he decidido
utilizarlo aquí. La versión de "AStartup.obj"
que incluyo con los programas de ejemplo es la que aparecía,
hace ya algún tiempo, en el Curso de Ensamblador de Amiga World.
Aquellos que utilicen Metacomco MacroAssembler ya tienen en su paquete
este mismo fichero, pero en versión más moderna. Para
enlazar "SalvarILBM.o" con su "AStartup.obj", antes
de ensamblar el código fuente deben editarlo para substituir
la etiqueta "START:" por "_main:" (¿o es
"main:" sin subrayado inicial?...).
CONCLUSION
|
El
programa empieza abriendo las librerías del sistema
que
necesita y, claro, también la nuestra -como verán,
la apertu-
ra se hace de la misma forma
|
|
Y hasta aquí
nuestra librería run-time. Para que vean con más claridad
el trabajo que realiza cada una de sus funciones, los argumentos que
necesitan y elvalor que devuelven he incluido un apéndice con
unos "autodocs", un poco al estilo de los manuales oficiales,
para que puedan emplearlo como guía de consulta rápida
a la hora de desarrollar sus aplicaciones. Y ahora sí que hemos
llegado al final. Espero que esta miniserie les haya resultado útil
-amena y divertida ya se que no, lo reconozco, es un peñazo-,
al menos para conocer un poco más a fondo lo que se esconde tras
el sistema operativo con el que cuenta esa caja de circuitos tan genial
que es el Amiga. Muchas gracias a los que hayan tenido la paciencia
de aguantar hasta aquí y mil perdones a los que no, si llegan
a leer esto.
/********************************************************************* FICHERO.H : ilbm.h DESCRIPCION : definición de estructuras y datos para lectura/escritura de ficheros IFF-ILBM *********************************************************************/
#ifndef IFF_ILBM_H
#define IFF_ILBM_H
#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif
#ifndef EXEC_IO_H
#include <exec/io.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef LIBRARIES_DOS_H
#include <libraries/dos.h>
#endif
#ifndef LIBRARIES_DOSEXTENS_H
#include <libraries/dosextern.h>
#endif
#ifndef GRAPHICS_GFX_H
#include <graphics/diplay.h>
#endif
#ifndef GRAPHICS_RASTPORT_H
#include <graphics/rastport.h>
#endif
#ifndef GRAPHICS_VIEW_H
#include <graphics/view.h>
#endif
/* MODELO DE ESTRUCTURA Y DATOS PARA BMHD */
struct BitMapHeader {
UWORD w, h; /* dimensiones del grafico */
WORD x, y; /* posicion */
UBYTE nPlanes; /* planos de profundidad */
UBYTE masking; /* tipo de mascara */
UBYTE compression; /* tipo de compresion */
UBYTE pad1; /* byte para alineamiento */
UWORD transparentColor; /* color transparente */
BYTE xAspect, yAspect; /* relacion de aspecto */
WORD pageWidth, pageHeight; /* dim pantalla original */
};
/* tipo de mascara (para la version 1.0 de ilbm.library siempre
0) */
#define NOMASK 0
/* tipo de compresion */
#define NOCOMP 0
#define BYTERUN1 1
/* MASCARAS PARA LECTURA/ESCRITURA DE MODO GRAFICO */
/* Flags de ViewModes cuyo uso en CAMG no es apropiado para la
lectura o
escritura de ficheros ILBM, segun especificaciones de Electronic
Arts y
Commodore */
#define BADFLAGS (SPRITES | VP_HIDE | GENLOCK_AUDIO | GENLOCK_VIDEO)
#define FLAGMASK (~BADFLAGS)
#define CAMGMASK (FLAGMASK & 0X0000FFFFL)
/* COMPROBACION DE TAMANO DE CHUNKS
Si el tamano de un chunk es impar es necesario escribir un byte
extra
despues de los datos. Estos bytes extras NO SE SUMAN al tamano
del chunk pero SI al tamano total del fichero.
La macro siguiente comprueba si el tamano es impar */
#define OddSize(cksize) ((cksize) & 1)
/* TAMANO DE FICHERO
El tamano de un fichero IFF es igual a la suma de:
tamano (numero de bytes de datos) de cada chunk +
8 bytes por cabecera de cada chunk +
4 bytes por identificador de subtipo +
numero total de bytes extras que sea necesario escribir
(no se tienen en cuenta los 4 bytes de FORM ni los 4 utilizados
para escribir el tamano total del fichero). */
LONG bmhdsz, camgsz, cmapsz, bodysz; /* tamano de chunks */
LONG subidsz; /* tamano de identificador */
LONG ilbmsz; /* Tamano total de fichero */
long npads = 0; /* tamano de bytes extras */
#define CKHSIZE 8 /* tamano de cabeceras */
#define TOTALCKH (CKHSIZE * 4) /* total de cabeceras */
/* ATENCION!!! La siguiente macro calcula el tamano total que
se
pasa como argumento a la funcion "PutILBMSize()", pero
solo debe
usarse en programas que salven ficheros completos, no paletas
(ILBMs sin chunk BODY) */
#define TotalSize()
(bmhds+camgsz+cmapsz+bodysz+subidsz+npads+TOTALCKH)
#endif
/* FIN DE ilbm.h ****************************************************/
/********************************************************************
FICHERO.H : ilbmbase.h
DESCRIPCION : definicion de ILBMBase para programas en C.
DESARROLLO : 21-06-92 - Creacion (V. Santos)
********************************************************************/
#ifndef IFF_ILBMBASE_H
#define IFF_ILBMBASE_H
#ifndel EXEC_TYPES_H
#include <exec/types.h>
#endif
#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif
#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif
/* ESTRUCTURA DE ILBMBase
==================================================================*/
struct ILBMBase {
struct Library LibNode;
UBYTE Flags;
UBYTE Pad;
ULONG SysLib;
ULONG DosLib;
ULONG SegList;
};
#define ILBMNOMBRE "ilbm.library"
#endif
/* FIN DE ilbmbase.h
********************************************************************/
FROM LIB:AStartup.obj+SalvarILBM.o
LIB LIB:amiga.lib+LIB:ilbm.lib
TO SalvarILBM
VERBOSE
************************************************************************
* PROGRAMA : SalvarILBM.s *
* VERSION : 1.0 *
* DESCRIPCION : Ejemplo de escritura de IFF-ILBMs con ilbm.library
1.0 *
* DESARROLLO : 22-06-92 - Creacion (V. Santos) *
************************************************************************
* FICHEROS DE CABECERA
========================================================================
INCDIR "sys:devpac/include.cbm/"
NOLIST
INCLUDE "exec/types.i"
INCLUDE "exec/memory.i"
INCLUDE "libraries/dos.i"
INCLUDE "libraries/dosextens.i"
INCLUDE "intuition/intuition.i"
INCLUDE "iff/ilbmbase.i"
INCLUDE "iff/ilbm.i"
LIST
* DECLARACIONES EXTERNAS
=======================================================================
XDEF START ; para "AStartup.obj"
* REFERENCIAS EXTERNAS
=======================================================================
|
| NOTA
DE REDACCION |
| |
| Los
listados publicados corresponden a |
| las
primeras partes |
| o
rutinas de este capítulo. |
| |
| El
resto puede encontrarse en nuestros |
| discos |
| Amiga
World 39 |
|