mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
842 lines
20 KiB
842 lines
20 KiB
TITLE - Converted Winrect.c to Assembler
|
|
|
|
.286p
|
|
|
|
.xlist
|
|
include wow.inc
|
|
include wowusr.inc
|
|
include cmacros.inc
|
|
NOEXTERNS=1 ; to suppress including most of the stuff in user.inc
|
|
include user.inc
|
|
.list
|
|
|
|
sBegin CODE
|
|
|
|
assumes cs, CODE
|
|
assumes ds, DATA
|
|
|
|
;******************************************************************************
|
|
; ORIGINAL C SOURCE
|
|
;
|
|
;*void FAR SetRect(pRect,left,top,right,bottom)
|
|
;*LPRECT pRect;
|
|
;*int top,left,bottom,right;
|
|
;*{
|
|
;* pRect->top = top;
|
|
;* pRect->left = left;
|
|
;* pRect->bottom = bottom;
|
|
;* pRect->right = right;
|
|
;*}
|
|
;******************************************************************************
|
|
|
|
cProcVDO SetRect,<FAR, PUBLIC, NODATA>
|
|
;ParmD lprc
|
|
;ParmW left
|
|
;ParmW top
|
|
;ParmW right
|
|
;ParmW bottom
|
|
cBegin nogen
|
|
|
|
mov bx,sp
|
|
mov cx,di
|
|
beg_fault_trap sr_trap
|
|
cld
|
|
les di,ss:[bx]+4+2+2+2+2
|
|
mov ax,ss:[bx]+4+2+2+2
|
|
stosw
|
|
mov ax,ss:[bx]+4+2+2
|
|
stosw
|
|
mov ax,ss:[bx]+4+2
|
|
stosw
|
|
mov ax,ss:[bx]+4
|
|
stosw
|
|
end_fault_trap
|
|
sr_cont:
|
|
mov di,cx
|
|
retf 4+2+2+2+2
|
|
|
|
cEnd nogen
|
|
|
|
sr_trap:
|
|
fault_fix_stack
|
|
jmp short sr_cont
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*int FAR SetRectEmpty(pRect)
|
|
;*LPRECT pRect;
|
|
;*{
|
|
;* LFillStruct(pRect,sizeof(RECT),0);
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
LabelVDO SetRectEmpty
|
|
pop ax
|
|
pop dx
|
|
|
|
pop bx
|
|
pop cx
|
|
|
|
push dx
|
|
push ax
|
|
|
|
xchg di,bx
|
|
|
|
beg_fault_trap sre_trap
|
|
mov es,cx
|
|
|
|
xor ax,ax
|
|
cld
|
|
stosw
|
|
stosw
|
|
stosw
|
|
stosw
|
|
end_fault_trap
|
|
|
|
sre_cont:
|
|
mov di,bx
|
|
retf
|
|
|
|
sre_trap:
|
|
fault_fix_stack
|
|
jmp short sre_cont
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*int FAR CopyRect(pDstRect,pSrcRect)
|
|
;*LPRECT pSrcRect; /*ptr to source rect */
|
|
;*LPRECT pDstRect; /*Ptr to dest rect */
|
|
;*{
|
|
;* LCopyStruct(pSrcRect,pDstRect,sizeof(RECT));
|
|
;* /*copy from source to dest */
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
cProcVDO CopyRect, <FAR, PUBLIC, NODATA>, <ds, si, di>
|
|
parmD lpDstRect ;long pointer to DstRect
|
|
parmD lpSrcRect ;long pointer to SrcRect
|
|
cBegin
|
|
beg_fault_trap cr_trap
|
|
lds si, lpSrcRect ;mov into ds:si a far pointer to SrcRect
|
|
les di, lpDstRect ;mov into es:di far pointer to DstRect
|
|
cld ;clear direction flag for increment stuff
|
|
movsw
|
|
movsw
|
|
movsw
|
|
movsw
|
|
end_fault_trap
|
|
cr_cont:
|
|
cEnd
|
|
|
|
cr_trap:
|
|
fault_fix_stack
|
|
jmp short cr_cont
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*BOOL FAR IsRectEmpty(pRect)
|
|
;*LPRECT pRect;
|
|
;*{
|
|
;* return(((pRect->right-pRect->left<=0)||(pRect->bottom-pRect->top<=0)) ? TRUE : FALSE);
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
LabelVDO IsRectEmpty
|
|
pop ax
|
|
pop dx
|
|
|
|
pop bx ; get lprc
|
|
pop cx
|
|
|
|
push dx
|
|
push ax
|
|
|
|
beg_fault_trap ire_trap
|
|
mov es,cx
|
|
mov ax,TRUE
|
|
mov cx,es:[bx].rcRight
|
|
cmp cx,es:[bx].rcLeft
|
|
jle empty0
|
|
mov cx,es:[bx].rcBottom
|
|
cmp cx,es:[bx].rcTop
|
|
jle empty0
|
|
xor ax,ax
|
|
end_fault_trap
|
|
empty0:
|
|
retf
|
|
|
|
ire_trap:
|
|
fault_fix_stack
|
|
jmp short empty0
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*BOOL FAR PtInRect(lprc, pt)
|
|
;*LPRECT lprc;
|
|
;*POINT pt;
|
|
;*{
|
|
;* return(pt.x >= lprc->left && pt.x < lprc->right &&
|
|
;* pt.y >= lprc->top && pt.y < lprc->bottom);
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
cProcVDO PtInRect,<PUBLIC,FAR,NODATA>,<DS,SI>
|
|
; parmD lpRect
|
|
; parmD lpPoint
|
|
cBegin nogen
|
|
|
|
mov bx,sp
|
|
push ds
|
|
push si
|
|
|
|
mov cx,ss:[bx+4] ; cx = pt.x
|
|
mov dx,ss:[bx+6] ; dx = pt.y
|
|
|
|
beg_fault_trap pir_trap
|
|
lds si,ss:[bx+8] ; lpRect
|
|
cld
|
|
xor bx,bx ; Result = FALSE
|
|
|
|
lodsw ; AX = lpRect->left
|
|
cmp cx,ax ; xcoord < left?
|
|
jl PtNotInRect ; Yes, not in rectangle
|
|
|
|
lodsw ; AX = lpRect->top
|
|
cmp dx,ax ; ycoord < top?
|
|
jl PtNotInRect ; Yes, not in rectangle
|
|
|
|
lodsw ; AX = lpRect->right
|
|
cmp cx,ax ; xcoord >= right?
|
|
jge PtNotInRect ; Yes, not in rectangle
|
|
|
|
lodsw ; AX = lpRect->bottom
|
|
cmp dx,ax ; ycoord >= bottom?
|
|
jge PtNotInRect ; Yes, not in rectangle
|
|
|
|
inc bx ; Point in rectangle, result = TRUE
|
|
end_fault_trap
|
|
PtNotInRect:
|
|
mov ax,bx
|
|
pop si
|
|
pop ds
|
|
retf 8
|
|
|
|
cEnd nogen
|
|
|
|
pir_trap:
|
|
fault_fix_stack
|
|
jmp short PtNotInRect
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*int FAR OffsetRect(pRect, x, y)
|
|
;*LPRECT pRect;
|
|
;*int x;
|
|
;*int y;
|
|
;*{
|
|
;* pRect->left += x;
|
|
;* pRect->right += x;
|
|
;* pRect->top += y;
|
|
;* pRect->bottom += y;
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
cProcVDO OffsetRect,<FAR, PUBLIC, NODATA>,<DS>
|
|
; parmD lpRect ;far pointer to struct type rect
|
|
; parmW xDelta ;X delta
|
|
; parmW yDelta ;Y Delta
|
|
cBegin nogen
|
|
mov bx,sp
|
|
push ds
|
|
beg_fault_trap or_trap
|
|
mov dx,ss:[bx+6] ; dx = dx
|
|
mov cx,ss:[bx+4] ; CX = dy
|
|
lds bx,ss:[bx+8] ; ds:bx = lprc
|
|
add [bx].rcLeft,dx
|
|
add [bx].rcTop,cx
|
|
add [bx].rcRight,dx
|
|
add [bx].rcBottom,cx
|
|
end_fault_trap
|
|
or_cont:
|
|
pop ds
|
|
retf 8
|
|
cEnd
|
|
or_trap:
|
|
fault_fix_stack
|
|
jmp short or_cont
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*int FAR InflateRect(pRect, x, y)
|
|
;*LPRECT pRect;
|
|
;*int x;
|
|
;*int y;
|
|
;*{
|
|
;* pRect->left -= x;
|
|
;* pRect->right += x;
|
|
;* pRect->top -= y;
|
|
;* pRect->bottom += y;
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
cProcVDO InflateRect,<FAR, PUBLIC, NODATA>,<DS>
|
|
; parmD lpRect ;far pointer to struct type rect
|
|
; parmW xOffset
|
|
; parmW yOffset
|
|
cBegin nogen
|
|
mov bx,sp
|
|
push ds
|
|
|
|
beg_fault_trap ir_trap
|
|
mov dx,ss:[bx+6] ; dx = dx
|
|
mov cx,ss:[bx+4] ; CX = dy
|
|
lds bx,ss:[bx+8] ; ds:bx = lprc
|
|
sub [bx].rcLeft,dx
|
|
sub [bx].rcTop,cx
|
|
add [bx].rcRight,dx
|
|
add [bx].rcBottom,cx
|
|
|
|
end_fault_trap
|
|
ir_cont:
|
|
pop ds
|
|
retf 8
|
|
cEnd
|
|
|
|
ir_trap:
|
|
fault_fix_stack
|
|
jmp short ir_cont
|
|
|
|
;-----------------------------------------------------------------
|
|
;
|
|
; IntersectRect(lprcDst, lprcSrc1, lprcSrc2);
|
|
;
|
|
cProcVDO IntersectRect,<PUBLIC, FAR, NODATA>,<SI, DI, DS>
|
|
ParmD lprcDst
|
|
ParmD lprcSrc1
|
|
ParmD lprcSrc2
|
|
cBegin
|
|
beg_fault_trap irc_trap
|
|
lds si,lprcSrc1 ; point at source rects
|
|
les di,lprcSrc2
|
|
|
|
mov ax,[si].rcLeft ; new left = cx = max(rc1.left, rc2.left)
|
|
mov cx,es:[di].rcLeft
|
|
cmp ax,cx
|
|
jl ir100
|
|
xchg ax,cx
|
|
ir100:
|
|
mov ax,[si].rcRight ; new right = dx = min(rc1.right, rc2.right)
|
|
mov dx,es:[di].rcRight
|
|
cmp ax,dx
|
|
jg ir200
|
|
xchg ax,dx
|
|
ir200:
|
|
cmp cx,dx ; is left >= right?
|
|
jge irempty ; yes - return empty rect
|
|
|
|
mov ax,[si].rcTop ; new top = cx = max(rc1.top, rc2.top)
|
|
mov bx,es:[di].rcTop
|
|
cmp ax,bx
|
|
jl ir300
|
|
xchg ax,bx
|
|
ir300:
|
|
mov ax,[si].rcBottom ; new bottom = dx = min(rc1.bottom, rc2.bottom)
|
|
mov di,es:[di].rcBottom
|
|
cmp ax,di
|
|
jg ir400
|
|
xchg ax,di
|
|
ir400:
|
|
cmp bx,di ; is top >= bottom?
|
|
jge irempty ; no: store result
|
|
|
|
lds si,lprcDst ; store away new right & left
|
|
mov [si].rcLeft,cx
|
|
mov [si].rcTop,bx
|
|
mov [si].rcRight,dx
|
|
mov [si].rcBottom,di
|
|
|
|
mov al,TRUE ; return TRUE
|
|
end_fault_trap
|
|
irexit:
|
|
|
|
cEnd
|
|
|
|
irc_trap:
|
|
fault_fix_stack
|
|
irempty:
|
|
les di,lprcDst ; point at dst rect
|
|
xor ax,ax ; set to (0, 0, 0, 0)
|
|
cld
|
|
stosw
|
|
stosw
|
|
stosw
|
|
stosw ; return FALSE
|
|
jmps irexit
|
|
|
|
;=============================================================================
|
|
;
|
|
; BOOL UnionRect(lprcDest, lprcSrc1, lprcSrc2)
|
|
; LPRECT lprcDest;
|
|
; LPRECT lprcSrc1;
|
|
; LPRECT lprcSrc2;
|
|
;
|
|
; Calculates *lprcDest as the minimum rectangle that bounds both
|
|
; *lprcSrc1 and *lprcSrc2. If either rectangle is empty, lprcDest
|
|
; is set to the other rectangle. Returns TRUE if the result is a non-empty
|
|
; rectangle, FALSE otherwise.
|
|
;
|
|
;
|
|
cProcVDO UnionRect,<FAR, PUBLIC, NODATA>,<SI, DI, DS>
|
|
ParmD lprcDest
|
|
ParmD lprcSrc1
|
|
ParmD lprcSrc2
|
|
LocalW wTemp
|
|
cBegin
|
|
beg_fault_trap ur_trap
|
|
lds si,lprcSrc1
|
|
les di,lprcSrc2
|
|
|
|
push es
|
|
push di
|
|
wcall IIsRectEmpty
|
|
push ax ; save result
|
|
|
|
; IsRectEmpty trashes es....
|
|
push es
|
|
|
|
push ds
|
|
push si
|
|
wcall IIsRectEmpty
|
|
|
|
pop es ; restore it
|
|
pop cx
|
|
|
|
;ax = IsRectEmpty(1), cx = IsRectEmpty(2)
|
|
|
|
or ax,ax
|
|
jnz URrc1empty
|
|
mov ax,TRUE ; return true, not both empty
|
|
or cx,cx
|
|
jz URnormalcase
|
|
jmps URrc2empty
|
|
|
|
URrc1empty:
|
|
lds si,lprcSrc2
|
|
jcxz URrc2empty ; rc2 not empty, ax has true for return
|
|
xor ax,ax ; return false, both empty
|
|
|
|
URrc2empty:
|
|
les di,lprcDest
|
|
cld
|
|
movsw
|
|
movsw
|
|
movsw
|
|
movsw
|
|
jmps URexit
|
|
|
|
; src1 and src2 not empty
|
|
|
|
URnormalcase:
|
|
mov ax,[si].rcLeft ; bx = min(Src1.left, Src2.left)
|
|
mov cx,es:[di].rcLeft
|
|
cmp ax,cx
|
|
jl URleft
|
|
xchg ax,cx
|
|
URleft:
|
|
mov bx,ax
|
|
|
|
mov ax,[si].rcTop ; dx = min(Src1.top, Src2.top)
|
|
mov cx,es:[di].rcTop
|
|
cmp ax,cx
|
|
jl URtop
|
|
xchg ax,cx
|
|
URtop:
|
|
mov dx,ax
|
|
|
|
mov ax,[si].rcRight ; wTemp = max(Src1.right, Src2.right)
|
|
mov cx,es:[di].rcRight
|
|
cmp ax,cx
|
|
jg URright
|
|
xchg ax,cx
|
|
URright:
|
|
mov wTemp,ax
|
|
|
|
mov ax,[si].rcBottom ; ax = max(Src1.bottom, Src2.bottom)
|
|
mov cx,es:[di].rcBottom
|
|
cmp ax,cx
|
|
jg URbottom
|
|
xchg ax,cx
|
|
URbottom:
|
|
|
|
les di,lprcDest ; fill into lprcDest
|
|
mov es:[di].rcLeft,bx
|
|
mov es:[di].rcTop,dx
|
|
mov es:[di].rcBottom,ax
|
|
mov ax,wTemp
|
|
mov es:[di].rcRight,ax
|
|
end_fault_trap
|
|
|
|
ur_true:
|
|
mov ax,TRUE ; return true, not both empty
|
|
URexit:
|
|
cEnd
|
|
|
|
ur_trap:
|
|
fault_fix_stack
|
|
jmp ur_true
|
|
|
|
|
|
;******************************************************************************
|
|
;* ORIGINAL C SOURCE
|
|
;*
|
|
;*BOOL FAR EqualRect(lpRect1, lpRect2)
|
|
;*LPRECT lpRect1;
|
|
;*LPRECT lpRect2;
|
|
;*{
|
|
;* return lpRect1->left == lpRect2->left && lpRect1->top == lpRect2->top
|
|
;* && lpRect1->right == lpRect1->right && lpRect1->bottom ==
|
|
;* lpRect2->bottom;
|
|
;*}
|
|
;*
|
|
;******************************************************************************
|
|
|
|
cProcVDO EqualRect, <FAR, PUBLIC, NODATA>, <SI, DI, DS>
|
|
parmD lpRect1
|
|
parmD lpRect2
|
|
cBegin
|
|
xor ax,ax ; assume FALSE
|
|
beg_fault_trap er_trap
|
|
lds si,lpRect1
|
|
les di,lpRect2
|
|
mov cx,4
|
|
cld
|
|
repz cmpsw
|
|
jnz er10
|
|
inc al
|
|
end_fault_trap
|
|
er10:
|
|
cEnd
|
|
|
|
er_trap:
|
|
fault_fix_stack
|
|
jmp er10
|
|
|
|
;****************************************************************************
|
|
; The following Routine to subtract one rectangle from another is lifted
|
|
; from PM and Modified by Sankar.
|
|
;
|
|
;****************************************************************************
|
|
|
|
;** Public Routine ****************************************************-;
|
|
; BOOL far SubtractRect(lprcDest, lprc1, lprc2)
|
|
; LPRECT lprcDest;
|
|
; LPRECT lprcSrc1;
|
|
; LPRECT lprcSrc2;
|
|
;
|
|
; This function subtracts *lprc2 from *lprc1, returning the result
|
|
; in *lprcDest. Returns TRUE if *lprcDest is non-empty, FALSE otherwise.
|
|
;
|
|
; Warning: Subtracting one rectangle from another may not
|
|
; always result in a rectangular area; in this case
|
|
; WinSubtractRect will return *lprc1 in *lprcDest.
|
|
; For this reason, WinSubtractRect provides only an
|
|
; approximation of subtraction. However, the area
|
|
; described by *lprcDest will always be greater
|
|
; than or equal to the "true" result of the
|
|
; subtraction.
|
|
;
|
|
; History :
|
|
; Added by Sankar on July 27, 1988
|
|
;**********************************************************************-;
|
|
|
|
cProcVDO SubtractRect, <PUBLIC, FAR, NODATA>, <SI, DI, DS>
|
|
ParmD lprcDest
|
|
ParmD lprc1
|
|
ParmD lprc2
|
|
LocalV rc,%size RECT
|
|
cBegin
|
|
;
|
|
; First copy lprc1 into lprcDest.
|
|
;
|
|
beg_fault_trap sbr_trap
|
|
lds si,lprc1
|
|
les di,lprcDest
|
|
cld
|
|
movsw
|
|
movsw
|
|
movsw
|
|
movsw
|
|
|
|
lds si,lprcDest ; ds:[si] = lprcDest.
|
|
lea di,rc ; ss:[di] = &rc
|
|
;
|
|
; We're subtracting lprc2 from lprc1. Make sure they at least
|
|
; intersect each other. If not, return TRUE.
|
|
;
|
|
push ss ; pushd &rc
|
|
push di
|
|
push ds ; pushd lprcDest
|
|
push si
|
|
push seg_lprc2 ; pushd lprc2
|
|
push off_lprc2
|
|
wcall IIntersectRect
|
|
|
|
or ax,ax ; Did we intersect?
|
|
jz sr700 ; If no, skip to check empty rect
|
|
;
|
|
; Now make sure that we can subtract lprc2 from lprc1 and get a rect.
|
|
;
|
|
errnz <rcLeft - 0>
|
|
errnz <rcTop - 2>
|
|
errnz <rcRight - 4>
|
|
errnz <rcBottom - 6>
|
|
;
|
|
; We make a loop that iterates twice - once for the x's and once for the
|
|
; y's. We want at least 3 sides of lprc2 to be outside of 3 sides of lprc1.
|
|
;
|
|
xor cx,cx
|
|
xor dx,dx
|
|
dec cx
|
|
;
|
|
; ds:si points to lprc1 (actually lprcDest)
|
|
; ss:di points to rc on stack
|
|
;
|
|
sr100:
|
|
inc cx
|
|
|
|
mov bx,cx
|
|
shl bx,1 ; bx is a Word pointer
|
|
|
|
mov ax,ss:[di+bx].rcLeft ; if lprc2 left/top is > lprc1 l/t,
|
|
cmp ax,ds:[si+bx].rcLeft
|
|
jg sr200 ; then inside the rect.
|
|
inc dx
|
|
sr200:
|
|
mov ax,ss:[di+bx].rcRight ; if lprc2 right/bottom is > lprc1 r/b,
|
|
cmp ax,ds:[si+bx].rcRight
|
|
jl sr300 ; then inside the rect.
|
|
inc dx
|
|
sr300:
|
|
jcxz sr100 ; loop one more time...
|
|
|
|
cmp dx,3 ; Are 3 sides outside? If not,
|
|
jb sr700 ; skip to check empty rect code
|
|
|
|
cmp dx,4 ; Is rc1 completely inside rc2? If so,
|
|
jne sr350 ; empty lprcDest and return TRUE
|
|
|
|
pushd lprcDest ; empty that puppy
|
|
wcall ISetRectEmpty
|
|
|
|
xor ax,ax ; Go return FALSE.
|
|
jmps srExit
|
|
|
|
sr350:
|
|
;
|
|
; Now we know that we can take lprc2 from lprc1 and leave a rect, so
|
|
; now we perform the 'subtract rect'. Interate twice, again once for the
|
|
; x's and once for the y's.
|
|
;
|
|
xor cx,cx
|
|
dec cx
|
|
|
|
sr400:
|
|
inc cx
|
|
mov bx,cx
|
|
shl bx,1 ; Make bx a Word pointer
|
|
|
|
mov dx,ss:[di+bx].rcLeft ; New right/Bottom border?
|
|
cmp dx,ds:[si+bx].rcLeft
|
|
jle sr500
|
|
|
|
mov ds:[si+bx].rcRight,dx
|
|
jmps sr600
|
|
|
|
sr500:
|
|
mov dx,ss:[di+bx].rcRight ; New left/top border?
|
|
cmp dx,ds:[si+bx].rcRight
|
|
jge sr600
|
|
|
|
mov ds:[si+bx].rcLeft,dx
|
|
|
|
sr600:
|
|
jcxz sr400
|
|
|
|
sr700:
|
|
xor ax,ax ; Assume it is empty: FALSE
|
|
|
|
mov cx,ds:[si].rcRight
|
|
cmp cx,ds:[si].rcLeft
|
|
jle SrExit
|
|
|
|
mov cx,ds:[si].rcBottom
|
|
cmp cx,ds:[si].rcTop
|
|
jle SrExit
|
|
|
|
inc al ; Non-empty: return TRUE.
|
|
end_fault_trap
|
|
srExit:
|
|
cEnd
|
|
|
|
sbr_trap:
|
|
fault_fix_stack
|
|
xor ax,ax ; return FALSE
|
|
jmp srExit
|
|
|
|
;****************************************************************************
|
|
;
|
|
; void FAR SplitRectangle(lprcRect, lprcRectArray, wcx, wcy)
|
|
; LPRECT lprcRect
|
|
; RECT lprcRectArray[4]
|
|
;
|
|
; This splits the given rectangular frame into four segments and stores
|
|
; them in the given array
|
|
;
|
|
; Pseudo code:
|
|
; -----------
|
|
;
|
|
; cxWidth = lprcRect -> rcRight - lprcRect -> rcLeft - wcx;
|
|
; cyWidth = lprcRect -> rcBottom - lprcRect -> rcTop - wcy;
|
|
;
|
|
; A = -cyWidth;
|
|
; B = -cxWidth;
|
|
;
|
|
; for (i = 0; i < 4; i++)
|
|
; {
|
|
; lprcRectArray[i][i] = lprcRect[i];
|
|
; lprcRectArray[i][(i+1)&3] = lprcRect[(i+3)&3] + A;
|
|
; lprcRectArray[i][(i+2)&3] = lprcRect[(i+2)&3] + B;
|
|
; lprcRectArray[i][(i+3)&3] = lprcRect[(i+3)];
|
|
;
|
|
; TMP = A;
|
|
; A = -B;
|
|
; B = TMP;
|
|
; }
|
|
;
|
|
; Note:
|
|
; Value of i Value of A Value of B
|
|
; ---------- ---------- ----------
|
|
; 0 -cyWidth -cxWidth
|
|
; 1 +cxWidth -cyWidth
|
|
; 2 +cyWidth +cxWidth
|
|
; 3 -cxWidth +cyWidth
|
|
;
|
|
;
|
|
;***************************************************************************
|
|
|
|
|
|
|
|
cProc SplitRectangle, <FAR, PUBLIC, NODATA>, <SI, DI, DS>
|
|
|
|
ParmD <lprcRect, lprcRectArray> ; Rect and Array
|
|
Parmw <wcx, wcy> ; Border widths
|
|
|
|
cBegin
|
|
|
|
les di, lprcRectArray ; es:di => lprcRectArray
|
|
lds si, lprcRect ; ds:si => given rectangle
|
|
|
|
; Calculate the value of -cxWidth
|
|
|
|
mov ax, [si].rcLeft
|
|
sub ax, [si].rcRight
|
|
add ax, wcx
|
|
|
|
push ax ; Save B on stack.
|
|
|
|
; Calculate the value of -cyWidth
|
|
|
|
mov ax, [si].rcTop
|
|
sub ax, [si].rcBottom
|
|
add ax, wcy
|
|
|
|
push ax ; Save A on stack
|
|
|
|
; Initialise the loop related variables
|
|
|
|
xor cx, cx ; Loop count
|
|
xor bx, bx ; Index into Rect Structure.
|
|
|
|
LoopSt:
|
|
; lprcRectArray[i][i] = lprcRect[i];
|
|
|
|
mov ax, [si+bx]
|
|
mov es:[di+bx], ax
|
|
|
|
; lprcRectArray[i][(i+1)&3] = lprcRect[(i+3)&3] + A;
|
|
|
|
inc bx
|
|
inc bx ; Make it a word pointer
|
|
and bx, 6
|
|
push bx ; Save (i+1) tempoarily
|
|
add bx, 4 ; Calculate (i+3)
|
|
and bx, 6
|
|
|
|
mov ax, [si+bx] ; lprcRect[(i+3)] is taken
|
|
pop bx ; (i+1) is returned to bx
|
|
|
|
pop dx ; Value "A" is taken from stack
|
|
add ax, dx
|
|
mov es:[di+bx], ax
|
|
|
|
; Swap A and B on stack. A is in DX
|
|
|
|
pop ax ; Value B from Stack.
|
|
push dx ; B = A;
|
|
Push ax ; A = B;
|
|
|
|
; Now B is on top of stack and A is below it.
|
|
|
|
|
|
; lprcRectArray[i][(i+2)&3] = lprcRect[(i+2)&3] + B;
|
|
|
|
inc bx
|
|
inc bx ; (i+2) is calculated
|
|
and bx, 6
|
|
|
|
mov ax, [si+bx]
|
|
pop dx ; pop B
|
|
add ax, dx
|
|
|
|
mov es:[di+bx], ax
|
|
neg dx ; make -B
|
|
push dx
|
|
|
|
; lprcRectArray[i][(i+3)&3] = lprcRect[(i+3)];
|
|
|
|
inc bx
|
|
inc bx
|
|
and bx, 6 ; make [(i+3)&3]
|
|
|
|
mov ax, [si+bx]
|
|
mov es:[di+bx], ax
|
|
|
|
inc cx
|
|
cmp cx, 4
|
|
jge exit
|
|
|
|
mov bx, cx
|
|
shl bx, 1 ; Make it a word pointer
|
|
add di, size RECT ; Make it point to next rect in the array
|
|
jmp LoopSt
|
|
exit:
|
|
; A and B exist on stack. So,Pop them
|
|
add sp, 4
|
|
|
|
cEnd
|
|
|
|
|
|
sEnd TEXT
|
|
end
|