program Nsamp19;       {Mouse Interface Demonstration}

{This program demonstrates most of the procedures available in Turbo Plus
 for control of the Mouse.  The mouse can be used in either graphics or text
 mode.  This sample demonstrates mouse usage in graphics mode.  To run this
 program you must have a graphics display system and a mouse installed.  }

uses crt,tplus,graph;
var
  buttons:integer;
  GraphDriver : integer;  { The Graphics device driver }
  GraphMode   : integer;  { The Graphics mode value }
  MaxX, MaxY  : word;     { The maximum resolution of the screen }
  ErrorCode   : integer;  { Reports any graphics errors }
  MaxColor    : word;     { The maximum color value available }
  OldExitProc : Pointer;  { Saves exit procedure address }
  xpos,ypos   : Integer;  { Mouse positions }
  xdist,ydist : integer;  { Mouse distance variables }
  bstat       : word;     { Mouse button status }
  presses     : integer;  { Mouse presses accumulator }
  releases    : integer;  { Mouse releases accumulator }
  lastx,lasty : integer;  { Mouse position upon press or release }

type mousemasks = array[0..31] of word;

const

  ScopeCursor:mousemasks = (

  $feff,    {*******.********}     {Screen Mask}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $0001,    {...............*}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $feff,    {*******.********}
  $ffff,    {****************}

  $0100,    {.......*........}     {Cursor Mask}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $fffe,    {***************.}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0100,    {.......*........}
  $0000);   {................}


procedure Initialize;
{ Initialize graphics and report any errors that may occur }
begin
  { when using Crt and graphics, turn off Crt's memory-mapped writes }
  DirectVideo := false;
  DetectGraph(GraphDriver, GraphMode);    { Test for RESERVED driver }
  InitGraph(GraphDriver, GraphMode, '\TP');  { activate graphics }
  ErrorCode := GraphResult;               { error? }
  if ErrorCode <> grOk then
  begin
    Writeln('Graphics error: ', GraphErrorMsg(ErrorCode));
    Halt(1);
  end;
  MaxX := GetMaxX;          { Get screen resolution values }
  MaxY := GetMaxY;
  SetColorsn(lightgray,black);
end; { Initialize }


Function MouseButtonCheck(bstat, bmask : Word) : Boolean;
  inline(
         $5A/
         $58/
         $21/$D0/               {Just AND the two valus together}
         $74/$03/
         $B8/$01/$00);          {And return true or false}


{********************* Main Line Start Here *************************}

begin
  initialize;             {Use Graphics}
  MouseInit(buttons);     {INITIALIZE MOUSE CURSOR}
  if buttons <> 0 then
  writeln('Mouse has ',buttons,' buttons.  Move it around and Click on Button 1.')
  else
  begin
    writeln('Mouse Not Installed');
    closegraph;
    halt;
  end;

  MouseShowCursor;        {BRING UP THE MOUSE CURSOR}

  repeat
  MouseFind(xpos,ypos,bstat);        {WAIT TILL CLICK AND FIND CURSOR}
  until MouseButtonCheck(bstat,1);
  MouseMotion(xdist,ydist);
  MouseHideCursor;
  writeln('Mouse Click at (',xpos,',',ypos,')');
  writeln('Mouse motion was (',xdist,',',ydist,')');
  writeln;
  writeln('Click Again On Button 1 When Ready...');
  MouseShowCursor;
  MousePress(0,presses,lastx,lasty,bstat);  {CLEAR PRESSES}
  repeat
    MousePress(0,presses,lastx,lasty,bstat);
  until presses <> 0;            {CONTINUE WHEN BUTTON PRESSED AGAIN}
  MouseHideCursor;
  cleardevice;
  gotoxy(1,1);
  writeln('Now Hold Down Button 2 And Mouse Will Move Until Released');
  MouseMove(0,0);
  MouseShowCursor;
  MousePress(1,presses,lastx,lasty,bstat);  {CLEAR PRESSES}
  repeat
    MousePress(1,presses,lastx,lasty,bstat);
  until presses <> 0;
    xpos:=0;
    ypos:=0;
    MouseRelease(1,releases,lastx,lasty,bstat); {CLEAR RELEASES}
  repeat
    if xpos >= getmaxx then
    begin
      xpos:=0;
      ypos:=0;
    end else xpos:=xpos+2;
    if ypos < getmaxy then ypos:=ypos+2 else ypos:=getmaxy-8;
    MouseMove(xpos,ypos);
    MouseRelease(1,releases,lastx,lasty,bstat); {MOVE CURSOR UNTIL RELEASED}
  until releases <> 0;
  MouseHideCursor;
  cleardevice;
  rectangle(100,100,199,199);
  MouseArea(100,100,199,199);   {RESTRICT MOUSE TO RECTANGLE AREA}
  MouseMickey(48,128);          {INCREASE THE MOUSE LEVERAGE}
  writeln('Mouse is now restricted to the rectangle area.  Notice that');
  writeln('the Hot Spot is up and to the left of the cursor point.  The');
  writeln('Leverage on the Mouse has also been increased.');
  writeln('Click on 1 to change Cursor to Scope Cursor.');
  MouseShowCursor;
  repeat
    MouseFind(xpos,ypos,bstat);        {WAIT TILL CLICK AND FIND CURSOR}
  until MouseButtonCheck(bstat,1);
  MouseHideCursor;
  MouseMakeCursor(7,7,scopecursor);    {MAKE A NEW MOUSE CURSOR}
  MouseShowCursor;
  MousePress(0,presses,lastx,lasty,bstat);  {CLEAR PRESSES}
  repeat
    MousePress(0,presses,lastx,lasty,bstat);
  until presses <> 0;
  closegraph;
end.
