]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/xmouse.asm
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / xlib / xmouse.asm
1 ;-----------------------------------------------------------------------\r
2 ; MODULE XMOUSE\r
3 ;\r
4 ; Mouse functions functions for all MODE X 256 Color resolutions\r
5 ;\r
6 ; Compile with Tasm.\r
7 ; C callable.\r
8 ;\r
9 ; ****** XLIB - Mode X graphics library                ****************\r
10 ; ******                                               ****************\r
11 ; ****** Written By Themie Gouthas                     ****************\r
12 ;\r
13 ; This module is based on Shane Hyde's module of the same name,\r
14 ; posted to Rec.Games.Programmer, October 92.\r
15 ;\r
16 ;\r
17 ; egg@dstos3.dsto.gov.au\r
18 ; teg@bart.dsto.gov.au\r
19 ;\r
20 ; mouse cursor shape by Tiaan A Geldenhuys\r
21 ;\r
22 ;-----------------------------------------------------------------------\r
23 \r
24 COMMENT  $\r
25 \r
26 \r
27 This is a module implementing very basic mouse functions.\r
28 \r
29 It does not support the full functionality of:\r
30 \r
31   SPLIT SCREENS\r
32   SCROLLED WINDOWS\r
33   VIRTUAL WINDOWS\r
34 \r
35               --------------------------------------\r
36 \r
37               MS Mouse Driver Functions\r
38 \r
39               Mouse Initialization                 0\r
40               Show Cursor                          1\r
41               Hide Cursor                          2\r
42               Get Mouse Position & Button Status   3\r
43               Set Mouse Cursor Position            4\r
44               Get Button Press Information         5\r
45               Get Button Release Information       6\r
46               Set Min/Max Horizontal Position      7\r
47               Set Min/Max Vertical Position        8\r
48               Define Graphics Cursor Block         9\r
49               Define Text Cursor                  10\r
50               Read Mouse Motion Counters          11\r
51               Define Event Handler                12\r
52               Light Pen Emulation Mode ON         13\r
53               Light Pen Emulation Mode OFF        14\r
54               Set Mouse Mickey/Pixel Ratio        15\r
55               Conditional Hide Cursor             16\r
56               Set Double-Speed Threshold          19\r
57               --------------------------------------\r
58 $\r
59 \r
60 include xlib.inc\r
61 include xdetect.inc\r
62 \r
63 .data\r
64 \r
65 global   _MouseInstalled    :word\r
66 global   _MouseHidden       :word\r
67 global   _MouseButtonStatus :word\r
68 global   _MouseX            :word\r
69 global   _MouseY            :word\r
70 global   _MouseFrozen       :byte\r
71 global   _MouseColor        :byte\r
72 \r
73 global   _x_define_mouse_cursor :proc\r
74 global   _x_show_mouse          :proc\r
75 global   _x_hide_mouse          :proc\r
76 global   _x_mouse_remove        :proc\r
77 global   _x_position_mouse      :proc\r
78 global   _x_put_cursor          :proc\r
79 global   _x_update_mouse        :proc\r
80 global   _x_mouse_init          :proc\r
81 global   _x_mouse_window        :proc\r
82 \r
83 \r
84 ALIGN 2\r
85 \r
86 \r
87 \r
88       InitMouseDef db 00000001b  ; Default mouse mask, note the reverse order\r
89                 db 00000011b\r
90                 db 00000111b\r
91                 db 00001111b\r
92                 db 00011111b\r
93                 db 00111111b\r
94                 db 01111111b\r
95                 db 11111111b\r
96                 db 00011111b\r
97                 db 00011011b\r
98                 db 00110001b\r
99                 db 00110000b\r
100                 db 01100000b\r
101                 db 01100000b\r
102 \r
103 \r
104 \r
105 COMMENT $\r
106 \r
107    Old mouse definition\r
108 \r
109    InitMouseDef db 00000001b  ; Default mouse mask, note the reverse order\r
110                 db 00000011b\r
111                 db 00000111b\r
112                 db 00001111b\r
113                 db 00011111b\r
114                 db 00111111b\r
115                 db 01111111b\r
116                 db 11111111b\r
117                 db 00011100b\r
118                 db 00111100b\r
119                 db 01111100b\r
120                 db 00000000b\r
121                 db 00000000b\r
122                 db 00000000b\r
123 \r
124 $\r
125 \r
126     MouseMask          db 168 dup(?)\r
127     OldHandlerSeg      dw  ?\r
128     OldHandlerOffs     dw  ?\r
129     OldHandlerMask     dw  ?\r
130     OldX               dw  ?\r
131     OldY               dw  ?\r
132     OldScrnOffs        dw  ?\r
133 \r
134     BGSaveOffs         dw  0\r
135 \r
136    _MouseInstalled     dw 0     ; Flag indicating whether mouse is installed\r
137    _MouseHidden        dw 0     ; Flag indicating whether mouse is hidden\r
138    _MouseButtonStatus  dw 0     ; Holds current button press information\r
139    _MouseX             dw 0     ; Coords of cursor hot spot\r
140    _MouseY             dw 0\r
141    _MouseFrozen        db 0     ; Mouse motion enable/disable control\r
142    _MouseColor         db 0     ; Mouse cursor colour\r
143 \r
144    inhandler           db 0\r
145 .code\r
146 \r
147 ;----------------------------------------------------------------------\r
148 ; Local function that updates the cursor position\r
149 ;\r
150 ; Destroys SI,DI,AX,BX\r
151 ;\r
152 ;----------------------------------------------------------------------\r
153 proc update_cursor near\r
154    WaitVsyncStart\r
155 \r
156    mov di,[OldScrnOffs]             ; Delete cursor (restore old background)\r
157    mov ax,[OldY]\r
158    mov bx,[OldX]\r
159 \r
160    call restorebg\r
161 \r
162    mov si,[_VisiblePageOffs]        ; Save cursor background\r
163    mov ax,[_MouseY]\r
164    mov bx,[_MouseX]\r
165    mov [OldScrnOffs],si\r
166    mov [OldY],ax\r
167    mov [OldX],bx\r
168    call getbg\r
169 \r
170    push [_VisiblePageOffs]          ; Draw the cursor\r
171    mov  ax,[_ScrnPhysicalHeight]\r
172    push ax\r
173    mov  ax,0\r
174    push ax\r
175    push [OldY]\r
176    push [OldX]\r
177    call _x_put_cursor\r
178    add  sp,10\r
179    ret\r
180 update_cursor endp\r
181 \r
182 \r
183 ;----------------------------------------------------------------------\r
184 ; x_mouse_init - Initialise Mode X mouse handler\r
185 ;\r
186 ; C Prototype\r
187 ;\r
188 ;  int x_mouse_init()\r
189 ;\r
190 ; This is the first function you must call before using any of the mouse\r
191 ; functions\r
192 ;\r
193 ; WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
194 ;          video ram for the saved mouse background.\r
195 ;\r
196 ; This mouse code uses the fastest possible techniques to save and restore\r
197 ; mouse backgrounds and to draw the mouse cursor.\r
198 ;\r
199 ; LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
200 ;              No validity checking is performed for NonVisual_Offs\r
201 ;\r
202 ;\r
203 ; **WARNING** Hide or freeze mouse while drawing using any of the other\r
204 ;             Modules. VGA register settings are not preserved which will\r
205 ;             result in unpredictable drawing behavior.\r
206 ;             If you know the drawing will occur away from the mouse cursor\r
207 ;             set MouseFrozen to TRUE (1), do your drawing then set it to\r
208 ;             FALSE (0). Alternatively call "x_hide_mouse", perform your\r
209 ;             drawing and then call "x_show_mouse"\r
210 ;\r
211 ;\r
212 ; Written by Themie Gouthas\r
213 ;----------------------------------------------------------------------\r
214 _x_mouse_init proc\r
215      push  bp\r
216      mov   bp,sp\r
217 \r
218      cmp   [_MouseButtonCount],0  ; Dont initialize if mouse detection\r
219      jne   @@DontInitialize       ; or initialization function previously\r
220                                   ;   called\r
221      xor   ax,ax                  ; FUNC 0: Mouse Initialization\r
222      int   33h                    ;\r
223      or    ax,ax                  ; Is there a mouse installed ?\r
224      jz    @@Done\r
225      mov   [_MouseButtonCount],bx ; Set the button count\r
226 \r
227 @@DontInitialize:\r
228 \r
229      mov   [_MouseInstalled],ax\r
230      or    ax,ax                  ; Do we have an installed mouse driver ?\r
231      jz    @@Done                 ; Nop!\r
232 \r
233      mov   ax,[_NonVisual_Offs];  ; Allocate VRAM for saved background\r
234      mov   BGSaveOffs,ax\r
235 \r
236      add   ax,14*3\r
237      mov   [_NonVisual_Offs],ax   ; Update NonVisualOffset\r
238 \r
239      mov   ax,02                  ; FUNC 2: Hide Cursor\r
240      int   33h                    ;  (hide the mouse driver's default cursor)\r
241      mov   _MouseInstalled,TRUE   ; Indicate user mouse driver present\r
242 \r
243      mov   ax,07h                 ; FUNC 7:Set min/max horizontal position\r
244      mov   cx,0\r
245      mov   dx,[_ScrnPhysicalPixelWidth]\r
246      shl   dx,1                   ; Mult X by 2 as cursor steps by 2 pixels\r
247      int   33h                    ; 0 < X < _ScrnPhysicalPixelWidth\r
248 \r
249      mov   ax,08h                 ; FUNC 8:Set min/max vertical position\r
250      mov   cx,0\r
251      mov   dx,_ScrnPhysicalHeight\r
252      int   33h                    ; 0 < Y < _ScrnPhysicalHeight\r
253 \r
254      mov   ax,0fh                 ; FUNC 15: Mouse Hor/Vert resolution\r
255      mov   cx,4                   ; Horiz speed  >> Value => << Speed\r
256      mov   dx,8                   ; Vert Speed\r
257      int   33h\r
258 \r
259      mov   ax,3                   ; FUNC 3: Get mouse pos & button status\r
260      int   33h\r
261      mov   [_MouseY],dx\r
262      shr   cx,1\r
263      mov   [_MouseX],cx\r
264 \r
265      mov   ax,12                  ; FUNC 12: Define Event Handler\r
266      mov   bx,seg mouse_handler   ;  ES:DX -> Event handler\r
267      mov   es,bx\r
268      mov   dx,offset mouse_handler\r
269      mov   cx,1fh                 ;  Set handler for all events\r
270      int   33h\r
271 \r
272 \r
273 \r
274      mov   [_MouseHidden],TRUE    ; Mouse initially hidden\r
275 \r
276      push  ds                     ; Set the default cursor shape\r
277      mov   ax,offset InitMouseDef\r
278      push  ax\r
279      call  _x_define_mouse_cursor\r
280      add   sp,04h\r
281 \r
282      mov   ax,[_MouseInstalled]   ; Return MouseInstalled flag\r
283 @@Done:\r
284      pop   bp\r
285      ret\r
286 _x_mouse_init endp\r
287 \r
288 ;----------------------------------------------------------------------\r
289 ; x_mouse_window - Define a mouse window\r
290 ;\r
291 ; C Prototype\r
292 ;\r
293 ;  void x_mouse_window(int x0, int y0, int x1, int y1);\r
294 ;\r
295 ;\r
296 ; Written by Themie Gouthas\r
297 ;----------------------------------------------------------------------\r
298 _x_mouse_window proc\r
299 ARG x0:word,y0:word,x1:word,y1:word\r
300      push  bp\r
301      mov   bp,sp\r
302 \r
303      mov   ax,7       ; FUNC 7: Set X range\r
304      mov   cx,x0\r
305      shl   cx,1\r
306      mov   dx,x1\r
307      shl   dx,1\r
308      int   33h\r
309 \r
310      mov   ax,8       ; FUNC 8: Set Y range\r
311      mov   cx,y0\r
312      mov   dx,y1\r
313      int   33h\r
314      pop   bp\r
315      ret\r
316 _x_mouse_window endp\r
317 \r
318 \r
319 ;----------------------------------------------------------------------\r
320 ; x_define_mouse_cursor - Define a mouse cursor from an input bitmask\r
321 ;\r
322 ; C Prototype\r
323 ;\r
324 ;  void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
325 ;\r
326 ; WARNING: This function assumes MouseDef points to 14 bytes.\r
327 ;\r
328 ; Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
329 ;       bit 0 represents pixel 7 in each "MouseDef" byte.\r
330 ;\r
331 ; Written by Themie Gouthas\r
332 ;----------------------------------------------------------------------\r
333 _x_define_mouse_cursor proc\r
334 ARG MouseDef:dword,MouseColor:byte\r
335      push  bp\r
336      mov   bp,sp\r
337 \r
338      cmp  [_MouseInstalled],FALSE   ; Check whether we have installed\r
339      je   @@Done                    ;  our mouse handler and leave if not\r
340 \r
341      mov  al,[MouseColor]           ; Set the mouse pointers color\r
342      mov  [_MouseColor],al\r
343 \r
344      push  si\r
345      push  di\r
346      push  ds\r
347      mov   ax,ds                ; ES:DI -> Stored plane mask for all\r
348      mov   es,ax                ;   pixel alignments of mouse cursor\r
349      mov   di,offset MouseMask\r
350      lds   si,MouseDef\r
351      xor   cl,cl                ; CL = current alignment (initially zero)\r
352 @@AlignmentLoop:\r
353      push  si                   ; save MouseDef ptr for next alignment\r
354      mov   dh,14                ; Init Row counter to Cursor Height\r
355 @@RowLoop:\r
356      lodsb                      ; Load first cursor def byte each bit\r
357                                 ;  representing pixel in the row\r
358      xor   ah,ah                ; AH is the shift overflow byte\r
359      shl   ax,cl                ; Shift mask for current alignment\r
360 \r
361      mov   bl,al                ; store first three nibbles of ax into\r
362      and   bl,0fh               ;  consecutive bytes in the destination\r
363      mov   es:[di],bl           ;  buffer\r
364      inc   di\r
365      shr   al,4\r
366      stosw\r
367 \r
368      dec   dh                   ; Next row for this alignment if there\r
369      jnz   @@RowLoop            ;  are more to do\r
370 \r
371      pop   si                   ; point to the start of the cursor def.\r
372      inc   cl                   ; Select next pixel alignment\r
373      cmp   cl,4                 ; If there are more alignments to do\r
374      jne   @@AlignmentLoop      ;   then jump\r
375 \r
376      pop   ds\r
377      pop   di\r
378      pop   si\r
379 @@Done:\r
380      pop   bp\r
381      ret\r
382 _x_define_mouse_cursor endp\r
383 \r
384 \r
385 ;----------------------------------------------------------------------\r
386 ; x_show_mouse - Shows a previously hidden mouse cursor\r
387 ;\r
388 ; C Prototype\r
389 ;\r
390 ;  void x_show_mouse()\r
391 ;\r
392 ; Written by Themie Gouthas\r
393 ;----------------------------------------------------------------------\r
394 _x_show_mouse proc\r
395      push  bp\r
396      mov   bp,sp\r
397      cmp   [_MouseInstalled],FALSE  ; Make sure our handler is installed\r
398      je    @@Done\r
399      cmp   [_MouseHidden],FALSE     ; If not hidden then exit\r
400      je    @@Done\r
401      push  si\r
402      push  di\r
403 \r
404 \r
405 @@WaitEndOfHandler:               ; Make sure handler not currently active\r
406      mov   cl,[inhandler]\r
407      or    cl,cl\r
408      jnz   @@WaitEndOfHandler\r
409 \r
410 \r
411      mov   si,[_VisiblePageOffs]  ; Save mouse background and pos details\r
412      mov   ax,[_MouseY]\r
413      mov   bx,[_MouseX]\r
414      mov   [OldScrnOffs],si\r
415      mov   [OldY],ax\r
416      mov   [OldX],bx\r
417      call  getbg\r
418 \r
419      push [_VisiblePageOffs]      ; Draw cursor\r
420      push [_ScrnLogicalHeight]\r
421      xor  ax,ax\r
422      push ax\r
423      push [OldY]\r
424      push [OldX]\r
425      call _x_put_cursor\r
426      add  sp,10\r
427 \r
428      mov   [_MouseHidden],FALSE   ; Indicate mouse cursor no longer hidden\r
429 \r
430      pop  di\r
431      pop  si\r
432 @@Done:\r
433      pop   bp\r
434      ret\r
435 _x_show_mouse endp\r
436 \r
437 \r
438 ;----------------------------------------------------------------------\r
439 ; x_hide_mouse - Hides a previously visible mouse cursor\r
440 ;\r
441 ; C Prototype\r
442 ;\r
443 ;  void x_hide_mouse()\r
444 ;\r
445 ; Written by Themie Gouthas\r
446 ;----------------------------------------------------------------------\r
447 _x_hide_mouse proc\r
448      push  bp\r
449      mov   bp,sp\r
450 \r
451      cmp   [_MouseInstalled],FALSE   ; Make sure our handler is installed\r
452      je    @@Done\r
453      cmp   [_MouseHidden],FALSE      ; If cursor is already hidden exit\r
454      jne   @@Done\r
455      push  si\r
456      push  di\r
457 \r
458 @@WaitEndOfHandler:            ; Make sure handler not currently active\r
459      mov   cl,[inhandler]\r
460      or    cl,cl\r
461      jnz   @@WaitEndOfHandler\r
462 \r
463      mov   [_MouseHidden],TRUE       ; Delete mouse cursor\r
464      mov   di,[OldScrnOffs]\r
465      mov   ax,[OldY]\r
466      mov   bx,[OldX]\r
467      call  restorebg\r
468      pop   di\r
469      pop   si\r
470 @@Done:\r
471      pop   bp\r
472      ret\r
473 _x_hide_mouse endp\r
474 \r
475 \r
476 ;----------------------------------------------------------------------\r
477 ; x_remove_mouse - removes mouse handler\r
478 ;\r
479 ; C Prototype\r
480 ;\r
481 ;  void x_remove_mouse()\r
482 ;\r
483 ; NOTE: This function MUST be called before quitting the program if\r
484 ;       a mouse handler has been installed\r
485 ;\r
486 ; Written by Themie Gouthas\r
487 ;----------------------------------------------------------------------\r
488 _x_mouse_remove proc\r
489     push  bp\r
490     mov   bp,sp\r
491     cmp   [_MouseInstalled],FALSE  ; Check whether we have installed\r
492     je    @@Done                   ;  our mouse handler\r
493     call  _x_hide_mouse\r
494     mov   ax,12                    ; FUNC 12: Install event handler\r
495     xor   cx,cx                    ; Disable all events\r
496     int   33h\r
497     mov   [_MouseInstalled],FALSE\r
498 @@Done:\r
499     pop   bp\r
500     ret\r
501 _x_mouse_remove endp\r
502 \r
503 \r
504 ;----------------------------------------------------------------------\r
505 ; x_position_mouse - Positions the mouse cursor at the specified location\r
506 ;\r
507 ; C Prototype\r
508 ;\r
509 ;  void x_position_mouse(int x, int y)\r
510 ;\r
511 ;\r
512 ; Written by Themie Gouthas\r
513 ;----------------------------------------------------------------------\r
514 _x_position_mouse proc\r
515 ARG  X:word,Y:word\r
516      push  bp\r
517      mov   bp,sp\r
518 \r
519 @@WaitEndOfHandler:               ; Make sure handler not currently active\r
520      mov   bl,[inhandler]\r
521 \r
522      or    bl,bl\r
523      jnz   @@WaitEndOfHandler\r
524 \r
525      mov   ax,4\r
526      mov   cx,X\r
527      mov   dx,Y\r
528      mov   [_MouseX],cx\r
529      mov   [_MouseY],dx\r
530      shl   cx,1\r
531 \r
532      mov   [inhandler],1\r
533      int   33h\r
534 \r
535      ; The handler doesnt get called so need\r
536      ; to update manually;\r
537 \r
538      cmp   [_MouseHidden],FALSE\r
539      jne   @@NotVisible\r
540      push  di si\r
541      call  update_cursor\r
542      pop   si di\r
543 \r
544 @@NotVisible:\r
545      mov   [inhandler],0\r
546      pop   bp\r
547      ret\r
548 _x_position_mouse endp\r
549 \r
550 ;----------------------------------------------------------------------\r
551 ; x_update_mouse - Forces the mouse position to be updated and cursor\r
552 ;                  to be redrawn.\r
553 ;\r
554 ; C Prototype\r
555 ;\r
556 ;  void x_update_mouse()\r
557 ;\r
558 ; Note this function is useful when you have set "MouseFrozen" to true.\r
559 ; Allows the cursor position to be updated manually rather than\r
560 ; automatically by the installed handler.\r
561 ;\r
562 ;\r
563 ; Written by Themie Gouthas\r
564 ;----------------------------------------------------------------------\r
565 _x_update_mouse proc\r
566      push  bp\r
567      mov   bp,sp\r
568      cmp   [_MouseInstalled],FALSE   ; Make sure our handler is installed\r
569      je    @@Done\r
570      cmp   [_MouseHidden],FALSE      ; If cursor is already hidden exit\r
571      jne   @@Done\r
572      push  si\r
573      push  di\r
574      mov   ax,03h                 ; FUNC 3: get cursor pos / button status\r
575      int   33h                    ; Update position variables first\r
576      shr   cx,1\r
577      mov   [_MouseX],cx\r
578      mov   [_MouseY],dx\r
579      mov   [_MouseButtonStatus],bx    ; Update button status\r
580      call  update_cursor\r
581      pop   di\r
582      pop   si\r
583 @@Done:\r
584      pop   bp\r
585      ret\r
586 _x_update_mouse endp\r
587 \r
588 \r
589 ;----------------------------------------------------------------------\r
590 ; x_put_cursor - Draws the mouse cursor\r
591 ;\r
592 ; C Prototype\r
593 ;\r
594 ; void x_put_cursor(int X, int Y, int TopClip, int BottomClip, WORD ScrnOffs)\r
595 ;\r
596 ;\r
597 ; Written by Themie Gouthas\r
598 ;----------------------------------------------------------------------\r
599 ALIGN 2\r
600 _x_put_cursor  proc\r
601 ARG X:word,Y:word,TopClip,BottomClip,ScrnOffs\r
602 LOCAL Height,TopRow,NextLineIncr:word=LocalStk\r
603         push  bp\r
604         mov   bp,sp\r
605         sub   sp,LocalStk                 ; Create space for local variables\r
606         push  si\r
607         push  di\r
608         push  ds\r
609         mov   ax,@data\r
610         mov   ds,ax\r
611         cld\r
612 \r
613         mov   ax,14                   ; Get image height and save in AX\r
614         mov   bx,Y\r
615         ; cx = top Row\r
616 \r
617         ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
618 \r
619         mov   dx,[TopClip]            ; Compare u.l. Y coord with Top\r
620         sub   dx,bx                   ; clipping border\r
621         jle   @@NotTopClip            ; jump if  not clipped from above\r
622         cmp   dx,ax\r
623         jnl   @@NotVisible            ; jump if  is completely obscured\r
624         mov   cx,dx\r
625         sub   ax,dx\r
626         add   bx,dx\r
627         jmp   short @@VertClipDone\r
628 \r
629         ;;;; EXIT FOR COMPLETELY OBSCURED  ;;;;;;;;;;;;;;;;;;;;;;\r
630 \r
631 @@NotVisible:\r
632         pop   ds\r
633         pop   di                          ; restore registers\r
634         pop   si\r
635         mov   sp,bp                       ; dealloc local variables\r
636         pop   bp\r
637         ret\r
638 \r
639         ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
640 \r
641 @@NotTopClip:\r
642         mov   dx,[BottomClip]\r
643         sub   dx,bx\r
644         js    @@NotVisible\r
645         mov   cx,0\r
646         cmp   dx,ax\r
647         jg    @@VertClipDone\r
648         inc   dx\r
649         mov   ax,dx\r
650 \r
651 @@VertClipDone:\r
652 \r
653         mov   [Height],ax\r
654         mov   [TopRow],cx\r
655 \r
656         mov   ax,SCREEN_SEG               ; Point es to VGA segment\r
657         mov   es,ax\r
658 \r
659         mov   ax,bx\r
660         mov   cx,[_ScrnLogicalByteWidth]  ; Find required screen address\r
661         mul   cx\r
662         mov   di,ax\r
663 \r
664         sub   cx,3                        ; Distance to next screen row\r
665         mov   [NextLineIncr],cx\r
666 \r
667 \r
668         mov   cx,[X]\r
669         mov   bx,cx\r
670         shr   cx,2\r
671         add   di,cx\r
672         and   bx,3\r
673         add   di,[ScrnOffs]\r
674 \r
675         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
676 \r
677 \r
678         mov   ax,42\r
679         mul   bx\r
680         mov   si,offset MouseMask\r
681         add   si,ax\r
682 \r
683         mov   ax,3                        ; Increment DS:BX and DS:SI to\r
684         mul   [TopRow]                    ;  been clipped by the top border\r
685         add   si,ax                       ; by the L.H.S border\r
686 \r
687         mov   dx,SC_INDEX                 ; Point SC register to map mask\r
688         mov   al,MAP_MASK                 ; in preperation for masking data\r
689         out   dx,al\r
690         inc   dx                          ; Point dx to SC data register\r
691         mov   ah,byte ptr [Height]        ; AH = Scanline loop counter\r
692         mov   bl,[_MouseColor]\r
693 @@RowLoop:\r
694         mov   cx,3                        ; Width in bytes across\r
695 @@ColLoop:\r
696         lodsb                             ; load plane mask and set MAP MASK\r
697         out   dx,al\r
698         mov   es:[di],bl                  ; store color to specified planes\r
699         inc   di\r
700         loop  @@ColLoop\r
701 \r
702         add   di,[NextLineIncr]\r
703         dec   ah\r
704         jnz   @@RowLoop\r
705 \r
706         pop   ds\r
707         pop   di                          ; restore registers\r
708         pop   si\r
709         mov   sp,bp                       ; dealloc local variables\r
710         pop   bp\r
711         ret\r
712 _x_put_cursor  endp\r
713 \r
714 \r
715 ;----------------------------------------------------------------------\r
716 ; getbg - saves cursor background\r
717 ;\r
718 ; C Prototype\r
719 ;\r
720 ; local function using register parameters\r
721 ;\r
722 ; si = screen offset\r
723 ; ax  = y\r
724 ; bx  = x\r
725 ;\r
726 ; Written by Themie Gouthas\r
727 ;----------------------------------------------------------------------\r
728 ALIGN 2\r
729 getbg  proc near\r
730 \r
731         push  bp\r
732         mov   bp,sp\r
733         push  ds\r
734         cld\r
735 \r
736         mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen\r
737         mul   cx                          ;  width then adding screen offset\r
738         add   si,ax                       ; Add Dest Screen Row to di\r
739         sub   cx,3\r
740         shr   bx,2\r
741         add   si,bx\r
742         mov   bx,cx\r
743 \r
744         mov   di,BGSaveOffs\r
745         mov   ax,SCREEN_SEG               ; Point es to VGA segment\r
746         mov   es,ax\r
747         mov   ds,ax\r
748 \r
749         mov   dx,GC_INDEX                 ; Set bit mask for all bits from\r
750         mov   ax,BIT_MASK                 ; VGA latches and none from CPU\r
751         out   dx,ax\r
752 \r
753         mov   dx,SC_INDEX                 ; Point SC register to map mask\r
754         mov   al,MAP_MASK           ; in preperation for masking data\r
755         out   dx,al\r
756         inc   dx\r
757         mov   al,0fh\r
758         out   dx,al\r
759 \r
760         mov   cx,14\r
761 @@Loop:\r
762         movsb\r
763         movsb\r
764         movsb\r
765         add si,bx\r
766         loop @@Loop\r
767 \r
768 mov     dx,GC_INDEX+1 ;restore the bit mask to its default,\r
769         mov     al,0ffh       ; which selects all bits from the CPU\r
770         out     dx,al         ; and none from the latches (the GC\r
771                               ; Index still points to Bit Mask)\r
772 \r
773         pop   ds\r
774         mov   sp,bp                       ; dealloc local variables\r
775         pop   bp\r
776         ret\r
777 getbg  endp\r
778 \r
779 ;----------------------------------------------------------------------\r
780 ; restorebg - restores cursor background\r
781 ;\r
782 ; C Prototype\r
783 ;\r
784 ; local function using register parameters\r
785 ;\r
786 ; di = screen offset\r
787 ; ax  = y\r
788 ; bx  = x\r
789 ;\r
790 ; Written by Themie Gouthas\r
791 ;----------------------------------------------------------------------\r
792 ALIGN 2\r
793 restorebg  proc near\r
794 ;di = scrn offs\r
795 ;ax  = y\r
796 ;bx  = x\r
797         push  bp\r
798         mov   bp,sp\r
799         push  ds\r
800         cld\r
801 \r
802         mov   cx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen\r
803         mul   cx                          ;  width then adding screen offset\r
804         add   di,ax                       ; Add Dest Screen Row to di\r
805         sub   cx,3\r
806         shr   bx,2\r
807         add   di,bx\r
808         mov   si,BGSaveOffs\r
809         mov   ax,SCREEN_SEG               ; Point es to VGA segment\r
810         mov   es,ax\r
811         mov   ds,ax\r
812 \r
813         mov   dx,GC_INDEX                 ; Set bit mask for all bits from\r
814         mov   ax,BIT_MASK                 ; VGA latches and none from CPU\r
815         out   dx,ax\r
816 \r
817         mov   dx,SC_INDEX                 ; Point SC register to map mask\r
818         mov   al,MAP_MASK                 ; in preperation for masking data\r
819         out   dx,al\r
820         inc   dx\r
821         mov   al,0fh\r
822         out   dx,al\r
823 \r
824         mov   bx,cx\r
825         mov   cx,14\r
826 @@Loop:\r
827         movsb\r
828         movsb\r
829         movsb\r
830         add di,bx\r
831         loop @@Loop\r
832         mov  dx,GC_INDEX+1 ;restore the bit mask to its default,\r
833         mov  al,0ffh       ; which selects all bits from the CPU\r
834         out  dx,al         ; and none from the latches (the GC\r
835                            ; Index still points to Bit Mask)\r
836         pop   ds\r
837         pop   bp\r
838         ret\r
839 restorebg  endp\r
840 \r
841 \r
842 \r
843 ;********************** The Mouse event handler *************************\r
844 \r
845 ALIGN 2\r
846 mouse_handler proc far\r
847    push  bp\r
848    mov   bp,sp\r
849    push  ds\r
850 \r
851    mov   di,@data                   ; Make sure DS points to data segment\r
852    mov   ds,di\r
853    cmp   [inhandler],1\r
854    jne   @@NotActive\r
855    pop   ds\r
856    pop   bp\r
857    ret\r
858 \r
859 @@NotActive:\r
860    mov   [inhandler],1\r
861    mov   [_MouseButtonStatus],bx    ; Update button status\r
862    test  ax,1                       ; Is this a motion event ?\r
863    jz    @@Done                     ; No Jump\r
864 \r
865    shr  cx,1                        ; convert X coord to pixel coords\r
866    mov  [_MouseX],cx                ; save mouse position\r
867    mov  [_MouseY],dx\r
868 \r
869    cmp  [_MouseHidden],TRUE         ; If mouse hidden dont bother drawing\r
870    je   @@Done\r
871 \r
872    cmp  [_MouseFrozen],TRUE         ; If mouse hidden dont bother drawing\r
873    je   @@Done\r
874 \r
875    call update_cursor\r
876 @@Done:\r
877    mov  [inhandler],0\r
878    pop  ds\r
879    pop  bp\r
880    ret\r
881 mouse_handler endp\r
882 \r
883 \r
884 end\r