2016-06-13 754 views
2

Ich arbeite an einem Assembly-Projekt mit TASM, DosBox und Notepad ++. Ich zeichne einen Punkt auf dem Bildschirm und ich muss wissen, ob der Benutzer darauf geklickt hat (rechte Maustaste). Ich habe versucht zu überprüfen, ob der Benutzer mit der rechten Maustaste geklickt hat und ob die Klickkoordinaten mit den Punktkoordinaten übereinstimmen.
Aus irgendeinem Grund funktioniert es nicht. Hier ist meine proc:TASM-Mauseingabe

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 

Hier nenne ich es:

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] 

Das Programm nur zwischen den Etiketten Springen ist, spielt es keine Rolle, ob die Koordinaten die gleichen sind oder nicht.

+1

Angenommen, der Aufruf von 'DotOne' zerstört' bx' nicht, dann gibt der Dienst 'Int 33/AX = 0003h' die ** aktuelle ** Position und den Status der Schaltflächen zurück. Vielleicht interessiert dich "Int 33/AX = 0005h" am meisten? Oder vielleicht "Int 33/AX = 000ch" für einen interruptgesteuerten Ansatz? –

Antwort

1

Ihr Code hat einige Probleme:

  • proc SetCursor sollte nicht die Maus init und die Position zur gleichen Zeit.
  • je Check_X_Cords braucht einen weiteren Sprung, falls es nicht gleich ist. Das gleiche für je Check_Y_Cords
  • Wie @MargaretBloom sagte, ist es möglich, dass call DotOne zerstört BX.

Es gibt eine Menge Code fehlt, also musste ich es zu geben, um es zu testen:

  • hinzugefügt Variablen x, y die Mausposition zu bewahren.
  • Zeigt die Koordinaten an, um zu überprüfen, wo wir klicken.
  • Zeigt "score!" wenn Pixel angeklickt wird.

Hier ist der Code, es läuft und erkennt richtig der rechten Maustaste auf das Pixel (Linksklick ignoriert wird, aber Sie können es ändern), werden die Kommentare helfen Ihnen, es zu verstehen:

.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