Reputation: 177
I want to be more efficient when I want to check if a location is inside a "mini border". I was checking each possible location in the border and compared it to the actual location.
For example, when I wanted to check if a location is indie a rectangle, I was providing the top left location, width and length of it. Then, comparing pixel location after pixel location to the actual location.
PROC CHECK_IF_IN_BORDER
;THIS PROC IS CHECKING IF THE LOCATION IS INSITE AN RECTANGLE THAT ITS
;TOP LEFT CORNER IOS TOP_LEFT LOCATION OF BORDER AND ITS LENGTH
;AND WIDTH ARE SIMILAR TO WHAT YOU RECIVE FROM THE USER
;----------------GET-------------------;
;BP + 4 - TOP LEFT LOCATION OF BORDER ;
;BP + 6 - LENGTH ;
;BP + 8 - WIDTH ;
;BP + 10 - LOCATION ;
;--------------------------------------;
;------------RETURN--------------------;
; 1 - IF LOCATION IS IN BORDER ;
; 0 - IF LOCATION IS NOT IN BORDER ;
;--------------------------------------;
PUSH BP
MOV BP,SP
PUSH AX
PUSH DX
PUSH BX
MOV BX, 0
MOV AX,[BP+10]
CHECK_NEXT_LINE1:
MOV DX,0
CHECK_LINE1:
CMP AX,[BP+4]
JE IN_BORDER1
INC AX
INC DX
CMP DX,[BP+8] ;LENGTH
JNE CHECK_LINE1
;----------------
SUB AX,[BP+8] ;LENGTH
ADD AX,320
;----------------
INC BX
CMP BX, [BP+6] ;WIDTH
JNE CHECK_NEXT_LINE1
;NOT IN_BORDER:
MOV [BP+10], 0
JMP SOF_BORDERPROC1
IN_BORDER1:
MOV [BP+10], 1
SOF_BORDERPROC1:
POP BX
POP DX
POP AX
POP BP
RET 6
ENDP CHECK_IF_IN_BORDER
Upvotes: 4
Views: 53
Reputation: 39546
What you named LENGTH is actually WIDTH because it refers to the horizontal direction.
What you named WIDTH is actually HEIGHT because it refers to the vertical direction.
This remains true even if the width is much longer than the height and where it becomes tempting to speak about lengths and widths.
Also note that this same confusion has introduced a numerical error in your code ([bp+6]
vs [bp+8]
).
How to make a number type location to x,y type location
Currently your program uses an (offset) address to refer to a pixel. It is easy to convert this address into the (x,y) coordinates. All it takes is a division by the length of the screen scanline. The quotient (AX
) gives you the y-coordinate, the remainder (DX
) gives you the x-coordinate.
mov ax, [bp+10] ; LOCATION
xor dx, dx
mov cx, 320
div cx ; -> DX = X, AX = Y
mov si, dx ; X
mov di, ax ; Y
mov ax, [bp+4] ; TOP LEFT LOCATION OF BORDER
xor dx, dx
div cx ; -> DX = TopLeftX, AX = TopLeftY
The coordinates for the bottom right corner of your rectangle are
(BottomRightX, BottomRightY) = (TopLeftX + Width - 1, TopLeftY + Height - 1)
mov bx, dx ; TopLeftX
add bx, [bp+6] ; + WIDTH
dec bx ; - 1
mov cx, ax ; TopLeftY
add cx, [bp+8] ; + HEIGHT
dec cx ; - 1
This is what we have by now:
<---------------WIDTH-------------->
(DX,AX) UpperLeft
*................................... ^
.............................o...... o is (SI,DI) TestPixel |
.................................... HEIGHT
.................................... |
...................................* v
(BX,CX) BottomRight
The pixel falls within the rectangle if
DX <= SI <= BX
and AX <= DI <= CX
which translates in assembly to:
mov word [bp+10], 0 ; LOCATION IS NOT IN BORDER
cmp dx, si
ja Outside
cmp si, bx
ja Outside
cmp ax, di
ja Outside
cmp di, cx
ja Outside
inc word [bp+10] ; LOCATION IS IN BORDER
Outside:
; all the pops that you need ...
ret 6
Upvotes: 2