putting together a mouse driven application divide and conquer

36
Putting together a mouse driven application Divide and conquer

Post on 21-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

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

;---------------------------------------------------------

HideCursor proc

;

; 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 continuedLBC1:

; 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

mov ax,Xcoordinate

call WriteDec

mov dl,20 ; screen column

call Gotoxy

mov ax,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 procShowMousePosition 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.

cmp cx,Xcoordinate

jne SMP1

cmp dx,Ycoordinate

je SMP_exit

Showmouseposition continuedSMP1:

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

1. Put a string at a random screen location… erase it when a key is struck and rewrite it elsewhere. Quit on escape key.

2. Cut/paste code from datetime.asm into leftbuttonclick proc in basic mouse program

3. Modify timer output to show time in seconds

4. Modify #3 to show elapsed seconds

5. 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

codemov ax,@datamov ds,axcall clrscr ;;;before the loop clrscrcall randomize ;;;randomize just once

top:mov eax,80-len ;;random column..make sure string will fit on this linecall randomrangemov dl,almov eax,25 ;;random rowcall randomrangemov dh,alpush dx ;;we need to save dx for latercall gotoxymov dx, offset stringcall writestring ;;write original stringmov dl,0ffh ;;see next couple of lines dl=ffh means inputmov ah,6 ;;DOS no echo input

poll: int 21hjz poll ;;zero means no char struck yetcmp al,27 ;;escape char to terminate…does not work as well as text versionje quitpop dxcall gotoxy ;;go back and erase the stringmov dx, offset blankscall writestringjmp 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

mov dl,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

Running it in dosbox

paste code from datetime.asm into left-button-click

; Position the cursor, clear the old numbers.mov dh,24 ; screen rowmov dl,15 ; screen columncall Gotoxypush dxmov dx,OFFSET blankscall WriteStringpop dx

; Show the timer info….this is what I pasted.call Gotoxymov ah,2Ch; get system timeint 21hmovzx eax,ch ; hourscall WritePaddedDecINVOKE Write,':'movzx eax,cl ; minutescall WritePaddedDecINVOKE Write,':'movzx eax,dh ; secondscall WritePaddedDeccall Crlf

;mov ax,Xcoordinate;call WriteDec;mov dl,20 ; screen column;call Gotoxy;mov ax,Ycoordinate;call WriteDec

LBC_exit:poparet

LeftButtonClick ENDP

Should look like this

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 procmov ah,2Ch ; get system timeint 21hpush dx ;;;save seconds for later recoverymovzx ax,ch ; hoursmul sixtymovzx bx,cl ; minutesadd ax,bxmul sixtypop dxshr dx,8add ax,dx ; get seconds and add them inmov dh,24mov dl,10call gotoxycall WriteDeccall Crlfret

gettime endp

Display elapsed seconds

Remove output from gettime proc

gettime procmov ah,2Ch ; get system timeint 21hpush dxmovzx ax,ch ; hoursmul sixtymovzx bx,cl ; minutesadd ax,bxmul sixtypop dxshr dx,8add ax,dx ; seconds

retgettime endp

In main… get time twice and display the difference

call gotoxymov dx, offset stringcall writestringcall gettime ;;get initial timemov oldtime,ax ;;save start of stop watchmov dl,0ffhmov ah,6poll:int 21hjz pollcmp al,1bhje quitpop dxcall gotoxymov dx, offset blankscall writestringcall gettime ;;get elapsed timesub ax,oldtime ;;calculate diffmov dh,24mov dl,10call gotoxycall WriteDec ;;display itcall 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

mouse program running: click is close

mouse program running: click is not close

Modifications to leftclick proc: checking for an arbitrary poisition (row=10 col=20)

; Show the mouse click coordinates.call Gotoxymov ax,Xcoordinateshr ax,3mov bx,colsub bx,4cmp ax,bx ;;;column20?jl m2add bx,4cmp ax,bx;;;col25ja m2mov dl,20 ; call Gotoxymov ax,Ycoordinateshr ax,3mov bx,rowsub bx,2cmp ax,bx;;;row 10jl m2add bx,2cmp ax,bxja m2mov dx,offset messagecall writestringjmp lbc_exit

m2: mov dx,offset outsidemessage

call writestringLBC_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