360 likes | 373 Views
Putting together a mouse driven application. Divide and conquer. Mouse.asm from 5 th edition in slide notes. Data area INCLUDE Irvine16.inc .data ESCkey = 1Bh GreetingMsg BYTE "Press Esc to quit",0dh,0ah,0 StatusLine BYTE "Left button: "
E N D
Putting together a mouse driven application Divide and conquer
Mouse.asm from 5th edition in slide notes • Data area INCLUDE Irvine16.inc .data ESCkey = 1Bh GreetingMsg BYTE "Press Esc to quit",0dh,0ah,0 StatusLine BYTE "Left button: " BYTE "Mouse position: ",0 blanks BYTE " ",0 Xcoordinate WORD 0 ; current X-position Ycoordinate WORD 0 ; current Y-position Xclick WORD 0 ; X-pos of last button click Yclick WORD 0 ; Y-pos of last button click
Driver: call HideCursor mov dx,OFFSET GreetingMsg call WriteString call ShowMousePointer ; Display a status line on line 24. mov dh,24 mov dl,0 call Gotoxy mov dx,OFFSET StatusLine call Writestring
Driver continued ; Loop: show mouse coordinates, check for left mouse ; button click, or for a keypress (Esc key). L1: call ShowMousePosition call LeftButtonClick ; check for button click mov ah,11h ; key pressed already? int 16h jz L2 ; no, continue the loop mov ah,10h ; remove key from buffer int 16h cmp al,ESCkey ; yes. Is it the ESC key? je quit ; yes, quit the program L2: jmp L1 ; no, continue the loop ; Hide the mouse, restore the text cursor, clear ; the screen, and display "Press any key to continue." quit: call HideMousePointer call ShowCursor call Clrscr call WaitMsg
HideCursor Show mousepointer procs ;--------------------------------------------------------- HideCursorproc ; ; Hide the text cursor by setting its top line ; value to an illegal value. ;--------------------------------------------------------- mov ah,3 ; get cursor size int 10h or ch,30h ; set upper row to illegal value mov ah,1 ; set cursor size int 10h ret HideCursor ENDP • ;--------------------------------------------------------- • ShowMousePointer PROC • ;--------------------------------------------------------- • push ax • mov ax,1 ; make mouse cursor visible • int 33h • pop ax • ret • ShowMousePointer ENDP
Showcursor/Hide mouse pointer procs ShowCursor PROC mov ah,3 ; get cursor size int 10h mov ah,1 ; set cursor size mov cx,0607h ; default size int 10h ret ShowCursor ENDP HideMousePointer PROC ;--------------------------------------------------------- push ax mov ax,2 ; hide mouse cursor int 33h pop ax ret HideMousePointer ENDP
GetMousePosition PROC ;--------------------------------------------------------- GetMousePosition PROC ; ; Return the current mouse position and button status. ; Receives: nothing ; Returns: BX = button status (0 = left button down, ; (1 = right button down, 2 = center button down) ; CX = X-coordinate ; DX = Y-coordinate ;--------------------------------------------------------- push ax mov ax,3 int 33h pop ax ret GetMousePosition ENDP
Left button click proc ;--------------------------------------------------------- LeftButtonClick PROC ; ; Check for the most recent click of the left mouse ; button, and display its location. ; Receives: BX = button number (0=left, 1=right, 2=middle) ; Returns: BX = button press counter ; CX = X-coordinate ; DX = Y-coordinate ;--------------------------------------------------------- pusha mov ah,0 ; get mouse status mov al,5 ; (button press information) mov bx,0 ; specify the left button int 33h ; Exit proc if the coordinates have not changed. cmp cx,Xclick jne LBC1 cmp dx,Yclick je LBC_exit
Left button click continued LBC1: ; Save the mouse coordinates. mov Xclick,cx mov Yclick,dx ; Position the cursor, clear the old numbers. mov dh,24 ; screen row mov dl,15 ; screen column call Gotoxy push dx mov dx,OFFSET blanks call WriteString pop dx
Left button click last slide ; Show the mouse click coordinates. call Gotoxy movax,Xcoordinate call WriteDec mov dl,20 ; screen column call Gotoxy movax,Ycoordinate call WriteDec LBC_exit: popa ret LeftButtonClick ENDP
Set mouse position • ;--------------------------------------------------------- • SetMousePosition PROC • ; • ; Set the mouse's position on the screen. • ; Receives: CX = X-coordinate • ; DX = Y-coordinate • ; Returns: nothing • ;--------------------------------------------------------- • mov ax,4 • int 33h • ret • SetMousePosition ENDP • ;---------------------------------------------------------
Showmouseposition proc ShowMousePosition PROC ; ; Get and show the mouse corrdinates at the ; bottom of the screen. ; Receives: nothing ; Returns: nothing ;--------------------------------------------------------- pusha call GetMousePosition ; Exit proc if the coordinates have not changed. cmpcx,Xcoordinate jne SMP1 cmpdx,Ycoordinate je SMP_exit
Showmouseposition continued SMP1: mov Xcoordinate,cx mov Ycoordinate,dx ; Position the cursor, clear the old numbers. mov dh,24 ; screen row mov dl,60 ; screen column call Gotoxy push dx mov dx,OFFSET blanks call WriteString pop dx ; Show the mouse coordinates. call Gotoxy ; (24,60) mov ax,Xcoordinate call WriteDec mov dl,65 ; screen column call Gotoxy mov ax,Ycoordinate call WriteDec SMP_exit: popa ret ShowMousePosition ENDP
Divide and conquer • Break the large problem into smaller parts. • The decomposition should be rational, and facilitate final assembly of the parts, but may not be unique.
Sample decomposition: code each of the following pieces • Put a string at a random screen location… erase it when a key is struck and rewrite it elsewhere. Quit on escape key. • Cut/paste code from datetime.asm into leftbuttonclick proc in basic mouse program • Modify timer output to show time in seconds • Modify #3 to show elapsed seconds • Modify mouse program to check screen location of click in rows and columns
Printing a string to a random location…and erasing it • My data area .data string byte 'random string',0 len=$-string blanks byte ' ',0;use to erase string
code mov ax,@data mov ds,ax call clrscr ;;;before the loop clrscr call randomize ;;;randomize just once top: mov eax,80-len ;;random column..make sure string will fit on this line call randomrange mov dl,al mov eax,25 ;;random row call randomrange mov dh,al push dx ;;we need to save dx for later call gotoxy mov dx, offset string call writestring ;;write original string mov dl,0ffh ;;see next couple of lines dl=ffh means input mov ah,6 ;;DOS no echo input poll: int 21h jz poll ;;zero means no char struck yet cmp al,27 ;;escape char to terminate…does not work as well as text version je quit pop dx call gotoxy ;;go back and erase the string mov dx, offset blanks call writestring jmp top quit: ;;exit code
Mouse program plus initial timer info • Paste timer interrupt code (plus output of it) into mouse.asm from chapt 15. Put it down in leftbuttonclick proc • You’ll have to paste the procs from the datetime program, as well as a proto statement into your new mouse program • Datetime.asm is in chapter14 examples
Here is datetime from chpt14 (6th ed) TITLE Display the Date and Time (DateTime.asm) ; This Real-mode program displays the date and time. ; Last update: 06/01/2006 Include Irvine16.inc Write PROTO char:BYTE .data str1 BYTE "Date: ",0 str2 BYTE ", Time: ",0
datetime from chpt14 (6th ed) .code main PROC mov ax,@data mov ds,ax ; Display the date: mov dx,OFFSET str1 call WriteString mov ah,2Ah ; get system date int 21h movzx eax,dh ; month call WriteDec INVOKE Write,'-' movzx eax,dl ; day call WriteDec INVOKE Write,'-' movzx eax,cx ; year call WriteDec
datetime from chpt14 (6th ed) ; Display the time: mov dx,OFFSET str2 call WriteString mov ah,2Ch ; get system time int 21h movzx eax,ch ; hours call WritePaddedDec INVOKE Write,':' movzx eax,cl ; minutes call WritePaddedDec INVOKE Write,':' movzx eax,dh ; seconds call WritePaddedDec call Crlf exit main ENDP
Datetime…continued ;--------------------------------------------- Write PROC char:BYTE ; Display a single character. ;--------------------------------------------- push eax push edx mov ah,2 movdl,char int 21h pop edx pop eax ret Write ENDP
Datetime…continued ;--------------------------------------------- WritePaddedDec PROC ; Display unsigned integer in EAX, padding ; to two digit positions with a leading zero. ;--------------------------------------------- .IF eax < 10 push eax push edx mov ah,2 mov dl,'0' int 21h pop edx pop eax .ENDIF call WriteDec ret WritePaddedDec ENDP END main
paste code from datetime.asm into left-button-click ; Position the cursor, clear the old numbers. mov dh,24 ; screen row mov dl,15 ; screen column call Gotoxy push dx mov dx,OFFSET blanks call WriteString pop dx ; Show the timer info….this is what I pasted. call Gotoxy mov ah,2Ch ; get system time int 21h movzx eax,ch ; hours call WritePaddedDec INVOKE Write,':' movzx eax,cl ; minutes call WritePaddedDec INVOKE Write,':' movzx eax,dh ; seconds call WritePaddedDec call Crlf ;mov ax,Xcoordinate ;call WriteDec ;mov dl,20 ; screen column ;call Gotoxy ;mov ax,Ycoordinate ;call WriteDec LBC_exit: popa ret LeftButtonClick ENDP
Next add seconds calculation to randomstring printing program: elapsed seconds appear in lower left
(DateTime.asm is currently in chapter 14 of text)A gettime proc – convert (h,m,s) into seconds gettime proc mov ah,2Ch ; get system time int 21h push dx ;;;save seconds for later recovery movzx ax,ch ; hours mul sixty movzx bx,cl ; minutes add ax,bx mul sixty pop dx shr dx,8 add ax,dx ; get seconds and add them in mov dh,24 mov dl,10 call gotoxy call WriteDec call Crlf ret gettime endp
Remove output from gettime proc gettime proc mov ah,2Ch ; get system time int 21h push dx movzx ax,ch ; hours mul sixty movzx bx,cl ; minutes add ax,bx mul sixty pop dx shr dx,8 add ax,dx ; seconds ret gettime endp
In main… get time twice and display the difference call gotoxy mov dx, offset string call writestring call gettime ;;get initial time mov oldtime,ax ;;save start of stop watch mov dl,0ffh mov ah,6 poll:int 21h jz poll cmp al,1bh je quit pop dx call gotoxy mov dx, offset blanks call writestring call gettime ;;get elapsed time sub ax,oldtime ;;calculate diff mov dh,24 mov dl,10 call gotoxy call WriteDec ;;display it call Crlf
Modify mouse program again • convert pixels to r/c • check if mousebutton click (row, col) is close to (row,col) of string • I used row=px/8 col=py/8 where px and py are mouse coordinates in pixels. • I simply checked if user was clicking in an arbitrary place and displayed a message for debug purposes
Modifications to leftclick proc: checking for an arbitrary poisition (row=10 col=20) ; Show the mouse click coordinates. call Gotoxy mov ax,Xcoordinate shr ax,3 mov bx,col sub bx,4 cmp ax,bx ;;;column20? jl m2 add bx,4 cmp ax,bx;;;col25 ja m2 mov dl,20 ; call Gotoxy mov ax,Ycoordinate shr ax,3 mov bx,row sub bx,2 cmp ax,bx;;;row 10 jl m2 add bx,2 cmp ax,bx ja m2 mov dx,offset message call writestring jmp lbc_exit m2: mov dx,offset outsidemessage call writestring LBC_exit:
What’s left to do • Put elapsed times into an array • Print a colored (not b/w) string • Find average value (etc) in array of times • Put all the pieces together and test the final program