You are on page 1of 9

Captulo 2. Programacin del ratn (I).

1.- El Manejador del Ratn


Para comunicarse con el ratn, tenemos que emplear la interrupcin 33h. El nmero de la funcin deseada se pasa con el registro AX y el resto de los registros se usan para pasar o recibir datos. Mov ax,0 int 0x33 Esta sera la forma de llamar a la funcin 0 del ratn. Algunas funciones del interfaz del ratn son las que se encuentran en el siguiente cuadro: Funcin 00h 01h 02h 03h 07h 08h 09h 0Ah 0Fh Uso Resetea el driver del ratn. Dibuja el cursor del ratn en la pantalla. Oculta el cursor del ratn. Devuelve la posicin del cursor y el estado de sus botones. Define la zona horizontal de movimiento para el cursor. Define la zona vertical de movimiento para el cursor. Define el cursor del ratn para los modos grficos. Define el cursor del ratn para los modos de texto. Fija la velocidad de desplazamiento del cursor.

Tras esta breve exposicin del ratn a nivel hardware, comenzamos con el anlisis de las rutinas que lo manejan. La librera que se encarga del ratn se llama "RATON.C", y sus cabeceras estn en "RATON.H", ambos ficheros incluidos ntegramente al final de esta seccin. Empecemos por cambiar el cursor del ratn, tarea sencilla para empezar. Slo hay que dibujar un mapa de bits con la forma que queramos, dibujar tambin su negativo (mscara) y luego traducir esas lneas de binario a hexadecimal. En el fichero de cabeceras (RATON.H) podemos encontrar la siguiente declaracin: int cursor1 [32+32] = { // Flecha 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, 0x03FF, 0x01FF, 0x00FF, 0x007F, 0x003F, 0x001F, 0x000F, 0x0007, 0x0007, 0xF81F, 0xFC0F, 0xFE0F, // Mscara 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, 0x7F80, 0x7FC0, 0x7FE0, 0x7FF0, 0x0780, 0x03C0, 0x01E0, 0x0000 }; Y usando el siguiente procedimiento hacemos efectivo el cambio: Void CambiaPunteroRaton(void) { long dir; int dir2,dir3; dir=(long)cursor1; dir2=(int)dir; dir3=(int)(dir>>16); asm{ mov ax,0x9 mov bx,0 mov cx,0

mov dx,dir2 mov es,dir3 int 0x33 } } Ntese el uso del Ensamblador dentro del cdigo C, es decir, "Ensamblador Inmerso". Como se ve, se ha llamado a la interrupcin 33h, al servicio 9h. Otra funcin y la primera que debemos ejecutar cuando queremos utilizar el ratn es la deteccin del propio ratn, ya que si ste no est, no podremos usarlo por mucho que programemos los eventos. El procedimiento que lo hace es el siguiente: int DetectarRaton(void) { int w; asm{ mov ax,0 mov bx,0x2 int 0x33 mov w,ax } return(w); } Si DetectarRaton devuelve -1, es que el ratn est presente. Una vez detectado la presencia del driver del ratn, hay que definir los lmites (en pxels) por los que se podr mover. void EstablecerLimRaton(int xi,int yi,int xf,int yf) { asm{ mov ax,7 mov cx,xi mov dx,xf int 0x33 mov ax,8 mov cx,yi mov dx,yf int 0x33 } } De esta forma, independientemente de la resolucin de la pantalla, podemos hacer que el ratn slo se pueda mover por una zona determinada, por un rectngulo que especifican las coordenadas del procedimiento. Esto es til cuando queremos centrar la atencin del usuario sobre una zona determinada, no permitindole hacer otra cosa hasta que haya seleccionado algo indispensable para continuar. Una vez detectado el ratn y establecido su mbito de movimiento, hay que mostrar la flecha. void MostrarRaton(void); Algo que hay que tener en cuenta es que cuando se vaya a hacer un cambio en la pantalla tales como escribir un texto o una lnea, hay que ocultar el ratn y volverlo a mostrar cuando acabemos, ya que si n, aparecern incongruencias entre la mscara del ratn y la memoria de vdeo, provocando la aparicin de rectngulos extraos que estropearn lo que veamos. Esto es debido a que el driver del ratn continuamente usa una pequea zona de memoria para almacenar lo que haba "debajo" del cursor antes de que alcanzase la posicin en que ahora se encuentra, de forma que al volverse a desplazar a

otra posicin se "restaura" lo que el cursor estaba "pisando". Por esto, si hacemos un cambio en una zona en la que se encuentra el cursor, al moverlo restaurar la "antigua" zona que antes estaba, y no la que ahora debera estar debido al cambio. Para ocultar el ratn usaremos: void OcultarRaton(void); Y jugando con estos dos ltimos procedimientos, escondemos y mostramos el ratn cuando se vayan a producir los cambios en la pantalla. Aparte de esto, dos de los ltimos procedimientos que vamos a presentar aqu (aunque hay ms pero son secundarios), son los que se encargan de hacer esperar a la CPU hasta que se haya pulsado un botn (en este caso slo se reconocen las pulsaciones de los botones izquierdo y derecho. Si se quisiera observar tambin el del botn central cuando el ratn disponga de tres, tendra que aadirse una tercera condicin al "while": (*bot!=4)): void EsperarPulsadoBoton(int *bot) { do { PulsadoBoton(bot); } while ((*bot!=1)&&(*bot!=2)); } y de hacerla esperar tambin hasta que se haya soltado ese botn. Los procedimientos son: void EsperarSoltadoBoton(int bot) { int *boton; do { PulsadoBoton(boton); } while (*boton==bot); } Ambos procedimientos llaman al procedimiento que interacta directamente con el ratn: void PulsadoBoton(int *bot) { int boton; asm{ mov ax,3 int 0x33 mov boton,bx } // Si vale 1 es el izquierdo, si vale 2 es el derecho,si vale 4 el central *bot=(int)boton; } Y por ltimo, el procedimiento que se encarga de leer las coordenadas: void LeerPosRaton(int *x,int *y) { int xx,yy; asm{ mov ax,3 int 0x33 mov xx,cx mov yy,dx } *x=xx; *y=yy; }

Con esto, la exposicin de los procedimientos que se encargan del ratn termina. Por ltimo, usando estos procedimientos podremos saber cundo el cursor se pulsa sobre una zona que nosotros hemos decidido que sea "sensible", esto es, un botn, un men, un submen, etc.

RATON.H
// LIBRERIA DEL RATON #include <dos.h> // Mascara-dibujo del cursor int cursor1 [32+32] = { 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, 0x03FF, 0x01FF, 0x00FF, 0x007F, 0x003F, 0x001F, 0x000F, 0x0007, 0x0007, 0xF81F, 0xFC0F, 0xFE0F, 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, 0x7F80, 0x7FC0, 0x7FE0, 0x7FF0, 0x0780, 0x03C0, 0x01E0, 0x0000 }; // Detecta la existencia del driver del ratn int DetectarRaton(void); // Muestra la flecha void MostrarRaton(void); // Oculta la flecha void OcultarRaton(void); // Establece una zona rectangular de la que el ratn no puede salir void EstablecerLimRaton(int,int,int,int); // Pone la flecha en una coordenada void EstablecerPosRaton(int,int); // Espera a que se pulse un botn determinado void EsperarPulsadoBoton(int *); // Espera a que se suelte el botn determinado void EsperarSoltadoBoton(int); // Espera a que se pulse el botn izquierdo void EsperarPulsadoBotonI(void); // Espera a que se suelte el botn izquierdo void EsperarSoltadoBotonI(void); // Espera a que se pulse el botn derecho void EsperarPulsadoBotonD(void); // Espera a que se suelte el botn derecho void EsperarSoltadoBotonD(void); // Lee la coordenada del ratn y el estado de los botones void LeerEstadoRaton(int *,int *,int *); // Lee slo la coordenada del ratn void LeerPosRaton(int *,int *); // Lee slo el estado de los botones void PulsadoBoton(int *); // Espera a que se pulse cualquier botn void EsperarPulsadoCualquierBoton(int *); // Cambia el puntero void CambiaPunteroRaton(void); // Inicializa el driver del ratn void InicializaRaton(int *,int *,char *); // Adeca la coordenada del ratn para las BGI de Borland C void EvitaIncompRaton1(int,int); // Guarda la coordenada actual y oculta la flecha void AlejaRaton(int *,int *); // Deshace el alejamiento del ratn guardando la compatibilidad con las BGI void AcercaRaton(int,int);

RATON.C
#include "raton.h" int DetectarRaton(void) { int w; asm{ mov ax,0

mov bx,2 int 0x33 mov w,ax } return(w); } void MostrarRaton( void ) { asm{ mov ax,1 int 0x33 } } void OcultarRaton( void ) { asm{ mov ax,2 int 0x33 } } void EstablecerLimRaton(int xi,int yi,int xf,int yf) { asm{ mov ax,7 mov cx,xi mov dx,xf int 0x33 mov ax,8 mov cx,yi mov dx,yf int 0x33 } } void EstablecerPosRaton(int x,int y) { asm{ mov ax,4 mov cx,x mov dx,y int 0x33 } } void EsperarPulsadoBoton(int *bot) { do { PulsadoBoton(bot); } while ((*bot!=1)&&(*bot!=2)); } void EsperarSoltadoBoton(int bot) { int *boton; do { PulsadoBoton(boton); } while (*boton==bot); } void EsperarPulsadoBotonI(void) { int *bot;

*bot=1; do { PulsadoBoton(bot); } while (*bot!=1); } void EsperarSoltadoBotonI(void) { int *bot; do { PulsadoBoton(bot); } while (*bot==1); } void EsperarPulsadoBotonD(void) { int *bot; // *bot=2; do { PulsadoBoton(bot); } while (*bot!=2); } void EsperarSoltadoBotonD(void) { int *bot; do { PulsadoBoton(bot); } while (*bot==2); } void LeerEstadoRaton(int *x,int *y,int *bot) { int xx,yy,boton; asm{ mov ax,3 int 0x33 mov boton,bx mov xx,cx mov yy,dx } // Si vale 1 es el izquierdo, si vale 2 es el derecho,si vale 4 el central *x=xx; *y=yy; *bot=(int)boton; } void LeerPosRaton(int *x,int *y) { int xx,yy; asm{ mov ax,3 int 0x33 mov xx,cx mov yy,dx } *x=xx; *y=yy; }

void PulsadoBoton(int *bot) { int boton; asm{ mov ax,3 int 0x33 mov boton,bx } // Si vale 1 es el izquierdo, si vale 2 es el derecho,si vale 4 el central *bot=(int)boton; } void EsperarPulsadoCualquierBoton(int *bot) { do { PulsadoBoton(bot); } while ((*bot==2)||(*bot==1)); } void CambiaPunteroRaton(void) { long dir; int dir2,dir3; dir=(long)cursor1; dir2=(int)dir; dir3=(int)(dir>>16); asm{ mov ax,9 mov bx,0 mov cx,0 mov dx,dir2 mov es,dir3 int 0x33 } } void InicializaRaton(int *posx,int *posy,char *hayraton) { *hayraton=DetectarRaton(); if (*hayraton==-1) { CambiaPunteroRaton(); EstablecerPosRaton(360,250); // EstablecerPosRaton(650,490); MostrarRaton(); LeerPosRaton(posx,posy); } } void EvitaIncompRaton(int posx,int posy) { if ((posx!=650)||(posy!=490)) { EstablecerLimRaton(0,0,630,470); } } void AlejaRaton(int *posx,int *posy) { LeerPosRaton(posx,posy); OcultarRaton(); } void AcercaRaton(int posx,int posy) { EstablecerLimRaton(0,0,650,490);

EstablecerPosRaton(650,490); MostrarRaton(); EstablecerPosRaton(posx,posy); EstablecerLimRaton(0,0,630,470); }

EJEMPLO DE USO
void main(void) { int bot; DetectarRaton(); do { sound(700); // Esperar pulsacin del botn izquierdo EsperarPulsadoBoton(&bot); // do // { // asm{ // mov ax,3 // int 0x33 // mov bot,bx // } // } // while ((bot!=1)&&(bot!=2)); nosound(); if (bot==1) EsperarSoltadoBotonI(); if (bot==2) EsperarSoltadoBotonD(); } while (!kbhit()); }

You might also like