TASM鼠标输入 [英] TASM mouse input
问题描述
我正在使用TASM,DosBox和Notepad ++进行装配项目.
我在屏幕上画了一个点,我需要知道用户是否单击了它(鼠标右键).
我尝试检查用户是否单击了鼠标右键,然后单击的坐标是否与点坐标相同.
由于某种原因,它无法正常工作.
这是我的程序:
I am working on an assembly project with TASM, DosBox and Notepad++.
I draw a dot on the screen and I need to know if the user clicked on it (right mouse).
I tried to check if the user clicked right mouse and then if the click coordinates are the same as the dot coordinates.
For some reason it's not working.
Here's my proc:
proc SetCursor
;initialize the mouse
mov ax, 0h
int 33h
;show mouse
mov ax, 1h
int 33h
; get mouse place and status
mov ax, 3h
int 33h
ret
endp SetCursor
在这里我叫它:
DotGame:
;enter graphics mode
mov ax, 13h
int 10h
call SetCursor ; mouse input
call DotOne
cmp bx, 01 ; check if left mouse was clicked
je Check_X_Cords
;check if the player clicked the dot cords
Check_X_Cords:
cmp cx, [XCords1]
je Check_Y_Cords
Check_Y_Cords:
cmp dx, [YCords1]
je ScoreLabel
ScoreLabel:
inc [score]
程序只是在标签之间跳转,所以坐标是否相同都没关系.
The program is just jumping between the labels, it doesn't matter if the coordinates are the same or not.
推荐答案
您的代码有一些问题:
-
proc SetCursor
不应初始化鼠标并同时获取位置. -
je Check_X_Cords
需要再次跳转,以防不相等.对于je Check_Y_Cords
也是一样
- 正如@MargaretBloom所说,
call DotOne
可能会破坏BX.
proc SetCursor
should not init the mouse and get the position at the same time.je Check_X_Cords
needs another jump in case it's not equal. The same forje Check_Y_Cords
- As @MargaretBloom said, it's possible that
call DotOne
destroys BX.
缺少很多代码,因此我必须添加它以对其进行测试:
There is a lot of code missing, so I had to add it in order to test it :
- 添加了变量x,y以保留鼠标位置.
- 显示坐标以检查我们单击的位置.
- 显示分数!"单击像素时.
这是代码,它可以运行并正确检测到在像素上的右键单击(忽略左键单击,但是您可以更改它),注释将帮助您理解它:>
Here is the code, it runs and properly detects the right click on the pixel (left click is ignored, but you can change it), the comments will help you to understand it :
.model small
.stack 100h
.data
XCords1 dw 160 ;COORDS OF PIXEL AT
YCords1 dw 100 ;SCREEN CENTER.
score dw 0
x dw ? ;MOUSE CLICK X.
y dw ? ;MOUSE CLICK Y.
msj db 'score!$'
hyphen db '-$'
clear db ' $' ;CLEAR LINE.
numstr db '$$$$$' ;STRING FOR 4 DIGITS.
.code
mov ax, @data
mov ds, ax
;DotGame:
;enter graphics mode
mov ax, 13h
int 10h
call SetCursor ; mouse input
call DotOne
DotGame:
mov bx, 1 ;CHECK RIGHT BUTTON (USE 0 TO CHECK LEFT BUTTON).
call GetMouseState
and bx, 00000010b ;CHECK SECOND BIT (BIT 1).
jz DotGame ;NO RIGHT CLICK. REPEAT.
mov x, cx ;PRESERVE X AND Y BECAUSE
mov y, dx ;CX DX WILL BE DESTROYED.
call display_coords
;cmp bx, 01 ; check if left mouse was clicked
;je Check_X_Cords
;check if the player clicked the dot cords
Check_X_Cords:
mov cx, x
cmp cx, XCords1
je Check_Y_Cords
jmp DotGame ;WRONG COLUMN. REPEAT.
Check_Y_Cords:
mov dx, y
cmp dx, YCords1
je ScoreLabel
jmp DotGame ;WRONG ROW. REPEAT.
ScoreLabel:
inc [score]
;DISPLAY "SCORE!".
mov ah, 9
mov dx, offset msj
int 21h
jmp DotGame ;REPEAT.
mov ax, 4c00h
int 21h
;---------------------------------------
proc SetCursor
;initialize the mouse
mov ax, 0h
int 33h
;show mouse
mov ax, 1h
int 33h
; get mouse place and status
;mov ax, 3h
;int 33h
ret
endp SetCursor
;---------------------------------------
;DRAW ONE PIXEL AT XCORDS1,YCORDS1.
proc DotOne
mov ah, 0ch ;SERVICE TO DRAW PIXEL.
mov al, 14 ;YELLOW.
mov bh, 0 ;VIDEO PAGE.
mov cx, XCords1
mov dx, YCords1
int 10h ;BIOS SCREEN SERVICES.
ret
endp DotOne
;---------------------------------------
;GET MOUSE CURSOR STATE.
;RETURN : BX : BIT 0 = 0 : LEFT BUTTON PRESSED.
; = 1 : LEFT BUTTON RELEASED.
; : BIT 1 = 0 : RIGHT BUTTON PRESSED.
; = 1 : RIGHT BUTTON RELEASED.
; CX = SCREEN COLUMN.
; DX = SCREEN ROW.
proc GetMouseState
mov ax, 3 ;SERVICE TO GET MOUSE STATE.
int 33h
ret
endp GetMouseState
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
; SI = POINTING WHERE TO STORE STRING.
;DESTROYED : AX, BX, CX, DX, SI.
number2string proc
call dollars ;FILL STRING WITH $.
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
;------------------------------------------
;FILLS VARIABLE "NUMSTR" WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.
;DESTROYED : BL, CX, DI.
proc dollars
mov cx, 5
mov di, offset numstr
dollars_loop:
mov bl, '$'
mov [ di ], bl
inc di
loop dollars_loop
ret
endp
;------------------------------------------
proc display_coords
;SEND CURSOR TO START OF UPPER LEFT.
mov ah, 2 ;SERVICE TO SET CURSOR POSITION.
mov bh, 0 ;VIDE PAGE.
mov dl, 0 ;X.
mov dh, 0 ;Y.
int 10h
;CLEAR LINE.
mov ah, 9
mov dx, offset clear
int 21h
;SEND CURSOR TO START OF UPPER LEFT.
mov ah, 2 ;SERVICE TO SET CURSOR POSITION.
mov bh, 0 ;VIDE PAGE.
mov dl, 0 ;X.
mov dh, 0 ;Y.
int 10h
;CONVERT X TO STRING.
mov ax, x ;AX = PARAMETER FOR NUMBER2STRING.
mov si, offset numstr
call number2string
;DISPLAY X.
mov ah, 9
mov dx, offset numstr
int 21h
;"-".
mov ah, 9
mov dx, offset hyphen
int 21h
;CONVERT Y TO STRING.
mov ax, y ;AX = PARAMETER FOR NUMBER2STRING.
mov si, offset numstr
call number2string
;DISPLAY Y.
mov ah, 9
mov dx, offset numstr
int 21h
ret
endp display_coords
这篇关于TASM鼠标输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!