{$g+}
unit maus2kb;
interface

uses
 kb;

var
 { not in delta-3d }
 mminx,
 mmaxx,
 mminy,
 mmaxy,
 mposx,
 mposy,
 visible,	{ iff =1 }
 mdbutton,	{ doubleclick }
 mtbutton,	{ 1 1/2 - click }

 { only delta-3d }
 mmovex,
 mmovey,
 mmovez,

 { both }
 mbutton,
 mbuttonchg:integer;


{Prozeduren für delta-3d-Modus:
 initmaus3d initialisiert den Maus-Modus
 mreset setzt mmove* auf 0

 Bei Mausbewegung/Tastendruck:(0:0) wird über Tastatur übergeben

 bei gedrückter rechter Maustaste:
  - Z-Bewegung
  - linke Maustaste spezial (0:255)
 sonst:
  - linke Maustaste schaltet mlock ein/aus }

procedure initmaus3d;
procedure mreset;

const
 mlock:boolean=false;

procedure initmaus;
procedure msetxy(x,y:word);
procedure msetct(_and,_xor:word);
procedure msetcg(hsx,hsy:word;var cursormask);
(* cursormask=array[{and,xor},0..15] of word; *)
procedure mshow;
procedure mhide;
procedure mhider(minx,miny,maxx,maxy:word);

implementation

procedure mreset;
begin
 mmovex:=0;
 mmovey:=0;
 mmovez:=0;
end;

{$ifndef unix}
var
 oldexitproc:pointer;
 timerhandler:pointer absolute 0:8*4;
 oldtimerhandler:pointer;

const
 dclick:word=0;

{$f+}
procedure newexitproc;
{$f-}
begin
 exitproc:=oldexitproc;
 asm
  xor ax,ax
  int $33
 end;
end;

{$f+}
procedure mousehandle;assembler;
{$f-}
asm
 push ds
 mov ax,seg @data
 mov ds,ax	{ ds=Datenseg PRG, cx,cy=x,y }
 shr cx,1
 shr dx,1
 sub cx,100
 sub dx,100	{ Bewegung angepaßt auf -100<=x,y<=100 }
 neg dx
 add mmovex,cx
 test bx,2	{ mb2 -> X,Z-Bewegung }
 jnz @zmove
 add mmovey,dx
 jmp @endmove
@zmove:
 add mmovez,dx
@endmove:
 mov al,mlock
 test bx,1
 jz @nopress	{\mb1\mb2: handle movement }
 test bx,2
 jz @lock	{ mb1\mb2: toggle mlock }
 push 0		{ mb1^mb2: special action }
 push 255
 jmp @keyput
@lock:		{ mlock toggled here }
 xor al,1
 mov mlock,al
 push 0
 push 0
@keyput:	{ mouse notify }
 call kbwrite
@nopress:
 mov si,bx
 xor si,mbutton
 mov mbutton,bx	{ set button status }
 mov mbuttonchg,si
 or al,al	{ if mouse locked ... }
 jz @nolock
 xor ax,ax 	{ ... set movement to zero ... }
 mov mmovex,ax
 mov mmovey,ax
 mov mmovez,ax
 jmp @reset2	{ ... and reset to center }
@nolock:	{ else if mouse moved ... }
 or dx,cx
 jz @skip
@reset:		{ ... notify and reset to center }
 push 0
 push 0
 call kbwrite
@reset2:	{ reset to center here }
 mov ax,4
 mov cx,200
 mov dx,200
 int $33
@skip:
 pop ds
end;

procedure initmaus;assembler;
asm
 xor ax,ax
 mov es,ax
 push word [es:$449]
  mov byte [es:$449],$10
  mov mmovex,ax
  mov mmovey,ax
  mov mmovez,ax
  mov mbutton,ax
  mov mbuttonchg,ax
  int $33
 pop word [es:$449]
 mov ax,7
 xor cx,cx
 mov dx,400
 int $33
 mov ax,8
 xor cx,cx
 mov dx,400
 int $33
 mov ax,4
 mov cx,200
 mov dx,200
 int $33
 mov ax,$f
 mov cx,24
 mov dx,48
 int $33
 mov ax,$c
 mov cx,$b
 push cs
 pop es
 mov dx,offset mousehandle
 int $33
end;

{$f+}
procedure mousehandle_n;assembler;
{$f-}
asm
 push ds
 mov ax,seg @data
 mov ds,ax	{ ds=Datenseg PRG, cx,cy=x,y }

 mov mposx,cx
 mov mposy,dx

 add mmovex,cx
 test bx,2	{ mb2 -> X,Z-Bewegung }
 jnz @zmove
 add mmovey,dx
 jmp @endmove
@zmove:
 add mmovez,dx
@endmove:
 mov al,mlock
 test bx,1
 jz @nopress	{\mb1\mb2: handle movement }
 test bx,2
 jz @lock	{ mb1\mb2: toggle mlock }
 push 0		{ mb1^mb2: special action }
 push 255
 jmp @keyput
@lock:		{ mlock toggled here }
 xor al,1
 mov mlock,al
 push 0
 push 0
@keyput:	{ mouse notify }
 call kbwrite
@nopress:
 mov si,bx
 xor si,mbutton
 mov mbutton,bx	{ set button status }
 mov mbuttonchg,si
 or al,al	{ if mouse locked ... }
 jz @nolock
 xor ax,ax 	{ ... set movement to zero ... }
 mov mmovex,ax
 mov mmovey,ax
 mov mmovez,ax
 jmp @reset2	{ ... and reset to center }
@nolock:	{ else if mouse moved ... }
 or dx,cx
 jz @skip
@reset:		{ ... notify and reset to center }
 push 0
 push 0
 call kbwrite
@reset2:	{ reset to center here }
 mov ax,4
 mov cx,200
 mov dx,200
 int $33
@skip:
 pop ds
end;

procedure timehandle;far;assembler;
asm
 push ds
 push ax
 mov ax,seg @data
 mov ds,ax
 sub dclick,1
 adc dclick,0
 pushf
 call oldtimerhandler
 pop ax
 pop ds
 iret
end;

procedure initmaus_n;assembler;
asm
 xor ax,ax
 mov mminx,ax
 mov mminy,ax
 mov mmovex,ax
 mov mmovey,ax
 mov mmovez,ax
 mov mbutton,ax
 mov mbuttonchg,ax
 int $33
 mov ax,3
 int $33
 shl cx,1
 shl dx,1
 mov mmaxx,cx
 mov mmaxy,dx
{ mov ax,$f
 mov cx,24
 mov dx,48
 int $33 }
 mov ax,$c
 mov cx,$f
 push cs
 pop es
 mov dx,offset mousehandle
 int $33
end;

procedure msetxy(x,y:word);assembler;
asm
 mov ax,4
 mov cx,x
 mov dx,y
 int $33
end;

procedure msetct(_and,_xor:word);assembler;
asm
 mov ax,9
 xor bx,bx
 mov cx,_and
 mov dx,_xor
 int $33
end;

procedure msetcg(hsx,hsy:word;var cursormask);assembler;
(* cursormask=array[{and,xor},0..15] of word; *)
asm
 mov ax,$a
 mov bx,hsx
 mov cx,hsy
 les dx,cursormask
 int $33
end;

procedure mshow;assembler;
asm
 inc visible
 mov ax,1
 int $33
end;


procedure mhide;assembler;
asm
 dec visible
 mov ax,2
 int $33
end;

procedure mhider(minx,miny,maxx,maxy:word);assembler;
asm
 mov ax,$10
 mov cx,minx
 mov dx,miny
 mov si,maxx
 mov di,maxy
 int $33
end;

begin
 oldtimerhandler:=timerhandler;
 oldexitproc:=exitproc;
 exitproc:=@newexitproc;
end.

{$else}

uses xcrt;
 
procedure initmaus;
begin
  Xsetmouse(1);
end;

procedure initmaus3d;
begin
  Xsetmouse(2);
end;

end.
{$endif}
