COLABORACIONES DE
LOS LECTORES
|
|
Las
colaboraciones de los lectores son un elemento importante en la
relación con la revista. En esta ocasión, además de didácticos,
son programas prácticos y de utilidad. Además, el lector se beneficia
de una pequeña compesación a su esfuerzo de programación. Pequeñas
rutinas, trucos, todo tiene cabida en esta sección reservada al
usuario programador.
|
COLOR
v1.00
Por
Alvaro Mateos Herrero
Color es un programa que
llamado como un comando desde el CLI nos permitirá cambiar el
color de la pantalla donde se encuentre nuestra ventana CLI. El formato
de este comando es:
Color <núm
color> <rojo> <verde> <azul>
'núm color' es el
número del color que queremos cambiar. El número puede
estar entre 0 y 63 aunque en una pantalla CLI normal se utilizan los
colores de 0 a 3. Por otra parte, con este comando también podremos
cambiar los colores del sprite del ratón, que corresponde a los
números 17 18 y 19.
'rojo' cantidad de rojo del
color (entre 0 y 15)
'verde' cantidad de verde
del color (entre 0 y 15)
'azul' cantidad de azul del
color (0 a 15)
Todos estos
parámetros son obligatorios. De todas formas si nos olvidamos
del formato, podemos escribir simplemente el nombre del comando y nos
aparecerá la ayuda.
Ejemplos:
Color 0 15 0 0 ; pone ROJO el color 0
Color 1 0 15 0 ; pone VERDE el color 1
Color 2 0 0 15 ; pone AZUL el color 2
Color 3 10 10 10 ; pone GRIS el color 3
Color 17 12 1 15 ; pone VIOLETA el primer color del ratón
Color 18 15 10 12 ; pone ROSA el segundo color del ratón
Color 19 15 9 0 ; pone NARANJA el tercer color del ratón
Este programa
es de dominio público, y puede distribuirse libremente siempre
que no sea con fines comerciales. Se incluye el fuente del programa
por si alguien quiere modificarlo.
JOYSTICK
Por Alvaro
Mateos Herrera
Leer el joystick del AMIGA
no es tan simple como leer el valor de un puerto y coger el valor de
un registro. Por una parte tenemos que decodificar la información
que se nos da en los registros JOY0DAT y JOY1DAT, y por otra leer los
botones de disparo en el registro 'cra' del CIAA.
JOY0DAT es
uno de los registros conectados al puerto 1 del joystick (donde va conectado
el ratón) mientras que JOY1DAT es el relacionado con el puerto
2.
Para interpretar la información
de estos registros tenemos que tener en cuenta lo siguiente:
bit 1 corresponde a la derecha
bit 2 corresponde a la izquierda
bit 1 XOR bit 0 corresponde a abajo
bit 9 XOR bit 8 corresponde a arriba
De tal forma
que si el bit (o la combinación de bits) vale 1 significará
que el usuario esta dirigiendo el joystick a esa o esas direcciones.
Por otra parte, para leer
los botones del joystick tendremos que examinar los bits 6 y 7 del regitro
'cra' ($bfe001) donde el bit 6 corresponde al puerto 1 y el bit 7 al
puerto 2.
En este caso si el bit vale
1 significará que NO esta pulsado.
En el fichero Joystick se
incluye una función en ensamblador que nos ahorra todo el trabajo.
La función llamada Joystick nos devolverá en d0 una larga
palabra que se interpretará de la forma siguiente:
bit 0 -> JOY 1 Derecha
bit 1 -> JOY 1 Izquierda
bit 2 -> JOY 1 Abajo
bit 3 -> JOY 1 Arriba
bit 4 -> JOY 1 Disparo |
bit 16 -> JOY 2 Derecha
bit 17 -> JOY 2 Izquierda
bit 18 -> JOY 2 Abajo
bit 19 -> JOY 2 Arriba
bit 20 -> JOY 2 Disparo |
Si el bit esta a 1 es que
el usuario esta pidiendo que se realice esa o esas acciones.
NOTA: Si tenemos conectado
el ratón en vez de un joystick, los valores devueltos serán
aleatorios a excepción del botón de disparo.
KEYBOARD v1.00
Por Alvaro
Mateos Herrera
Keyboard consiste en un conjunto
de funciones y subrutinas para leer el teclado del AMIGA. Estas funciones
nos permiten comunicarnos con el keyboard.device para leer el estado
de las teclas. Su uso es bastante simple, y puede incluirse en cualquier
programa que necesite saber que teclas están pulsadas o cuales
han dejado de pulsarse. Las funciones son compatibles con el sistema
de tal forma que correrán en total armonía con la multitarea
del AMIGA. Además la rapidez de la función Read_Keyboard
no ralentiza el programa principal así como las tareas que corran
simultáneamente.
Las tres funciones principales
son Open_Keyboard, Read_Keyboard y Close_Keyboard. Estas funciones hacen
uso de las subrutinas Create_Port, Delete_Port, Create_ExtIO, Delete_ExtIO.
Todas ellas están incluidas en el fichero KeyDevice, con una
amplia descripción de lo que hacen.
Para saber como se utilizan
se incluye un ejemplo llamado KeyEjmp que demuestra lo fácil
de su uso. De todas formas aquí viene una amplia descripción
de los pasos a seguir.
1. LLamamos
a la función Open_Keyboard al mismo tiempo que creará
las estructuras necesarias para comunicarnos con el device. Todo esto
es transparente a nosotros y no nos interesa entrar en detalles.
NOTA: Open_Keyboard
deberá devolver cero en d0. Si no es así es que ha habido
algún error. Por jemplo. -1 indica error de memoria. Cualquier
otro valor distinto de cero será un código de error devuelto
por OpenDevice de EXEC.
2. Una vez
abierto el keyboard.device y cada vez que queramos leer el estado de
las teclas, llamaremos a la función Read_Keyboard que tomara
como argumento en a0 el puntero a un buffer de 13 bytes que se interpretará
como una matriz de 13 x 8 bits. Cada bit representará a una tecla.
Si el bit esta a uno es que la tecla esta siendo pulsada, mientras que
siesta a 0 es que no lo esta. Para saber a que byte corresponde una
tecla determinada dentro de ese buffer, y en concreto a que bit dentro
de ese byte, existen unos códigos relacionados con cada tecla.
Más adelante se dará un esquema del teclado con su código
correspondiente. Este código, dividido por 8 nos dará
el número de byte dentro del buffer, y el resto de la división
nos dará el orden del bit. Por ejemplo, si queremos leer la tecla
correspondiente a la letra 'D' cuyo código es $22 hexadecimal
lo dividimos por 8 que nos dará 4 y de resto 2, luego tendremos
que examinar el byte cuatro del buffer y dentro de este byte, el bit
2. Si el bit esta a uno es que la tecla 'D' esta siendo pulsada. Hay
que tener en cuenta que no tenemos por que darle siempre el mismo buffer
a la función Read_Keyboard, luego podemos utilizar dos buffers
diferentes donde vamos leyendo simultáneamente en uno y otro
y comparando que tecla o teclas han modificado su estado.
3. Una vez
que hayamos terminado tendremos que llamar a la función Close_Keyboard,
teniendo en cuenta que no podremos hacer ninguna llamada a Read_Keyboard
después de haber llamado a esta, a no ser que volvamos a abrir
el keyboard.device mediante Open_Keyboard. No es recomendable estar
abriendo y cerrando el Keyboard para hacer una llamada a Read_Keyboard.
Lo normal es hacer una llamada a Open_Keyboard al principio del programa
y Close_Keyboard al final y dentro del programa hacer todas las llamadas
que queramos a Read_Keyboard.
En la Tabla 1 viene el esquema
de los códigos de las teclas.
NOTA: los códigos
están en hexadecimal.
Esta información deberá
ser suministrada junto con el fichero KeyDevice que contiene el fuente
de las rutinas y el programa KeyEjmp de ejemplo.
TABLA 1
El teclado principal
Tecla ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10
Código 45 50 51 52 53 54 55 56 57 58 59
Tecla ' 1 2 3 4 5 6 7 8 9 0 - = \ DEL
Código 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 41
Tecla TAB Q W E R T Y U I O P £ > RETURN
Código 42 10 11 12 13 14 15 16 17 18 19 1a 1b 44
Tecla CTL CAP A S D F G H J K L - ; Ç
Código 63 62 20 21 22 23 24 25 26 27 28 29 2a 2b
Tecla MAY < Z X C V B N M , . ' MAY
Código 60 0 31 32 33 34 35 36 37 38 39 3a 61
Tecla ALT AMIGA ESPACIO AMIGA ALT
Código 64 66 40 67 65
El teclado expandido
Tecla DEL HELP { } / *
Código 46 5f 5a 5b 5c 5d
Tecla 7 8 9 -
Código 3d 3e 3f 4a
Tecla ARR 4 5 6 +
Código 4c 2d 2e 2f 5e
Tecla IZQ ABA DER 1 2 3 ENTER
Código 4f 4d 4e 1d 1e 1f 43
Tecla 0 .
Código 0f 3c
|
NOTA:
El esquema corresponde a un teclado A500. La configuración
de las teclas nos pueden ayudar a saber a cual corresponde exactamente
en caso de duda.
No han podido
ser introducidos todos los listados por falta de espacio físico.
En nuestros
discos Amiga World 37 podrán encontrar los listados completos.
También pueden solicitarlos a la redacción, enviando
un disco formateado para Amiga.
|
RATON
Por Alvaro
Mateos Herrera
En la mayoría de los
programas nos va a hacer falta esperar la respuesta del usuario para
hacer algo determinado. El famoso 'pulsa el botón del ratón
para continuar' es un ejemplo de ello.
Esperar a que
el botón del ratón sea pulsado es la forma más
simple y cómoda de comunicar nuestro programa con el exterior.
En el fichero 'Ratón' hay una amplia información con las
rutinas necesarias para leer los botones izquierdo, derecho e incluso
el botón del medio (para los que tengan un 'Super Ratón'),
tanto si esta conectado al puerto 1 como si lo esta al puerto 2.
Para cualquier sugerencia
me pueden escribir o ponerse en contacto a través de la redacción
de Amiga World.
ALVARO MATEOS HERRERA
C/ Bermúdez de Castro, 4
41011 Sevilla
* LISTADOS COLABORACIONES *
/
/*************************************************/
/* Color v1.0 16/jul/92 */
/* */
/* Copyright 1992 hi-score Alvaro Mateos */
/* */
/*************************************************/
#include
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <proto/all.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
/* declaracion de funciones */
int number(char *);
int openall(void);
void closeall(void);
void chgcolor(SHORT,UBYTE,UBYTE,UBYTE);
/* declaracion de variables globales */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
/* Funcion principal donde comprobamos el numero de parametros,
los convertimos en numeros, abrimos las librerias necesarias,
llamamos a la funcion que cambian el color especificado y
cerramos la librerias.
Si hay algun error en la linea de comandos imprimimos el mensaje de ayuda.
*/
void main (int argc,char *argv[])
{
SHORT colorN;
UBYTE colorR,colorG,colorB;
if (argc==5)
{
if ((colorN=(SHORT) number(argv[1]))!=-1)
if ((colorR=(UBYTE) number(argv[2]))!=-1)
if ((colorG=(UBYTE) number(arg[3]))!=-1)
if ((colorB=(UBYTE) number(arg[4]))!=-1)
if (colorN<64) && ((colorR*colorG*colorB)<4096) )
{
if (openall())
chgcolor(colorN,colorR,colorG,colorB);
closeall();
exit (0);
}
printf ("** Expresion no valida **\n");
}
printf("Usar: Color \n");
printf("Ejemplo: Color 0 15 15 15 pone el fondo de color
blanco\n");
printf("Color v1.0 Copyright hi-score 1992\n");
}
/* Esta funcion convierte una cadena de caracteres en un numero
entero. Devuelve -1 si hay algun error
*/
int number(char *cadena)
{
int n,num;
n=0
num=0;
while (cadena[n]!='\0')
{
if (1(cadena[n]>='0' && cadena[n]<='9'))
return (-1);
num=num*10+(cadena[n]-'0');
n++;
}
return (num);
}
/* Aqui abrimos las librerias necesarias. Si ocurre algun error
devolvemos FALSE.
*/
int openall(void)
{
if ( (IntuitionBase=(struct IntuitionBase *)
OpenLibrary ("intuition.library",0)) != NULL)
if ((GfxBase=(struct GfxBase *)
OpenLibrary ("graphics.library",0)) != NULL)
return (TRUE);
return (FALSE);
}
/* Aquí cerramos las librerias abiertas anteriormente
*/
void closeall(void)
{
if (IntuitionBase) CloseLibrary( (struct Library *) IntuitionBase);
if (GfxBase) CloseLibrary( (struct Library *) GfxBase);
}
/* Esta es la funcion que cambia el color
Primero cogemos la ventana que esta activada, cogemos su estructura ViewPort
y con esto llamamos a la funcion de la
libreria Graphics SetRGB4, que toma como parametros el ViewPort,
el numero de color y los valores de rojo, verde y azul.
*/
void chgcolor(SHORT colorN, UBYTE colorR, UBYTE colorG, UBYTE colorB)
{
struct Window *window;
struct ViewPort *vp;
window=IntuitionBase->ActiveWindow;
vp=ViewPortAddress(window);
SetRGB4(vp,colorN,colorR,colorG,colorB);
}
;*****************************************
; Lectura de los dos puertos del Joystick
; Copyright 1992 hi-score Alvaro Mateos
; 25/Sep/1992
;
;*****************************************
| Situar el tabulador a 4 espacios
;**********
; JOYSTICK
;**********
; Esta funcion devuelve en d0 el estado de los dos puetos del Joystick
; de la siguiente forma:
; PUERTO 1 PUERTO 2
; bit 0 -> derecha bit 16 -> derecha
; bit 1 -> izquierda bit 17 -> izquierda
; bit 2 -> abajo bit 18 -> abajo
; bit 3 -> arriba bit 19 -> arriba
; bit 4 -> disparo bit 20 -> disparo
;
; Conserva todos los registros menos d0 y d1
Joystick:
move CUSTOM+joy1dat,d0 ; cogemos el valor del puerto 2
bsr Decode_JoyDat ; lo decodificamos
move.b $bfe001,d1
not d1
and #$0080,d1 ; cogemos el bit 'disparo'
lsr #3,d1
or d0,d1 ; ponemos el valor del Joystick 2
swap d1 ; en la palabra alta
move CUSTOM+joy0dat,d0 ; cogemos el valor del puerto 1
bsr Decode_JoyDat ; lo decodificamos
move.b $bfe001,d1
not d1
and #$0040,d1 ; cogemos el bit 'disparo'
lsr #2,d1
or d0,d1 ; unimos los valores en d1
move.l d1,d0 ; y pasamos el valor completo a d0
RTS
; DECODE JOYDAT
; Esta subrutina toma en d0 el valor dado por uno de los puertos del
; joystick y lo decodifica, devolviendo en d0 el estado del joystick de
; la siguiente forma:
; bit 0 -> derecha
; bit 1 -> izquierda
; bit 2 -> abajo
; bit 3 -> arriba
Decode_JoyDay:
movem.l d1-d2,-(a7) ; guardamos los registros utilizados
move d0,d1 ; copiamos JOYDAT en d1
lsr #1,d1
and #%0001,d1 ; cogemos el bit 'derecha'
move d1,d2 ; en d2 vamos almacenando los valores
move d0,d1
lsr #8,d1
and #%0010,d1 ; cogemos el bit 'izquierda'
or d1,d2 ; en d2 ya tenemos el valor de 'izq' y 'der'
move d0,d1 ; ahora vienen los valores de 'abajo'
lsr #1,d1 ; y 'arriba'- Para ello hay que tener en
eor d1,d0 ; cuenta que:
move d0,d1 ; 'abajo' = bit 1 XOR bit 0
lsl #2,d1 ; 'arriba'= bit 9 XOR bit 8
and #%0100,d1
or d1,d2 ; ... y lo vamos situando en d2
lsr #5,d0
and #%1000,d0
or d0,d2
move d2,d0 ; por ultimo pasamos el valor a d0
movem.l (a7)+,d1-d2 ; recuperamos los registros y
RTS ; salimos
; Etiquetas utilizadas
CUSTOM equ $dff000
joy0dat equ $000a
joy1dat equ $000c
;*********************************************************************
; KeyDevice v1.00
; Copyright 1992 hi-score Alvaro Mateos
; 22/Sep/92
;
; Rutinas necesarias para leer el teclado mediante el keyboard.device
; Estas rutinas pueden ser utilizadas libremente, sin hacerse
; responsable el autor de cualquier daño o perdida de informacion
; que pudiese ocasionar su uso directa o indirectamente.
; KeyDevice debera ser suministrado con el fichero Readme que explica
; su uso y el programa ejemplo KeyEjmp.
; La distribucion de estos ficheros es libre siempre que se respete
; el copyright del autor, no se haga con fines comerciales y se
; respete lo dicho anteriormente en este o en los otros 2 ficheros.
; Cualquier mejora podra hacerse sobre el programa, en cuyo caso
; agradecieria que me enviaran una copia.
; *******************************************************************
;Ajustar el tabulador a 4 espacios
; Aqui estan las funciones necesarias para leer el keyboard.device
; Open_Keyboard: Abre el keyboard.device y crea las estructuras
; necesarias para trabajar con el. Deberemos llamarla una sola vez
; antes de trabajar con el device.
; Close_Device: Cierra el keyboard.device y desaloja la memoira
; utilizada por las estructuras utilizadas.
; Read_Keyboard: Lee el estado de todas las teclas. En a0 le daremos
; la direccion de un buffer de 13 bytes que se interpretara como una
; matriz de 8 x 13 bits. Cada bit representa una tecla. Si la tecla esta
; pulsada su bit correspondiente estara a 1 y si no esta pulsada a 0.
; Para saber a que byte corresponde una tecla determinada tendremos que
; dividir el codigo de la tecla por 8. El resto de la division nos dara el
; bit correspondiente. Asi por ejemplo para ver si esta pulsada la
; tecla 'espacio' que tiene como codigo el $40 (64 en decimal) hariamos
; lo siguiente:
; move #$40,d0 ; cargamos el codigo del 'espacio'
; lea buffer,a0 ; apuntamos al buffer
; divu #8,d0 ; div. por 8 para saber que byte
; move 0(a0,d0)d1 ; cogemos el byte correspondiente
; swap d0 ; cogemos el resto de la division
; btst d0,d1 ; comprobamos si el bit esta a cero
; beq tecla_NO_pulsada
; (aqui sabemos que la tecla
; en cuestion esta pulsada)
; ...
; Estas funciones llaman a las siguiente rutinas:
; Create_Port: Crea la estructura MsgPort necesaria para comunicarnos
; con otra tarea, en este caso con el keyboard.device'.
; Create_ExtIO: Crea la estructura IORequest, que sera el mensaje con
; el que nos comunicaremos con el device.
; Delete_Port: Borra el MsgPort creado anteriormente.
; Delete_ExtIO: Borra el IORequest creado anteriormente.
; NOTA IMPORTANTE:
; Todas estas rutinas funcionan bajo el control de EXEC.
; Para el perfecto funcionamiento de ellas tendremos que asegurarnos de
; que las interrupciones del sistema no estan deshabilitadas o
; desactivadas. Todas las rutinas y funciones cumplen con las leyes que
; hacen que el sistema permita la multitarea. Asi pues el uso de estas
; rutinas estara en armonia con otras aplicaciones que esten corriendo
; simultaneamente.
; La velocidad que he calculado de la lectura del teclado es bastante alta.
; esto significa que una llamada a Read_Keyboard volvera casi al
; instante.
|
|