home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_PAS / XLIB_TP5.ZIP / UNITS / X_MOUSE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-11-21  |  17KB  |  669 lines

  1. unit X_Mouse;
  2.  
  3. (*
  4.     Basic Mouse Routines for Mode X
  5.  
  6.     ****** XLIB - Mode X graphics library                ****************
  7.     ******                                               ****************
  8.     ****** Written By Themie Gouthas ( C-Version )       ****************
  9.     ****** Converted By Christian Harms in TP            ****************
  10.  
  11.     Gouthas : egg@dstos3.dsto.gov.au or teg@bart.dsto.gov.au
  12.     Harms   : harms@minnie.informatik.uni-stuttgart.de
  13.  
  14.     documentation in german and english
  15. *)
  16.  
  17. (* Es werden die letzten 42 Bytes des Bildschirmspeicher zum schnellen *)
  18. (* Zwischenschpeichern des Maushintergrunds genutzt !                  *)
  19. (* The last 42 Bytes of Video-RAM are used to same the Mouse - Pointer *)
  20. (* BackGround .                                                        *)
  21. interface
  22.  
  23. var  ButtonStatus,
  24.      MouseX,
  25.      MouseY         : Word;
  26.      OldMouseTyp,        (* True, wenn Mausz. sonst nur zur Haelfe geht *)
  27.                          (* if your MousePointer only go to the hald of *)
  28.                          (* screen, set it to true.                     *)
  29.      MouseAction    :Boolean; (* Auf true gesetzt, wenn Maus bewegt wird *)
  30.                           (* Rücksetzen ist dem Programmierer überlassen.*)
  31.                           (* It will be true, if MousePointer moved. You *)
  32.                           (* can it use it, by set to false and wait.    *)
  33.  
  34. const MyMouseForm : Array[1..14] of Byte =
  35.     ($01,$03,$07,$0f,$1f,$3f,$7f,$ff,$ff,$1c,$3c,$7c,0,0);
  36.  
  37. (* Setzt den Mauszeiger auf Unsichtbar                                   *)
  38. (* Hide the mousepointer                                                 *)
  39. procedure HideMouse;
  40. (* Setzt den Mauszeiger auf sichtbar                                     *)
  41. (* Show the mousepointer                                                 *)
  42. procedure ShowMouse;
  43.  
  44. (* Beim Zeichnen auf activ_page muss der Mauszeiger unsichtbar sein.     *)
  45. (* While drawing on activ_page mousepointer have to be hiding.           *)
  46.  
  47. (* Installiert einen Maus-event für Mode X.                              *)
  48. (* Install mouseevent for mode X.                                        *)
  49. procedure MyMouseInit;
  50.  
  51. (* Deinstalliert den Maus-event.                                         *)
  52. (* Deinstall the mousevent.                                              *)
  53. procedure MyMouseDestroy;
  54.  
  55. (* Setzt einen MausCursor - eine Bitmaske.                               *)
  56. (* set a mousecursor - bitmask.                                          *)
  57. procedure DefineMouseCursor(var MouseDef : Array of Byte;Color : Byte);
  58.  
  59. (* Setzt das Mausfenster, indem sich der Mauszeiger aufhalten kann.      *)
  60. (* Set the mousewindow. Mousepointer can't leave this window.            *)
  61. procedure SetMouseWindow(x1,y1,x2,y2:Word);
  62.  
  63. (* Setzt den MausZeiger auf die Position (x,y).                          *)
  64. (* set the mousepointer to (x,y).                                        *)
  65. procedure SetPosMouse(x,y:Integer);
  66.  
  67. (* Ist true, wenn die Maus unsichtbar ist. Wenn nach ShowMouse true ->   *)
  68. (* ist keine Maus installiert.                                           *)
  69. (* Return true, if mOuse hide.                                           *)
  70. function  IsMouseHidden:Boolean;
  71.  
  72. (* Gibt true, wenn der Mauszeiger in diesem Rechteck ist.                *)
  73. (* Return true, if mousepointer in this rectangle.                       *)
  74. function  InBox(x1,y1,x2,y2:Integer):Boolean;
  75.  
  76. implementation
  77.  
  78. uses crt,dos,X_Const;
  79.  
  80.  
  81. var MouseInstalled,  (* True, wenn eigenen Treiber installiert *)
  82.     MouseHidden,    (* True, wenn Maus unsichtbar             *)
  83.     InHandler       (* True, wenn grad im Maus_Handler        *)
  84.                     : Boolean;
  85.     ButtonCount,    (* Anzahl der Maustasten *)
  86.     MouseColor
  87.                     : Byte;
  88.     OldX,OldY,OldScreenOfs
  89.                     : Word;
  90.     MouseMask       : Array[0..168] of Byte;
  91.  
  92. (* interne Funktion : Restauriert den CursorHintergrund          *)
  93. (* SI: ScreenOffset,  AX = Y,   BX = X                           *)
  94. procedure restoreBG; assembler;
  95. asm;
  96.   push ds
  97.   cld
  98.  
  99.   mov cx,X_Const.ScrnLogicalByteWidth
  100.   mul cx                 (* Y*ScreenBreite+ScreenOfs+x/4 *)
  101.   add di,ax
  102.   sub cx,3
  103.   shr bx,1
  104.   shr bx,1
  105.   add di,bx
  106.   mov si,BGSaveOffs
  107.   mov ax,$a000
  108.   mov es,ax              (* ES: zeigt auf ScreenSeg *)
  109.   mov ds,ax
  110.  
  111.   mov dx,3ceh            (* Graphics controller Index *)
  112.   mov ax,008h            (* index in GC of Bit Mask Register *)
  113.   out dx,ax              (* Set bitmask: all of VGA Latches and *)
  114.                          (*              none of CPU            *)
  115.   mov dx,3c4h            (* Sequence Controller Register *)
  116.   mov al,002h            (* index in SC of Map Mask register *)
  117.   out dx,al              (* SC register zeigt schon auf Masking Data *)
  118.   inc dx
  119.   mov al,0fh
  120.   out dx,al
  121.  
  122.   mov bx,cx
  123.   mov cx,14
  124.  
  125.   @Loop:
  126.     movsb
  127.     movsb
  128.     movsb
  129.     add di,bx
  130.     loop @Loop
  131.  
  132.   mov dx,3cfh            (* restore bitmask to its default, which *)
  133.   mov al,$ff             (* selects all bits from the CPU and none *)
  134.   out dx,al              (* of VGA Latches *)
  135.  
  136.   pop ds
  137.  
  138. end;
  139.  
  140. (* interne Funktion : Speichert den CursorHintergrund            *)
  141. (* SI: ScreenOffset,  AX = Y,   BX = X                           *)
  142. procedure getBG;      assembler;
  143. asm;
  144.   push ds
  145.   cld
  146.  
  147.   mov cx,ScrnLogicalByteWidth
  148.   mul cx
  149.   add si,ax
  150.   sub cx,3
  151.   shr bx,1
  152.   shr bx,1
  153.   add si,bx
  154.   mov di,BGSaveOffs
  155.   mov ax,$a000
  156.   mov es,ax
  157.   mov ds,ax
  158.  
  159.   mov dx,3ceh            (* set bitmask  from VGA Latches and none of CPU *)
  160.   mov ax,008h
  161.   out dx,ax
  162.  
  163.   mov dx,3c4h
  164.   mov al,02h
  165.   out dx,al
  166.   inc dx
  167.   mov al,0fh
  168.   out dx,al
  169.  
  170.   mov bx,cx
  171.   mov cx,14
  172.  
  173.   @Loop:
  174.     movsb
  175.     movsb
  176.     movsb
  177.     add si,bx
  178.     loop @Loop
  179.  
  180.   mov dx,3cfh            (* restore Bitmask from Latches to CPU *)
  181.   mov al,$ff
  182.   out dx,al
  183.  
  184.   pop ds
  185. end;  (* getBG *)
  186.  
  187. procedure x_Put_Cursor(x,y,TopClip,BottonClip : Integer;
  188.                        ScrnOfs            : Word    );   assembler;
  189. var Height,TopRow,NextLine:Word;
  190. asm;
  191.   push ds
  192.   mov ax,SEG ScrnLogicalByteWidth
  193.   mov ds,ax
  194.  
  195.   mov ax,14              (* Zeichenhöhe *)
  196.   mov bx,y
  197.   (* Clipping für obere Bildschirmgrenze berechnen *)
  198.   mov dx,TopClip
  199.   sub dx,bx
  200.   jle @NotTopClip        (* kein Clipping *)
  201.   cmp dx,ax
  202.   jnl @NoAction           (* Unsichtbar, also raus *)
  203.   mov cx,dx
  204.   sub ax,dx
  205.   add bx,dx
  206.   jmp @VertClipDone
  207.   (* Clipping für untere Bildschirmgrenze berechnen *)
  208. @NotTopClip:
  209.   mov dx,BottonClip
  210.   sub dx,bx
  211.   js  @NoAction
  212.   mov cx,0
  213.   cmp dx,ax
  214.   jg  @VertClipDone
  215.   inc dx
  216.   mov ax,dx
  217.   (* eigentliche Zeichenroutine / Vorbereitungen *)
  218. @VertClipDone:
  219.   mov Height,ax
  220.   mov TopRow,cx
  221.  
  222.   mov ax,$A000           (* es point to ScreenSeg *)
  223.   mov es,ax
  224.  
  225.   mov ax,bx
  226.   mov cx,ScrnLogicalByteWidth
  227.   mul cx
  228.   mov di,ax
  229.  
  230.   sub cx,3
  231.   mov NextLine,cx
  232.  
  233.   mov cx,x
  234.   mov bx,cx
  235.   shr cx,1
  236.   shr cx,1
  237.   add di,cx
  238.   and bx,3
  239.   add di,ScrnOfs
  240.   (* eigentliche Zeichenroutine / Zeichnen *)
  241.   mov ax,42
  242.   mul bx
  243.   mov si,OFFSET MouseMask
  244.   add si,ax
  245.  
  246.   mov ax,3               (* INC DS:BX und DS:SI  to top border *)
  247.   mul TopRow
  248.   add si,ax
  249.  
  250.   mov dx,3c4h            (* Sequence Controller Index *)
  251.   mov al,02              (* index in SC of Map Mask Register *)
  252.   out dx,al
  253.   inc dx
  254.   mov ah,byte ptr [Height] (* AH = ScanLine Loop-Counter *)
  255.   mov bl,MouseColor
  256.  
  257.   @RowLoop:
  258.     mov cx,3             (* Breite in Bytes *)
  259.  
  260.     @ColLoop:
  261.       lodsb
  262.       out dx,al
  263.       mov es:[di],bl
  264.       inc di
  265.       loop @ColLoop
  266.  
  267.     add di,NextLine
  268.     dec ah
  269.     jnz @RowLoop
  270.  
  271. @NoAction:
  272.   pop ds
  273.   nop
  274. end;
  275.  
  276. {$F+}
  277. procedure Maus_Handler{(Flags,ax,bx,cx,dx,si,di,es:Word); interrupt};  assembler;
  278. asm;
  279.   push ds
  280.   push si
  281.   push di
  282.   push ax
  283.   push bx
  284.   push cx
  285.   push dx
  286.  
  287.   mov ax,SEG ScrnLogicalByteWidth          (* Falls DS geaendert *)
  288.   mov ds,ax
  289.   mov InHandler,True
  290.  
  291.   mov ButtonStatus,bx               (* ButtonStatus eintragen *)
  292.   test cx,1                         (* Wenn Bewegungs-event : *)
  293.   jnz @NoAction
  294.  
  295.   cmp OldMouseTyp,true
  296.   jne @Weiter
  297.   shr cx,1
  298. @Weiter:
  299.   mov MouseX,cx
  300.   mov MouseY,dx
  301.  
  302.   mov MouseAction,true
  303.  
  304.   cmp MouseHidden,true
  305.   je  @NoAction
  306.  
  307.   (* WaitVSyncStart *)
  308.       mov  dx,3dah
  309.   @1: in   al,dx
  310.       test al,8
  311.       jnz  @1
  312.   @2: in   al,dx
  313.       test al,8
  314.       jz @2
  315.  
  316.   mov di,OldScreenOfs
  317.   mov ax,OldY
  318.   mov bx,OldX
  319.   call restoreBG
  320.  
  321.   mov si,X_Const.ScreenOfs
  322.   mov ax,MouseY
  323.   mov bx,MouseX
  324.   mov OldScreenOfs,si
  325.   mov OldY,ax
  326.   mov OldX,bx
  327.   call getBG
  328.  
  329.   push MouseX
  330.   push MouseY
  331.   xor  ax,ax
  332.   push ax
  333.   mov  ax,GetMaxY
  334.   push ax
  335.   push X_Const.ScreenOfs
  336.   call x_Put_Cursor
  337.  
  338. @NoAction:
  339.   mov InHandler,false
  340.   pop dx
  341.   pop cx
  342.   pop bx
  343.   pop ax
  344.   pop di
  345.   pop si
  346.   pop ds
  347. end;
  348. {$F-}
  349.  
  350. procedure MyMouseInit; assembler;
  351. asm;
  352.   cmp MouseInstalled,True               (* Wenn schon installiert, raus *)
  353.   je  @EndNo
  354.  
  355.   xor ax,ax                            (* Wenn kein Maus-Device, raus *)
  356.   int 33h
  357.   or  ax,ax
  358.   jz  @EndNo
  359.  
  360.   mov ButtonCount,bl
  361.  
  362.   mov ax,02                            (* Hide Cursor *)
  363.   int 33h
  364.  
  365.   mov ax,07h                           (* Set Min/Max horiz. Position *)
  366.   mov cx,0
  367.   mov dx,GetMaxX
  368.   sub dx,8
  369.   shl dx,1                             (* Cursorbewegung aller 2 Pixel ? *)
  370.   int 33h
  371.  
  372.   mov ax,08h                           (* Set Min/Max vertical Position *)
  373.   mov cx,0
  374.   mov dx,GetMaxY
  375.   int 33h
  376.  
  377.   mov ax,0fh                           (* Set hor/ver. Speed *)
  378.   mov cx,4
  379.   mov dx,4
  380.   int 33h
  381.  
  382.   mov ax,12                            (* Define event-Handler *)
  383.   mov bx,SEG Maus_Handler
  384.   mov es,bx
  385.   mov dx,OFFSET Maus_Handler
  386.   mov cx,1fh
  387.   int 33h
  388.  
  389. @EndYes : mov MouseInstalled,true       (* Default - Werte *)
  390.           mov MouseHidden,true
  391.           mov MouseX,1
  392.           mov MouseY,1
  393. @EndNo  :                              (* Ende ohne etwas zu installieren *)
  394. end; (* MyMouseInit *)
  395.  
  396. procedure SetMouseWindow(x1,y1,x2,y2:Word); assembler;
  397. asm
  398.   mov ax,07h                           (* Set Min/Max horiz. Position *)
  399.   mov cx,x1
  400.   mov dx,x2
  401.   sub dx,7
  402.   shl dx,1                             (* Cursorbewegung aller 2 Pixel ? *)
  403.   int 33h
  404.  
  405.   mov ax,08h                           (* Set Min/Max vertical Position *)
  406.   mov cx,y1
  407.   mov dx,y2
  408.   int 33h
  409. end;
  410.  
  411. procedure MyMouseDestroy; assembler;
  412. asm;
  413.   cmp MouseInstalled,False              (* Wenn nicht installiert, raus *)
  414.   je  @EndNo
  415.  
  416.   call HideMouse
  417.  
  418.   mov ax,12                            (* Install event-Handler *)
  419.   xor cx,cx                            (* Disable all events    *)
  420.   int 33h
  421.  
  422.   mov MouseInstalled,false;
  423.  
  424. @EndNo:
  425. end;
  426.  
  427. (*----------------------------------------------------------------------    *)
  428. (* Local function that updates the cursor position                          *)
  429. (*                                                                          *)
  430. (* Destroys SI,DI,AX,BX                                                     *)
  431. (*                                                                          *)
  432. (*----------------------------------------------------------------------    *)
  433. procedure  update_cursor; assembler;
  434. asm
  435.    call WaitVsyncStart
  436.  
  437.    mov di,[OldScreenOfs]           (* Delete cursor (restore old background) *)
  438.    mov ax,[OldY]
  439.    mov bx,[OldX]
  440.  
  441.    call restorebg
  442.  
  443.    mov si,[ScreenOfs]        (* Save cursor background *)
  444.    mov ax,[MouseY]
  445.    mov bx,[MouseX]
  446.    mov [OldScreenOfs],si
  447.    mov [OldY],ax
  448.    mov [OldX],bx
  449.    call getbg
  450.  
  451.    push [ScreenOfs]                  (* Draw the cursor        *)
  452.    mov  ax,[ScrnPhysicalHeight]
  453.    push ax
  454.    mov  ax,0
  455.    push ax
  456.    push [OldY]
  457.    push [OldX]
  458.    call x_put_cursor
  459.    add  sp,10
  460.    ret
  461. end;
  462.  
  463.  
  464. (*----------------------------------------------------------------------    *)
  465. (* x_update_mouse - Forces the mouse position to be updated and cursor      *)
  466. (*                  to be redrawn.                                          *)
  467. (*                                                                          *)
  468. (*                                                                          *)
  469. (* Note this function is useful when you have set "MouseFrozen" to true.    *)
  470. (* Allows the cursor position to be updated manually rather than            *)
  471. (* automatically by the installed handler.                                  *)
  472. (*                                                                          *)
  473. (*                                                                          *)
  474. (* Written by Themie Gouthas                                                *)
  475. (*----------------------------------------------------------------------    *)
  476. procedure x_update_mouse; assembler;
  477. asm
  478.      cmp   [MouseInstalled],FALSE    (* Make sure our handler is installed  *)
  479.      je    @@Done
  480.      cmp   [MouseHidden],FALSE       (* If cursor is already hidden exit    *)
  481.      jne   @@Done
  482.      push  si
  483.      push  di
  484.      mov   ax,03h                 (* FUNC 3: get cursor pos / button status *)
  485.      int   33h                    (* Update position variables first        *)
  486.      shr   cx,1
  487.      mov   [MouseX],cx
  488.      mov   [MouseY],dx
  489.      mov   [ButtonStatus],bx    (* Update button status                *)
  490.      call  update_cursor
  491.      pop   di
  492.      pop   si
  493. @@Done:
  494.      pop   bp
  495.      ret
  496. end;
  497.  
  498. (*----------------------------------------------------------------------    *)
  499. (* x_position_mouse - Positions the mouse cursor at the specified location  *)
  500. (*                                                                          *)
  501. procedure x_position_mouse(x,y:Word); assembler;
  502. asm
  503. @@WaitEndOfHandler:               (* Make sure handler not currently active *)
  504.      mov   bl,[inhandler]
  505.  
  506.      or    bl,bl
  507.      jnz   @@WaitEndOfHandler
  508.  
  509.      mov   ax,4
  510.      mov   cx,X
  511.      mov   dx,Y
  512.      mov   [MouseX],cx
  513.      mov   [MouseY],dx
  514.      shl   cx,1
  515.  
  516.      mov   [inhandler],1
  517.      int   33h
  518.  
  519.      (* The handler doesnt get called so need *)
  520.      (* to update manually;                   *)
  521.  
  522.      cmp   [MouseHidden],FALSE
  523.      jne   @@NotVisible
  524.      push  di
  525.      push  si
  526.      call  update_cursor
  527.      pop   si
  528.      pop   di
  529.  
  530. @@NotVisible:
  531.      mov   [inhandler],0
  532.      pop   bp
  533.      ret
  534. end;
  535.  
  536.  
  537. procedure SetPosMouse(x,y:Integer); assembler;
  538. asm;
  539.   mov ax,4
  540.   mov cx,x
  541.   shl cx,1
  542.   mov dx,y
  543.   int 33h
  544. end;
  545.  
  546. procedure HideMouse;   assembler;
  547. asm;
  548.   cmp MouseInstalled,false    (* Kein Handler -> raus *)
  549.   je  @NoAction
  550.  
  551.   cmp MouseHidden,false      (* wenn unsichtbar -> raus *)
  552.   jne @NoAction
  553.  
  554. @WaitEndOfHandler:
  555.   mov cl,InHandler
  556.   or cl,cl
  557.   jnz @WaitEndOfHandler
  558.  
  559.   mov MouseHidden,True
  560.   mov di,OldScreenOfs
  561.   mov ax,OldY
  562.   mov bx,OldX
  563.   call restoreBG
  564.  
  565. @NoAction:
  566. end;
  567.  
  568. procedure ShowMouse;  assembler;
  569. asm;
  570.   cmp MouseInstalled,false
  571.   je  @NoAction
  572.  
  573.   cmp MouseHidden,false
  574.   je  @NoAction
  575.  
  576. @WaitEndOfHandler:
  577.   mov cl,InHandler
  578.   or cl,cl
  579.   jnz @WaitEndOfHandler
  580.  
  581.   mov si,X_Const.ScreenOfs
  582.   mov ax,MouseY
  583.   mov bx,MouseX
  584.   mov OldScreenOfs,si
  585.   mov OldY,ax
  586.   mov OldX,bx
  587.   call getBG
  588.  
  589.   push OldX
  590.   push OldY
  591.   xor ax,ax
  592.   push ax
  593.   mov ax,X_Const.GetMaxY
  594.   push ax
  595.   push X_Const.ScreenOfs
  596.   call x_Put_Cursor
  597.  
  598.   mov MouseHidden,False
  599.  
  600. @NoAction:
  601. end;
  602.  
  603. procedure DefineMouseCursor(var MouseDef : Array of Byte;
  604.                             Color   : Byte);         assembler;
  605. asm;
  606.   cmp MouseInstalled,false
  607.   je  @NoAction
  608.  
  609.   push ds
  610.  
  611.   mov al,Color
  612.   mov MouseColor,al
  613.  
  614.   mov ax,ds                    (* ES:DI Feld für alle Pixelsachen vom *)
  615.   mov es,ax                    (* Mauszeiger *)
  616.   mov di,OFFSET MouseMask
  617.  
  618.   lds si,DWord Ptr [MouseDef]
  619.   xor cl,cl
  620.  
  621.   @Loop:
  622.     push si
  623.     mov dh,14
  624.  
  625.     @RowLoop:
  626.       lodsb
  627.  
  628.       xor ah,ah
  629.       shl ax,cl
  630.  
  631.       mov bl,al
  632.       and bl,0fh
  633.       mov es:[di],bl
  634.       inc di
  635.       shr al,1
  636.       shr al,1
  637.       shr al,1
  638.       shr al,1
  639.       stosw
  640.       dec dh
  641.       jnz @RowLoop
  642.  
  643.     pop si
  644.     inc cl
  645.     cmp cl,4
  646.     jne @Loop
  647.  
  648.   pop ds
  649. @NoAction:
  650. end;
  651.  
  652. function  InBox(x1,y1,x2,y2:Integer):Boolean;
  653. begin;
  654.   InBox:= (MouseX>=X1)and(MouseX<=X2)and(MouseY>=y1)and(MouseY<=y2);
  655. end;
  656.  
  657. function  IsMouseHidden:Boolean;
  658. begin;
  659.   IsMouseHidden:=MouseHidden;
  660. end;
  661.  
  662. (* UNIT - CODE *)
  663. begin;
  664.   MouseInstalled := false;
  665.   MouseHidden   := True;
  666.   InHandler     := false;
  667.   BGSaveOffs    := BGSaveOffs-14*3-1;
  668.   OldMouseTyp   := true;
  669. end.