Revistas en papel
 Amiga World Nº23 - Julio/Agosto 1991
Anterior
Menú
Logotipo
Sí puedes leer esta frase, la página ha sido actualizada.

El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España
para ofrecer los artículos de la revista Amiga World España.


En el capítulo del
mes pasado
vimos los pasos
necesarios
a la hora de abrir
una pantalla,
sin embargo
todavía se puede
sacar un mayor
provecho de
la estructura
de pantalla.

Los cuadernos del
Ensamblador

 

Por F. Javier Rodríguez

 

CAPÍTULO X

Una vez vista la estructura que devuelve el sistema cada vez que se abre una pantalla de usuario, nos damos cuenta de la flexibilidad con la que cuenta el Amiga para su programación. Pudieron comprobar en la tabal publicada de la estructura la existencia de unas cuantas direcciones que sin lugar a dudas pueden sernos de gran ayuda. En este capítulo nos detendremos a ver que es todo lo que podemos realizar con dicha información, y quizás podamos llegar a realizar un programa similar a 'Melt (1)' e incluso también podríamos llegar a realizar nuestro propio capturador de pantallas.

(1) Melt es un programa de dominio público que simula el derretimiento de la pantalla WorkBench, en alguna de las versiones de este programa puede considerarse como un Virus residente en memoria algo molesto.

Para ello lo primero que deberemos conocer es para qué sirve la primera palabra de la estructura de pantalla. En concreto esta contiene un puntero a la estructura de la siguiente pantalla abierta, en caso de que no se encuentre ninguna del tipo Custom esta será pantalla WorkBench. Otras direcciones de gran utilidad dentro de esta estructura es la que nos indica la resolución y dimensiones de la pantalla en cuestión, así como el offset de desplazamiento sobre el cual se encuentra abierta. Como podrán deducir, también es la primera palabra de la siguiente estructura la que apunte a la siguiente; así hasta que en dicha posición de la estructura se encuentre el valor cero.

Ahora es el momento para pasar a ver la forma de 'interceptar' una pantalla, para ello tendremos que utilizar la estructura de pantalla. El primer paso que debemos realizar es cargar en un registro el puntero a la siguiente estructura de pantalla; las dos líneas siguientes de programa se encargan de realizar esta tarea:

 
   move.l   screenhd,a0    ;Cargamos puntero de estructura.
   move.l   $0(a0),a0      ;Cargamos puntero a siguiente
                           ;estructura de pantalla en el mismo
                           ;registro (ubicado en la estructura   
                           ;con el offset = 0).
						

A partir de esta operación tendremos en el registro A0 el puntero a la nueva estructura de pantalla; generalmente la primera siempre es WorkBench, a no ser que se encuentren otras pantallas abiertas por encima del WorkBench.

A continuación podremos acceder a los datos que nos interesan, tales como ancho y alto de la pantalla, número de bitplanes, offset de desplazamiento con respecto a la esquina superior izquierda y lo que es más importante; ubicación de los bitplanes de dicha pantalla.

En el caso concreto del programa 'Melt' se puede prescindir de unos cuantos parámetros, ya que se saben datos fijos a cerca de la pantalla WorkBench; tales como ancho y alto, modo de representación, número de bitplanes (a no ser que se utilicen los programas que circulan en el dominio público encargados de aumentar el número de colores de la pantalla WorkBench), y offset de desplazamiento. De esta forma sólo es necesario leer las direcciones que apuntan a los dos BitPLanes que la componen, para ello al igual que en el caso anterior leeremos los correspondientes offsets de su estructura:

   move.l   $c0(a0),bitplane1
move.l $c4(a0),bitplane2

Mediante estas dos líneas se cargan los vectores que apuntan a los dos BitPlanes que componen la pantalla del WorkBench. El siguiente paso que se debe realizar es calcular el algoritmo mediante el cual se 'derretirán' los planos de la pantalla. En esta ocasión lo realizaremos de una forma sencilla, aunque el usuario podrá complicarlo para dar una mayor sensación de que la pantalla efectivamente se está derritiendo.

En nuestro caso primeramente copiaremos el contenido de la pantalla WorkBench a la nuestra propia, para realizar las posteriores operaciones en esta. Para ello debemos calcular el número de Bytes que deben ser leídos:

 
   Ancho = 640
   Altura = 256
   n� BitPlanes = 2
   640/8 = 80
   80*256 = 20480
   20480 * 2 = 40960   
 

Una vez realizada esta operación sabemos que necesitamos copiar un total de 40960 Bytes. Para agilizar el proceso, copiaremos los datos con una longitud de palabra, con lo cual debemos dividir este valor entre cuatro;

   40960/4 = 10240

Ahora ya tenemos el valor real de datos con el cual deberemos trabajar. Para copiar la pantalla del WorkBench es necesario leer los datos de la misma hacia la nuestra propia, por lo que debemos conocer los vectores que apuntan a nuestros BitPLanes. Para ello realizaremos la siguiente operación:

 
   move.l   screenhd,a0
   move.l   $c0(a0),BP1C
   move.l   $c4(a0),BP2C
   BP1C = BitPlane 1 Custom
   BP2C = BitPlane 2 Custom   
 

Ahora debemos cargar los primeros vectores de cada pantalla en sendos registros; no es necesario cargar los cuatro puesto que los segundos BitPlanes de cada pantalla son correlativos a los primeros. La siguiente rutina es la encargada de copiar la pantalal WorkBench en la nuestra (CUstom):

 
           move.l   bitplane1,a0   
           move.l   BP1C,a1
           move.l   #10240-1,d0
   loop:   move.l   (a0)+.(a1)+
           dbra     d0,loop
 

Cuando esta rutina se haya ejecutado, nuestra pantalla contendrá la misma imagen que la pantalla WorkBench, ahora es cuando podrá realizar la rutina encargada de grabar esta a disco (con lo cual se habrá hecho un minicapturador) o bien realizar un programa tipo Melt; en definitiva podrá realizar con los datos de la misma todo lo que quiera.

Sin embargo con las pantallas Custom no sólo podemos realizar este tipo de operaciones, sino que con las funciones contenidas en las librerías, varias vistas en 'Las Librerías del Amiga', podremos realizar operaciones tales como pasar la pantalla al fondo, a primer plano, mover con respecto a su eje X, etc.

En concreto varias de las funciones de la librería Intuition, relacionadas con operaciones de pantalla son las siguientes: OpenScreen(), CloseScreen(), DisplayBeep(), GetScreenData, MakeScreen(), MoveScreen(), OpenWorkBench(), CloseWorkBench(), ScreenToBack(), ScreenToFront(), ShowTitle(), WBenchToBack() y WBenchToFront().


Ventanas: una 'zona' de trabajo

Un elemento muy importante y al cual ya estamos acostumbrados, por su continuado uso en el Amiga, son las ventanas. Podemos decir que estas sirven para 'separar' varias zonas de trabajo en un mismo programa o para separar programas entre si. Al igual que las pantallas Custom, las ventanas resultan muy flexibles, siendo estas las que a su vez pueden contener diversos elementos del Intuition como es el caso de los Gadgets, Requesters o lo que es más importante: los menús (en este mismo número se incluye un interesante artículo explicando la estructura de los mismos).

Una característica de las ventanas es que estas pueden abrirse o visualizarse en cualquier tipo de pantalla (incluida la pantalla WorkBench), además de poder redimensionarse o desplazar la misma a lo largo de la pantalla.

Al igual que las pantallas Custom, hay que informar al Intuition de diversos parámetros mediante la correspondiente estructura. Esta tiene algunos parámetros que también son necesarios en las pantallas Custom, tales como ancho y alto de la ventana, offset de desplazamiento, etc.

A continuación podrá ver la estructura necesaria para definir la ventana en cuestión, así como informar al Intuition de dónde se abrirá la misma:

Número Tamaño Definición
0 W Esquina superior izquierda relativa a la posición de la pantalla.
2 W -
4 W Ancho y alto de la ventana (en Pixels).
6 W -
8 B Color para el primer plano.
9 B Color de fondo.
10 L Flags IDCMP. Tratamiento del Intuition (VER CUADRO 1).
14 L Flags para definición de la ventana (VER CUADRO 2).
18 L Puntero a primer Gadget de ventana.
22 L Puntero al gráfico de Selección.
26 L Puntero al texto para título de la ventana.
30 L Puntero a la pantalla sobre la cual se abre la ventana.
34 L Puntero al BitMap de ventana.
38 W Ancho mínimo de la ventana.
40 W Altura mínima de la ventana.
42 W Ancho máximo de la ventana.
44 W Altura máxima de la ventana.
46 W Tipo de ventana.

CUADRO 1. Flags de Control IDCMP.

Bit Valor Descripción
0 $000001 Comprueba tamaño.
1 $000002 Nuevo tamaño. El Intuition envía mensaje si se altera tamaño.
2 $000004 Refresco de Ventana.
3 $000008 Pulsación del ratón. El Intuition envía mensaje si se pulsa cualquier botón del ratón.
4 $000010 Movimiento del ratón. El Intuition envía mensaje si se mueve el ratón.
5 $000020 Gadget activado. El Intuition envía mensaje si se ha pulsado un Gadget especial.
6 $000040 Gadget desactivado. Lo mismo que el caso anterior.
7 $000080 Activación del Requester.
8 $000100 Elección de una opción del menú. El Intuition devuelve mensaje si se ha seleccionado alguna opción del menú.
9 $000200 Cerrar ventana. El Intuition envía un mensaje si se cierra la ventana.
10 $000400 Comprobación del teclado. El Intuition envía mensaje si se pulsa una tecla.
11 $000800 Verificar Requester.
12 $001000 Borrar Requester.
13 $002000 Verificación del menú.
14 $004000 Modificación en las opciones del Preferences.
15 $008000 Comprobación de disco insertado. El Intuition envía un mensaje si se ha insertado un disco en cualquier unidad.
16 $010000 Comprueba si se ha sacado un disco de cualquier disquetera. El Intuition envía mensaje si el disco ha sido sacado de cualquier disquetera.
17 $020000 La ventana muestra los mensajes en la pantalla WorkBench.
18 $040000 Comprueba la activación de una ventana. El Intuition envía un mensaje si la ventana ha sido activada.
19 $080000 Comprueba si una ventana está desactivada. El Intuition envía un mensaje si la ventana ha sido desactivada.
20 $100000 Movimiento relativo del ratón. El Intuition envía un mensaje en caso de que se haya movido el ratón.

Al igual que en el caso de definición y apertura de la pantalla, necesitamos acceder a una función de Intuition para abrir la ventana. Dicha función es OpenWindow(), a la cual se accede mediante el offset -204. Es necesario saber que antes de abrir una ventana deberá abrirse una pantalla, en el caso de que se desee situar sobre una pantalla Custom, o que se encuentre abierto (activo) el WorkBench. Una vez esta se encuentra abierta mediante la correspondiente rutina (sirva la del mes pasado), podremos abrir la ventana. Como ejemplo, a continuación, les mostraré la rutina que se encarga de abrir la ventana propipamente dicha:

 
   ; Abrir Ventana sobre la pantalla Custom.   
   OpenWindow = -204
               lea      windefs,a0
               jsr      OpenWindow(a6)
               beq      error
               move.l   D0,winhd
               .
               .
               .
   windefs:    dc.w     0
               dc.w     0
               dc.w     320
               dc.w     256
               dc.b     0
               dc.b     1
               dc.w     0
               dc.l     $1008
               dc.l     0
               dc.l     0
               dc.l     wintitle
   screenhd:   dc.l     0
               dc.l     0
               dc.w     0
               dc.w     0
               dc.w     320
               dc.w     256
               dc.w     15
   winhd:      dc.l     0
   wintitle:   dc.b     'Mi ventana',0
 

Una vez ejecutada esta rutina se nos devolverá en D0 el vector que apunta a un bloque de datos sobre la ventana abierta (usualmente llamada Handler), como podrán recordar esta misma operación era resultado de abrir una pantalla, en el caso de que esta no haya podido abrirse por cualquier motivo, el registro D0 devolverá el valor cero; con lo cual se saltará a la rutina encargada de tratar el error. Hay que tomar una precaución muy especial, ya que si las dimensiones de la ventana son mayores que la de la pantalla sobre la cual se dese abrir, o el offset de desplazamiento sobrepasa las dimensiones de la pantalla, o las definidas como máximo en la ventana, se producirá un error al abrir la misma.

En concreto los datos de control para la ventana, resultante de la operación OpenWindow(), son muy útiles. A continuación se muestran los mismos en forma de offset con respecto a la dirección base del Handler:

Offset Tamaño Descripción
0 L Puntero a la siguiente ventana de la pantalla.
4 W Posición del margen superior e izquierdo de la ventana.
6 W -
8 W Ancho y altura de la ventana el Pixels.
10 W -
12 W Posición del ratón relativa a la ventana (Y/X).
14 W -
16 W Ancho mínimo de la ventana.
18 W Altura mínima de la misma.
20 W Ancho máximo de la ventana.
22 W Altura máxima de la misma.
24 L Flags de la ventana.
28 L Puntero a la estructura de menú de esta ventana.
32 L Puntero al texto de título en la ventana.
36 L Puntero al primer Requester de la ventana.
40 L Puntero al doble menú Requester de la ventana.
44 W Número de Requester abiertos sobre la ventana.
46 W Vector que apunta a la pantalla WorkBench.
50 L Puntero a RastPort de la ventana.
62 L Puntero al primer Gadget en la ventana.
66 L Puntero a ventana previa.
70 L Puntero a ventana siguiente.
74 L Puntero al gráfico del puntero.
98 B Color para primer plano.
99 B Color de fondo.
100 L Puntero a gráfico para marca deseleccionado.
104 L Puntero a texto de título de pantalla.

CUADRO 2. Flags para definición de Ventana.

Bit Valor Descripción
0 $000001 El tamaño de la ventana podrá alterarse.
1 $000002 La ventana podrá desplazarse por la pantalla.
2 $000004 La ventana dispondrá de Gadgets de profundidad.
3 $000008 La ventana dispondrá del Gadget para cerrar la misma.
4 $0000010 La ventana dispondrá de barra de Slider horizontal.
5 $0000020 La ventana dispondrá de barra de Slider vertical.
6 $0000040 Refresco de la ventana simple.
7 $0000080 Super_Bitmap. Salvará el contenido de la ventana al ser 'pisada' por otra.
8 $0000100 La ventana aparecerá detrás de las demás.
9 $0000200 Devuelve las coordenadas del ratón.
10 $0000400 Ventana Gimmezerozero.
11 $0000800 Ventana sin bordes.
12 $0001000 Ventana activada.
25 $2000000 Ventana WorkBench.

Como puede observar, la información contenida en este Handler es mucho más amplia que en el caso de la pantalla. Obviamente se pueden realizar muchas más operaciones actuando en base a estos datos. En el próximo capítulo mostraremos varios ejemplos, además de explicar diversos conceptos que aparecen contenidos en la estructura de ventana. En el cuadro 'LISTADO 1' se encuentra el programa completo, encargado de abrir una ventana (sin Gadgets ni marco) sobre una pantalla Custom.

Como puede observar, la información contenida en este Handler es mucho más amplia que en el caso de la pantalla. Obviamente se pueden realizar muchas más operaciones actuando en base a estos datos. En el próximo capítulo mostraremos varios ejemplos, además de explicar diversos conceptos que aparecen contenidos en la estructura de ventana. En el cuadro 'LISTADO 1' se encuentra el programa completo, encargado de abrir una ventana (sin Gadgets ni marco) sobre una pantalla Custom.

Una características
de las ventanas
es que estas
pueden abrirse
o visualizarse
en cualquier tipo
de pantalla
(incluida la pantalla
WorkBench).



LISTADO. 1

   ;              ABRIR VENTANA USUARIO
   ;
   ;              7/6/91, Window V1.0
   ;
   ;              (C) 1991, F. Javier Rodr�guez
   ;
   ; Esta rutina se encarga de abrir una pantalla y una ventana    
   ; (Esta �ltima sin marco ni Gadgets).
   ;
   execbase      = 4
   openlibrary   = -408
   closelibrary  = -414
   openscreen    = -198
   closescreen   = -66
   openwindow    = -204
   closewindow   = -72
   PANTA:        move.l   execbase,a6
                 lea      intname,a1
                 jsr      openlibrary(a6)
                 move.l   d0,intbase
                 move.l   intbase,a6
                 lea      screendefs,a0
                 jsr      openscreen(a6)
                 move.l   d0,screenhd
   WINDOW:       lea      windefs,a0
                 jsr      openwindow(a6)
                 move.l   d0,windowhd
                 beq      error
   loop:         btst     #6,$bfe001
                 bne.s    loop
                 move.l   windowhd,a0
                 jsr      closewindow(a6)
   error:        move.l   intbase,a6
                 move.l   screenhd,a0
                 jsr      closescreen(a6)
                 move.l   intbase,a1
                 move.l   execbase,a6
                 jsr      closelibrary(a6)
                 rts
   screendefs:   dc.w     0
                 dc.w     0
                 dc.w     320
                 dc.w     256
                 dc.w     2
                 dc.b     0
                 dc.b     1
                 dc.w     2
                 dc.w     15
                 dc.l     0
                 dc.l     sname
                 dc.l     0
                 dc.l     0
   sname:        dc.b     'Mi Pantalla',0
                 even
   intname:      dc.b     'intuition.library',0
                 even
   windowhd:     dc.l     0
   intbase:      dc.l     0
   windefs:      dc.w     120
                 dc.w     0
                 dc.w     160
                 dc.w     256
                 dc.b     1
                 dc.b     0
                 dc.l     $0
                 dc.l     $1800
                 dc.l     0
                 dc.l     0
                 dc.l     windowname
   screenhd:     dc.l     0
                 dc.l     0
                 dc.w     320
                 dc.w     200
                 dc.w     320
                 dc.w     200
                 dc.w     15
   windowname:   dc.b     'Mi Ventana'
                 end
 

 


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