📄 xmouse.asm
字号:
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_hide_mouse proc
push bp
mov bp,sp
cmp [_MouseInstalled],FALSE ; Make sure our handler is installed
je @@Done
cmp [_MouseHidden],FALSE ; If cursor is already hidden exit
jne @@Done
push si
push di
@@WaitEndOfHandler: ; Make sure handler not currently active
mov cl,[inhandler]
or cl,cl
jnz @@WaitEndOfHandler
mov [_MouseHidden],TRUE ; Delete mouse cursor
mov di,[OldScrnOffs]
mov ax,[OldY]
mov bx,[OldX]
call restorebg
pop di
pop si
@@Done:
pop bp
ret
_x_hide_mouse endp
;----------------------------------------------------------------------
; x_remove_mouse - removes mouse handler
;
; C Prototype
;
; void x_remove_mouse()
;
; NOTE: This function MUST be called before quitting the program if
; a mouse handler has been installed
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_mouse_remove proc
push bp
mov bp,sp
cmp [_MouseInstalled],FALSE ; Check whether we have installed
je @@Done ; our mouse handler
call _x_hide_mouse
mov ax,12 ; FUNC 12: Install event handler
xor cx,cx ; Disable all events
int 33h
mov [_MouseInstalled],FALSE
@@Done:
pop bp
ret
_x_mouse_remove endp
;----------------------------------------------------------------------
; x_position_mouse - Positions the mouse cursor at the specified location
;
; C Prototype
;
; void x_position_mouse(int x, int y)
;
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_position_mouse proc
ARG X:word,Y:word
push bp
mov bp,sp
@@WaitEndOfHandler: ; Make sure handler not currently active
mov bl,[inhandler]
or bl,bl
jnz @@WaitEndOfHandler
mov ax,4
mov cx,X
mov dx,Y
mov [_MouseX],cx
mov [_MouseY],dx
shl cx,1
mov [inhandler],1
int 33h
; The handler doesnt get called so need
; to update manually;
cmp [_MouseHidden],FALSE
jne @@NotVisible
push di si
call update_cursor
pop si di
@@NotVisible:
mov [inhandler],0
pop bp
ret
_x_position_mouse endp
;----------------------------------------------------------------------
; x_update_mouse - Forces the mouse position to be updated and cursor
; to be redrawn.
;
; C Prototype
;
; void x_update_mouse()
;
; Note this function is useful when you have set "MouseFrozen" to true.
; Allows the cursor position to be updated manually rather than
; automatically by the installed handler.
;
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_update_mouse proc
push bp
mov bp,sp
cmp [_MouseInstalled],FALSE ; Make sure our handler is installed
je @@Done
cmp [_MouseHidden],FALSE ; If cursor is already hidden exit
jne @@Done
push si
push di
mov ax,03h ; FUNC 3: get cursor pos / button status
int 33h ; Update position variables first
shr cx,1
mov [_MouseX],cx
mov [_MouseY],dx
mov [_MouseButtonStatus],bx ; Update button status
call update_cursor
pop di
pop si
@@Done:
pop bp
ret
_x_update_mouse endp
;----------------------------------------------------------------------
; x_put_cursor - Draws the mouse cursor
;
; C Prototype
;
; void x_put_cursor(int X, int Y, int TopClip, int BottomClip, WORD ScrnOffs)
;
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
ALIGN 2
_x_put_cursor proc
ARG X:word,Y:word,TopClip,BottomClip,ScrnOffs
LOCAL Height,TopRow,NextLineIncr:word=LocalStk
push bp
mov bp,sp
sub sp,LocalStk ; Create space for local variables
push si
push di
push ds
mov ax,@data
mov ds,ax
cld
mov ax,14 ; Get image height and save in AX
mov bx,Y
; cx = top Row
;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
mov dx,[TopClip] ; Compare u.l. Y coord with Top
sub dx,bx ; clipping border
jle @@NotTopClip ; jump if not clipped from above
cmp dx,ax
jnl @@NotVisible ; jump if is completely obscured
mov cx,dx
sub ax,dx
add bx,dx
jmp short @@VertClipDone
;;;; EXIT FOR COMPLETELY OBSCURED ;;;;;;;;;;;;;;;;;;;;;;
@@NotVisible:
pop ds
pop di ; restore registers
pop si
mov sp,bp ; dealloc local variables
pop bp
ret
;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
@@NotTopClip:
mov dx,[BottomClip]
sub dx,bx
js @@NotVisible
mov cx,0
cmp dx,ax
jg @@VertClipDone
inc dx
mov ax,dx
@@VertClipDone:
mov [Height],ax
mov [TopRow],cx
mov ax,SCREEN_SEG ; Point es to VGA segment
mov es,ax
mov ax,bx
mov cx,[_ScrnLogicalByteWidth] ; Find required screen address
mul cx
mov di,ax
sub cx,3 ; Distance to next screen row
mov [NextLineIncr],cx
mov cx,[X]
mov bx,cx
shr cx,2
add di,cx
and bx,3
add di,[ScrnOffs]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,42
mul bx
mov si,offset MouseMask
add si,ax
mov ax,3 ; Increment DS:BX and DS:SI to
mul [TopRow] ; been clipped by the top border
add si,ax ; by the L.H.S border
mov dx,SC_INDEX ; Point SC register to map mask
mov al,MAP_MASK ; in preperation for masking data
out dx,al
inc dx ; Point dx to SC data register
mov ah,byte ptr [Height] ; AH = Scanline loop counter
mov bl,[_MouseColor]
@@RowLoop:
mov cx,3 ; Width in bytes across
@@ColLoop:
lodsb ; load plane mask and set MAP MASK
out dx,al
mov es:[di],bl ; store color to specified planes
inc di
loop @@ColLoop
add di,[NextLineIncr]
dec ah
jnz @@RowLoop
pop ds
pop di ; restore registers
pop si
mov sp,bp ; dealloc local variables
pop bp
ret
_x_put_cursor endp
;----------------------------------------------------------------------
; getbg - saves cursor background
;
; C Prototype
;
; local function using register parameters
;
; si = screen offset
; ax = y
; bx = x
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
ALIGN 2
getbg proc near
push bp
mov bp,sp
push ds
cld
mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen
mul cx ; width then adding screen offset
add si,ax ; Add Dest Screen Row to di
sub cx,3
shr bx,2
add si,bx
mov bx,cx
mov di,BGSaveOffs
mov ax,SCREEN_SEG ; Point es to VGA segment
mov es,ax
mov ds,ax
mov dx,GC_INDEX ; Set bit mask for all bits from
mov ax,BIT_MASK ; VGA latches and none from CPU
out dx,ax
mov dx,SC_INDEX ; Point SC register to map mask
mov al,MAP_MASK ; in preperation for masking data
out dx,al
inc dx
mov al,0fh
out dx,al
mov cx,14
@@Loop:
movsb
movsb
movsb
add si,bx
loop @@Loop
mov dx,GC_INDEX+1 ;restore the bit mask to its default,
mov al,0ffh ; which selects all bits from the CPU
out dx,al ; and none from the latches (the GC
; Index still points to Bit Mask)
pop ds
mov sp,bp ; dealloc local variables
pop bp
ret
getbg endp
;----------------------------------------------------------------------
; restorebg - restores cursor background
;
; C Prototype
;
; local function using register parameters
;
; di = screen offset
; ax = y
; bx = x
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
ALIGN 2
restorebg proc near
;di = scrn offs
;ax = y
;bx = x
push bp
mov bp,sp
push ds
cld
mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen
mul cx ; width then adding screen offset
add di,ax ; Add Dest Screen Row to di
sub cx,3
shr bx,2
add di,bx
mov si,BGSaveOffs
mov ax,SCREEN_SEG ; Point es to VGA segment
mov es,ax
mov ds,ax
mov dx,GC_INDEX ; Set bit mask for all bits from
mov ax,BIT_MASK ; VGA latches and none from CPU
out dx,ax
mov dx,SC_INDEX ; Point SC register to map mask
mov al,MAP_MASK ; in preperation for masking data
out dx,al
inc dx
mov al,0fh
out dx,al
mov bx,cx
mov cx,14
@@Loop:
movsb
movsb
movsb
add di,bx
loop @@Loop
mov dx,GC_INDEX+1 ;restore the bit mask to its default,
mov al,0ffh ; which selects all bits from the CPU
out dx,al ; and none from the latches (the GC
; Index still points to Bit Mask)
pop ds
pop bp
ret
restorebg endp
;********************** The Mouse event handler *************************
ALIGN 2
mouse_handler proc far
push bp
mov bp,sp
push ds
mov di,@data ; Make sure DS points to data segment
mov ds,di
cmp [inhandler],1
jne @@NotActive
pop ds
pop bp
ret
@@NotActive:
mov [inhandler],1
mov [_MouseButtonStatus],bx ; Update button status
test ax,1 ; Is this a motion event ?
jz @@Done ; No Jump
shr cx,1 ; convert X coord to pixel coords
mov [_MouseX],cx ; save mouse position
mov [_MouseY],dx
cmp [_MouseHidden],TRUE ; If mouse hidden dont bother drawing
je @@Done
cmp [_MouseFrozen],TRUE ; If mouse hidden dont bother drawing
je @@Done
call update_cursor
@@Done:
mov [inhandler],0
pop ds
pop bp
ret
mouse_handler endp
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -