MOUSE.TXT

===============================================================================
     Date: 12-14-95    Time: 00:43a     Number: 3880   
     From: Magnus Holm                   Refer: 3878    
       To: Anders Sandvig             Board ID: INFOLINK        Reply: 
  Subject: VESA Mouse                       54: Programming/   Status: Public 
-------------------------------------------------------------------------------
Heisann!
AS│ Hvordan kan jeg mekke en egen mousehandler for VESA modes?
AS│ Jeg trenger bare en som tegner en cursor (gjerne en 256 fargers spri
AS│ Må jeg hooke meg på INT 33h? - I så fall hvor og hvordan?

Nå som jeg først har begynt å svare deg med lange sourcer, kan jeg
like godt fortsette :-)

Unit Mouse4;

{*******************************************************************}
{*                   Mouse4 - Text Mouse Unit                      *}
{*                     version .9, 11/20/87                        *}
{*                by Richard Sadowsky 74017,1670                   *}
{*                 released to the public domain                   *}
{*******************************************************************}

Interface

Uses DOS,CRT;

const
  CURPOS           = 1; { not used yet in this version }
  LEFTPRESS        = 2;
  LEFTREL          = 4;
  RIGHTPRESS       = 8;
  RIGHTREL         = 16;
  lbuttnum         = 4;
  mbuttnum         = 2;
  rbuttnum         = 1;
  Mouse_Scale : Byte = 1;
  Mouse_Irq       = $33;


type Graph_Cursor_Type      = ARRAY[0..31] OF WORD;

var
  Mouse_Reg        : Registers;
  Mouse_Installed  : Boolean;
  Mouse_Error      : Word;
  Mouse_Cursor_On : boolean;

  lbutt,mbutt,rbutt : boolean;
  mouseX,mouseY,mouseStat : Word;

  Mouse_Event_Busy         : WORD;
  Mouse_Event_Address      : POINTER;
  Mouse_Event_Mask         : BYTE;

  regs                     : registers;



function doubleclick:boolean;  { MAGNUS HOLM - 1995! }
function mousexy(x,y:word):boolean;{ --- II --- }
procedure getmouse;            { ------- II -------- }
procedure waitforrelease;      { ------- II -------- }


function InitMouse : Word;
{ Function 0 - Initialize mouse software and hardware }

procedure ShowMouseCursor;
{ function 1 - show mouse cursor }

procedure HideMouseCursor;
{ function 2 - hide mouse cursor }

procedure setmousexy(mousex, mousey: Word);
{ function 4 - sets mouse position  }
{ X and Y values scaled for 80 col text mode }

function mousepress(button: Word;
                     var count, lastx, lasty: Word): Word;
{ function 5 - gets button press information  }
{ X and Y values scaled for 80 col text mode }

function mouserelease(button: Word;
                       var count, lastx, lasty: Word): Word;
{ function 6 - gets button release information  }
{ X and Y values scaled for 80 col text mode }

procedure setmousewin(x1,y1,x2,y2: Word);
{ functions 7 and 8 - sets min/max values for horizontal/vertical  }
{ X and Y values scaled for 80 col text mode }

procedure restoremousewin;
{ functions 7 and 8 - restores min/max values for CGA screen }

procedure setmousesens(Horiz,Verti : Word);
{ function 15 - sets the mickey to pixel ratio (sets the mouse sensitivi

procedure GetMouseStatus;
{ return mouse position and button status in variables }
{ - shell around the MousePosition function ( no. 3 )  }
{ X and Y values scaled for 80 col text mode }

procedure setmouseform(scr,cur : word);
{ function 10 - set mouse cursor form }

function mousein(x1,y1,x2,y2 : integer) : boolean;

procedure waitforpress;

procedure define_graphics_cursor(var gc : graph_cursor_type;
          s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 : string

PROCEDURE Set_Graphics_Cursor(VAR GCursor : Graph_Cursor_Type;
                                  Hot_Spot_X, Hot_Spot_Y : INTEGER);


PROCEDURE Define_Event_Handler(Event_Mask      : BYTE;
                               Event_Procedure : POINTER);
{
This procedure defines an event handler which will interrupt when a spec
action from the mouse occurs. (See TECHNOTE.TXT for information on how t

the Event_Procedure). The Event_Mask is defined bitwise as follows :

                      Mask Bit   Condition
                    ------------------------------------
                      0          Cursor position changed
                      1          Left button pressed
                      2          Left button released
                      3          Right button pressed
                      4          Right button released
                      5          Middle button pressed
                      6          Middle button release

As you will see from the example in TECHNOTE.TXT, the Event_Procedure wi
receive values from the mouse hardware.

( var Flags, CS, IP,
      Event_Identification : Same as Event_Mask, but a bit is only set i
                             condition occured.
      Button_Status        : Same function as mentioned before.
      Mouse_X
      Mouse_Y
      Horizontal_Mickey_Count,
      Vertical_Mickey_Count  : word  );
}

PROCEDURE Stop_Mouse_Event;
{
Call this procedure when you want to disable the event handler from inte
rupting your program.
}


implementation
function mousexy(x,y:word):boolean;
begin
  mousexy:=(y=mousey) and (x=mousex);
end;

procedure getmouse;
begin
  getmousestatus;
  dec(mousex);
  dec(mousey);
end;

procedure waitforrelease;
begin
  repeat getmouse until not (lbutt or rbutt or mbutt);
end;

procedure intretrace;assembler;
asm
  mov dx,3DAh
@1:
  in al,dx
  and al,8h
  jnz @1
@2:
  in al,dx
  and al,8h
  jz @2
end;

function doubleclick:boolean;
var
  x,y,timer:byte;
const maxtimer=30;
begin
  doubleclick:=false;
  if not lbutt then exit;
  x:=mousex;
  y:=mousey;
  timer:=1;
  repeat getmouse until not lbutt;
  repeat getmouse; intretrace; inc(timer); until lbutt or mbutt or rbutt
sex<>x) or (mousey<>y) or (timer=maxtimer);
  doubleclick:=lbutt and (x=mousex) and (y=mousey) and (timer=x1) and (mousex<=x2)) and ((mousey>=y1) and (mousey

end;

procedure setmouseform(scr,cur : word);
begin
  with Mouse_Reg do begin
    Ax := 10;
    Bx:=0;
    Cx:=scr;
    Dx:=cur;
  end;
  Intr($33,Mouse_Reg);
end;

function MousePosition(var MouseX,MouseY : Word) : Word; forward;

procedure getmousestatus;
begin
  mousestat:=mouseposition(mousex,mousey);
  lbutt:=odd(mousestat);
  mbutt:=mousestat>=4;
  rbutt:=mousestat in [2,3,6,7];
end;

function InitMouse : Word;
{ Function 0 - Initialize mouse software and hardware }
begin
  with Mouse_Reg do
    Ax := 0;
  Intr($33,Mouse_Reg);
  InitMouse := Mouse_Reg.Ax;
end;

procedure ShowMouseCursor;
{ function 1 - show mouse cursor }
begin
  if mouse_cursor_on then exit;
  Mouse_Reg.Ax := 1;
  Intr($33,Mouse_Reg);
  Mouse_Cursor_On:=true;
end;

procedure HideMouseCursor;
{ function 2 - hide mouse cursor }
begin
  if not mouse_cursor_on then exit;
  Mouse_Reg.AX := 2;
  Intr($33,Mouse_Reg);
  Mouse_Cursor_On:=false;
end;

function MousePosition(var MouseX,MouseY : Word) : Word;
{ function 3 - return mouse position and button status }
{ X and Y values scaled for 80 col text mode }
begin
  Mouse_Reg.Ax := 3;
  Intr($33,Mouse_Reg);
  with Mouse_Reg do begin
    if Mouse_Scale=2 then begin
      MouseX := Succ(Cx DIV 8);
      MouseY := Succ(Dx DIV 8);
    end else if Mouse_Scale=1 then begin
      MouseX := Cx DIV 2;
      MouseY := Dx;
    end else begin
      MouseX := Cx;
      MouseY := Dx;
    end;
    MousePosition := Bx;
  end;
end;

procedure setmousexy(mousex, mousey: Word);
{ function 4 - sets mouse position  }
{ X and Y values scaled for 80 col text mode }
begin
  Mouse_Reg.ax:=4;
  if Mouse_Scale=2 then begin
    Mouse_Reg.cx:=Pred(mousex*8);
    Mouse_Reg.dx:=Pred(mousey*8);
  end else if Mouse_Scale=1 then begin
    Mouse_Reg.cx:=mousex*2;
    Mouse_Reg.dx:=mousey;
  end else begin
    Mouse_Reg.cx:=mousex;
    Mouse_Reg.dx:=mousey;
  end;
  intr($33,Mouse_Reg);
end;

function mousepress(button: Word;
                     var count, lastx, lasty: Word): Word;
{ function 5 - gets button press information  }
{ X and Y values scaled for 80 col text mode }
begin
  Mouse_Reg.ax:=5;
  Mouse_Reg.bx:=button;
  intr($33,Mouse_Reg);;
  mousepress:=Mouse_Reg.ax;
  count:=Mouse_Reg.bx;
  if Mouse_Scale=2 then begin
    lastx:=Succ(Mouse_Reg.cx div 8);
    lasty:=Succ(Mouse_Reg.dx div 8);
  end else if Mouse_Scale=1 then begin
    lastx:=Mouse_Reg.cx div 2;
    lasty:=Mouse_Reg.dx;
  end else begin
    lastx:=Mouse_Reg.cx;
    lasty:=Mouse_Reg.dx;
  end;
end;

function mouserelease(button: Word;
                       var count, lastx, lasty: Word): Word;
{ function 6 - gets button release information  }
{ X and Y values scaled for 80 col text mode }
begin
  Mouse_Reg.ax:=6;
  Mouse_Reg.bx:=button;
  intr($33,Mouse_Reg);;
  mouserelease:=Mouse_Reg.ax;
  count:=Mouse_Reg.bx;
  if Mouse_Scale=2 then begin
    lastx:=Succ(Mouse_Reg.cx div 8);
    lasty:=Succ(Mouse_Reg.dx div 8);
  end else if Mouse_Scale=1 then begin
    lastx:=Mouse_Reg.cx div 2;
    lasty:=Mouse_Reg.dx;
  end else begin
    lastx:=Mouse_Reg.cx;
    lasty:=Mouse_Reg.dx;
  end;
end;

procedure setmousewin(x1,y1,x2,y2: Word);
{ functions 7 and 8 - sets min/max values for horizontal/vertical  }
{ X and Y values scaled for 80 col text mode }
begin
  Mouse_Reg.ax:=7;
  if Mouse_Scale=2 then begin
    Mouse_Reg.cx:=Pred(x1*8);
    Mouse_Reg.dx:=Pred(x2*8);
  end else if Mouse_Scale=1 then begin
    Mouse_Reg.cx:=x1*2;
    Mouse_Reg.dx:=x2*2;
  end else begin
    Mouse_Reg.cx:=x1;
    Mouse_Reg.dx:=x2;
  end;
  intr($33,Mouse_Reg);
  Mouse_Reg.ax:=8;
  if Mouse_Scale=2 then begin
    Mouse_Reg.cx:=Pred(y1*8);
    Mouse_Reg.dx:=Pred(y2*8);
  end else if Mouse_Scale=1 then begin
    Mouse_Reg.cx:=y1;
    Mouse_Reg.dx:=y2;
  end else begin
    Mouse_Reg.cx:=y1;
    Mouse_Reg.dx:=y2;
  end;
  intr($33,Mouse_Reg);
end;

procedure restoremousewin;
{ functions 7 and 8 - restores min/max values for CGA screen }
begin
  Mouse_Reg.ax:=7;
  Mouse_Reg.cx:=0;
  Mouse_Reg.dx:=639;
  intr($33,Mouse_Reg);
  Mouse_Reg.ax:=8;
  Mouse_Reg.cx:=0;
  Mouse_Reg.dx:=199;
  intr($33,Mouse_Reg);
end;

procedure setmousesens(Horiz,Verti : Word);
{ function 15 - sets the mickey to pixel ratio }

begin
  with Mouse_Reg do begin
    Ax := 15;
    Cx := Horiz;
    Dx := Verti;
  end;
  Intr($33,Mouse_Reg)
end;

{$F+}   {Very important. NEVER REMOVE THESE, otherwise the irq-handler w
{$S-}   {work. The INLINE code below MUST be assembled as pure m/c code
{$R-}
PROCEDURE Mouse_Event_Handler; {$F-}
BEGIN
  INLINE (
          $A1/Mouse_Event_Busy/     { MOV AX, Mouse_Event_Busy }
          $3D/01/00/                { CMP AX, 1                }
          $75/$01/                  { JNZ LBL001               }
          $CB/                      { RETF                     }
{LBL001:}
          $FF/$06/Mouse_Event_Busy/ { INC Mouse_Event_Busy     }
          $CD/$60/                  { INT 60                   }
          $FF/$0E/Mouse_Event_Busy  { DEC Mouse_Event_Busy     }
         )
END;
{$S+}
{$R+}


PROCEDURE Define_Event_Handler(Event_Mask      : BYTE;
                               Event_Procedure : POINTER);
BEGIN
  Mouse_Event_Address := @Mouse_Event_Handler;
  Mouse_Event_Mask    := Event_Mask;
  Mouse_Event_Busy    := 0;
  Regs.AX             := 12;
  Regs.CX             := Event_Mask;
  Regs.ES             := SEG(Mouse_Event_Address^);
  Regs.DX             := OFS(Mouse_Event_Address^);
  SetIntVec($60, Event_Procedure);
  INTR(Mouse_Irq, Regs)
END;

PROCEDURE Stop_Mouse_Event;
VAR Stop_Address : POINTER;
BEGIN
  Define_Event_Handler(0, @Stop_Address);
  Mouse_Event_Busy := 0;
END;

begin
  Mouse_Error := InitMouse;
  Mouse_Installed := Mouse_Error = 65535;
  Mouse_Cursor_On:=false;
  if Mouse_Installed then begin
    getmousestatus;
    setmouseform($FFFF,$7700);
    restoremousewin;
  end;
end.

MBBS klarer 499 linjer?? - I så fall har jeg TI igjen :)
Kluet er å lese av posisjonene, og tegne en sprite der..
Jeg tror det funker fint i VESA...!?
---
 ■ Magnus Holm 
 ■ Call Programmers BBS at +47 22714107
===============================================================================
     Date: 12-16-95    Time: 05:24a     Number: 3888   
     From: Kurt_Inge Grønbech            Refer: 0       
       To: Anders Sandvig             Board ID: INFOLINK        Reply: 
  Subject: VESA Mouse                       54: Programming/   Status: Public 
-------------------------------------------------------------------------------
AS>  MH> Du er vel såpass stødig til å programmere at du greier å

AS>  MH> getmousestatus;
AS>  MH> getSprite(mousex,mousey,backGround);
AS>  MH> tegnSprite(mousex,mousey,spriten);
AS>  MH> osv...??:)

AS>  Joda, men poenget er at jeg helst vil at mouseinterrupten skal ta s
AS>  av den saken slik at jeg slipper a gjøre alt det der i en masse
AS>  forskjellige looper i progget mitt.

Det du kan gjøre er å programmere en mousehandler som tegner opp muspila 
(og sletter den når man flytter på musa)...:

mousehandler()
{
   Slett pil som allerede er på skjermen
   Tegn ny pil
}

{
   asm {
     mov ax, seg mousehandler
     mov es, ax
     mov dx, offset mousehandler
     mov ax, 12
     mov cx, 0x1f  
     int 0x33
   }
}

Cluet er altså Int 33h, function 12

  ┌                                                          ┐
         Kurt Inge Grønbech ■ Ghoul / Xenon Development
  └                                                          ┘
===============================================================================