TASM mouse input

一世执手 提交于 2019-12-24 00:59:29

问题


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

Here I call it:

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.


回答1:


Your code has some problems :

  • 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 for je 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 :

  • Added variables x,y to preserve the mouse position.
  • Displays the coordinates to check where we are clicking on.
  • Displays "score!" when pixel is clicked.

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


来源:https://stackoverflow.com/questions/37786154/tasm-mouse-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!