Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1189 lines
35 KiB

;---------------------------Module-Header------------------------------;
; Module Name: strips.asm
;
; Routines used by line code to draw strips of pixels.
;
; Copyright (c) 1992 Microsoft Corporation
;-----------------------------------------------------------------------;
.386
.model small,c
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
assume fs:nothing,gs:nothing
; Set LOOP_UNROLL_SHIFT to the log2 of the number of times you want loops in
; this module unrolled. For example, LOOP_UNROLL_SHIFT of 3 yields 2**3 = 8
; times unrolling. This is the only thing you need to change to control
; unrolling.
LOOP_UNROLL_SHIFT equ 1
.xlist
include stdcall.inc ;calling convention cmacros
include i386\egavga.inc
include i386\strucs.inc
include i386\driver.inc
include i386\lines.inc
.list
.code
;--------------------------Private-Routine------------------------------;
; vStripSolid0
;
; Draw lines in the 1st half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolid0,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
; Do some initializing:
mov esi, pStrips
push ebp
mov ebp, plStripEnd
mov eax,[esi].ST_lNextScan
mov [ebp],eax ;copy delta
mov eax,[esi].ST_chAndXor
mov bl,ah
mov bh,ah
mov ah,al
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; ax = and mask
; bx = xor mask
; ecx = pixel count
; dx = temporary register
; esi = strip pointer
; edi = display pointer
; ebp = ends of strips pointer
; [ebp] = delta
mov ecx,[esi]
add esi,4
test edi,1
jnz short sol0_unaligned_start
sol0_aligned_loop:
sub ecx,2
jl short sol0_strip_end_unaligned
je short sol0_strip_end_aligned
mov dx,[edi]
and edx,eax
xor edx,ebx
mov [edi],dx
add edi,2
jmp short sol0_aligned_loop
sol0_strip_end_aligned:
mov dx,[edi]
and edx,eax
xor edx,ebx
mov [edi],dx
add edi,2
add edi,[ebp] ;go to next scan
cmp esi,ebp
jae short sol0_all_done
mov ecx,[esi]
add esi,4
jmp short sol0_aligned_loop
sol0_strip_end_unaligned:
mov dl,[edi] ;do last pixel
and dl,al
xor dl,bl
mov [edi],dl
inc edi
add edi,[ebp] ;go to next scan
cmp esi,ebp
jae short sol0_all_done
mov ecx,[esi] ;do first pixel of next strip
add esi,4
sol0_unaligned_start:
mov dl,[edi]
and dl,al
xor dl,bl
mov [edi],dl
inc edi
dec ecx
jnz short sol0_aligned_loop
; Have to be careful when there is only one pel in the strip and it starts
; on an unaligned address:
add edi,[ebp]
cmp esi,ebp
jae short sol0_all_done
mov ecx,[esi]
add esi,4
jmp short sol0_aligned_loop
sol0_all_done:
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolid0
endProc vStripSolid0
;--------------------------Private-Routine------------------------------;
; vStripSolid1
;
; Draws lines in the 2nd half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolid1,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
inc ecx ; Make delta advance 1 to right
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol1_next_diagonal:
mov ebx,[esi]
add esi, 4
sol1_diagonal_loop:
mov dl,[edi]
and dl,al
xor dl,ah
mov [edi],dl
add edi,ecx
dec ebx
jnz short sol1_diagonal_loop
sub edi,ecx
inc edi
cmp esi,ebp
jb short sol1_next_diagonal
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolid1
endProc vStripSolid1
;--------------------------Private-Routine------------------------------;
; vStripSolid2
;
; Draws lines in the 3rd half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolid2,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
inc ecx ; Make delta advance 1 to right
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol2_next_diagonal:
mov ebx,[esi]
add esi,4
sol2_diagonal_loop:
mov dl,[edi]
and dl,al
xor dl,ah
mov [edi],dl
add edi,ecx
dec ebx
jnz short sol2_diagonal_loop
dec edi
cmp esi,ebp
jb short sol2_next_diagonal
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolid2
endProc vStripSolid2
;--------------------------Private-Routine------------------------------;
; vStripSolid3
;
; Draws lines in the 4th half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolid3,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol3_next_vertical:
mov ebx,[esi]
add esi,4
sol3_vertical_loop:
mov dl,[edi]
and dl,al
xor dl,ah
mov [edi],dl
add edi,ecx
dec ebx
jnz short sol3_vertical_loop
inc edi
cmp esi,ebp
jb short sol3_next_vertical
pop ebp
mov esi,pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolid3
endProc vStripSolid3
;--------------------------Private-Routine------------------------------;
; vStripStyled0
;
; Draws styled lines in the 1st half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripStyled0,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
local ulNumPixels: dword ;# of pixels in current style
local pspEnd: dword ;pointer to end of style array
local cjMajor: dword ;lNextScan for screen
local cjStyleDelta: dword ;delta from end of style array to start
; al = and mask
; ah = xor mask
; ebx = # of pixels in current strip
; ecx = style pointer
; edx = temporary register
; esi = strips pointer
; edi = memory pointer
mov esi,pStrips
mov eax,[esi].ST_lNextScan
mov cjMajor,eax
mov eax,[esi].ST_pspEnd
mov pspEnd,eax
mov ebx,[esi].ST_pspStart
sub ebx,eax ;compute cjStyleDelta
sub ebx,4 ;make it exclusive
mov cjStyleDelta,ebx
mov edx,[esi].ST_spRemaining
mov ulNumPixels,edx
mov eax,[esi].ST_chAndXor
mov ecx,[esi].ST_psp
mov edx,[esi].ST_bIsGap
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
mov ebx,[esi]
add esi,4
or edx,edx
jz short sty0_output_loop ;if working on a dash, start there
jmp short sty0_skip_loop ;if working on a gap, start there
sty0_prepare_for_output:
add edi,ulNumPixels ;adjust to do remainder of strip
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
mov ebx,ulNumPixels
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
neg ebx
jz short sty0_output_get_new_strip
sty0_output_loop:
mov dl,[edi]
and dl,al
xor dl,ah
mov [edi],dl ;write pixel
inc edi ;move one pixel to right
dec ulNumPixels ;might have to go to next style element
jz short sty0_prepare_for_skip
dec ebx
jnz short sty0_output_loop
sty0_output_get_new_strip:
add edi,cjMajor ;move up one scan
cmp esi,plStripEnd
jae short sty0_output_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty0_output_loop
sty0_output_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0 ;we were working on a dash
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyled0
sty0_prepare_for_skip:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
dec ebx
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
jz short sty0_skip_get_new_strip
sty0_skip_loop:
add edi,ebx ;assume we'll skip entire strip
sub ulNumPixels,ebx ; (we'll correct it if not)
jle short sty0_prepare_for_output
sty0_skip_get_new_strip:
add edi,cjMajor ;move up one scan
cmp esi,plStripEnd
jae short sty0_skip_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty0_skip_loop
sty0_skip_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0ffh ;we were working on a gap
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyled0
endProc vStripStyled0
;--------------------------Private-Routine------------------------------;
; vStripStyled123
;
; Draws styled lines in the 2nd, 3rd and 4th half-octants.
;
;-----------------------------------------------------------------------;
cProc vStripStyled123,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
local ulNumPixels: dword ;# of pixels in current style
local pspEnd: dword ;pointer to end of style array
local cjMajor: dword ;delta to go in major direction
local cjMinor: dword ;delta to go in minor direction
local cjStyleDelta: dword ;delta from end of style array to start
; al = and mask
; ah = xor mask
; ebx = # of pixels in current strip
; ecx = style pointer
; edx = temporary register
; esi = strips pointer
; edi = memory pointer
mov esi,pStrips
; If in half-octant 3, cjMajor = cjDelta and cjMinor = 1
; If in half-octant 2, cjMajor = cjDelta + 1 and cjMinor = -1
; If in half-octant 1, cjMajor = cjDelta + 1 and cjMinor = -cjDelta
mov eax,[esi].ST_lNextScan
mov ebx,[esi].ST_flFlips
test ebx,FL_FLIP_HALF
jz short sty3_halfoctant_3
inc eax
mov cjMajor,eax
mov cjMinor,-1
test ebx,FL_FLIP_D
jnz short sty3_done_major_minor_comp
neg eax
inc eax
mov cjMinor,eax
jmp short sty3_done_major_minor_comp
sty3_halfoctant_3:
mov cjMajor,eax
mov cjMinor,1
sty3_done_major_minor_comp:
mov eax,[esi].ST_pspEnd
mov pspEnd,eax
mov ebx,[esi].ST_pspStart
sub ebx,eax ;compute cjStyleDelta
sub ebx,4 ;make it exclusive
mov cjStyleDelta,ebx
mov edx,[esi].ST_spRemaining
mov ulNumPixels,edx
mov eax,[esi].ST_chAndXor
mov ecx,[esi].ST_psp
mov edx,[esi].ST_bIsGap
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
mov ebx,[esi]
add esi,4
or edx,edx
jz short sty3_output_loop ;if working on a dash, start there
jmp short sty3_skip_loop ;if working on a gap, start there
sty3_prepare_for_output:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
mov ebx,ulNumPixels
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
neg ebx ;adjust to do remainder of strip
jz short sty3_output_get_new_strip
sty3_output_loop:
mov dl,[edi]
and dl,al
xor dl,ah
mov [edi],dl ;write pixel
add edi,cjMajor ;move to next scan
dec ulNumPixels ;might have to go to next style element
jz short sty3_prepare_for_skip
dec ebx
jnz short sty3_output_loop
sty3_output_get_new_strip:
add edi,cjMinor ;move one pixel in minor direction
cmp esi,plStripEnd
jae short sty3_output_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty3_output_loop
sty3_output_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0 ;we were working on a dash
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyled123
sty3_prepare_for_skip:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
dec ebx
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
jz short sty3_skip_get_new_strip
sty3_skip_loop:
; compute min(left in strip, left in style)
sub ulNumPixels,ebx ;ulNumPixels = # style - # strip
sbb edx,edx
and edx,ulNumPixels
add ebx,edx ;ebx = min(pels left in strip,
; pels left in style)
mov edx,cjMajor
imul edx,ebx
add edi,edx ;adjust our pointer
cmp ulNumPixels,0
jle sty3_prepare_for_output
sty3_skip_get_new_strip:
add edi,cjMinor ;move one pixel in minor direction
cmp esi,plStripEnd
jae short sty3_skip_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty3_skip_loop
sty3_skip_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0ffh ;we were working on a gap
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyled123
endProc vStripStyled123
;--------------------------Private-Routine------------------------------;
; vStripSolidSet0
;
; Draw lines in the 1st half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolidSet0,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
; Do some initializing:
mov esi, pStrips
push ebp
mov ebp, plStripEnd
mov eax,[esi].ST_lNextScan
mov [ebp],eax ;copy delta
mov eax,[esi].ST_chAndXor
mov bl,ah
mov bh,ah
mov ah,al
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; ax = and mask
; bx = xor mask
; ecx = pixel count
; dx = temporary register
; esi = strip pointer
; edi = display pointer
; ebp = ends of strips pointer
; [ebp] = delta
mov ecx,[esi]
add esi,4
test edi,1
jnz short sol0s_unaligned_start
sol0s_aligned_loop:
sub ecx,2
jl short sol0s_strip_end_unaligned
je short sol0s_strip_end_aligned
mov [edi],bx
add edi,2
jmp short sol0s_aligned_loop
sol0s_strip_end_aligned:
mov [edi],bx
add edi,2
add edi,[ebp] ;go to next scan
cmp esi,ebp
jae short sol0s_all_done
mov ecx,[esi]
add esi,4
jmp short sol0s_aligned_loop
sol0s_strip_end_unaligned:
mov [edi],bl ;do last pixel
inc edi
add edi,[ebp] ;go to next scan
cmp esi,ebp
jae short sol0s_all_done
mov ecx,[esi] ;do first pixel of next strip
add esi,4
sol0s_unaligned_start:
mov [edi],bl
inc edi
dec ecx
jnz short sol0s_aligned_loop
; Have to be careful when there is only one pel in the strip and it starts
; on an unaligned address:
add edi,[ebp]
cmp esi,ebp
jae short sol0s_all_done
mov ecx,[esi]
add esi,4
jmp short sol0s_aligned_loop
sol0s_all_done:
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolidSet0
endProc vStripSolidSet0
;--------------------------Private-Routine------------------------------;
; vStripSolidSet1
;
; Draws lines in the 2nd half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolidSet1,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
inc ecx ; Make delta advance 1 to right
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol1s_next_diagonal:
mov ebx,[esi]
add esi, 4
sol1s_diagonal_loop:
mov [edi],ah
add edi,ecx
dec ebx
jnz short sol1s_diagonal_loop
sub edi,ecx
inc edi
cmp esi,ebp
jb short sol1s_next_diagonal
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolidSet1
endProc vStripSolidSet1
;--------------------------Private-Routine------------------------------;
; vStripSolidSet2
;
; Draws lines in the 3rd half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolidSet2,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
inc ecx ; Make delta advance 1 to right
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol2s_next_diagonal:
mov ebx,[esi]
add esi,4
sol2s_diagonal_loop:
mov [edi],ah
add edi,ecx
dec ebx
jnz short sol2s_diagonal_loop
dec edi
cmp esi,ebp
jb short sol2s_next_diagonal
pop ebp
mov esi, pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolidSet2
endProc vStripSolidSet2
;--------------------------Private-Routine------------------------------;
; vStripSolidSet3
;
; Draws lines in the 4th half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripSolidSet3,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
mov esi,pStrips
push ebp
mov ebp,plStripEnd
mov ecx,[esi].ST_lNextScan
mov eax,[esi].ST_chAndXor
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
; al = and mask
; ah = xor mask
; ebx = pixel count
; ecx = delta
; dl = temporary register
; esi = strip pointer
; edi = memory pointer
; ebp = end of strips pointer
sol3s_next_vertical:
mov ebx,[esi]
add esi,4
sol3s_vertical_loop:
mov [edi],ah
add edi,ecx
dec ebx
jnz short sol3s_vertical_loop
inc edi
cmp esi,ebp
jb short sol3s_next_vertical
pop ebp
mov esi,pStrips
mov [esi].ST_pjScreen,edi
cRet vStripSolidSet3
endProc vStripSolidSet3
;--------------------------Private-Routine------------------------------;
; vStripStyledSet0
;
; Draws styled lines in the 1st half-octant.
;
;-----------------------------------------------------------------------;
cProc vStripStyledSet0,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
local ulNumPixels: dword ;# of pixels in current style
local pspEnd: dword ;pointer to end of style array
local cjMajor: dword ;lNextScan for screen
local cjStyleDelta: dword ;delta from end of style array to start
; al = and mask
; ah = xor mask
; ebx = # of pixels in current strip
; ecx = style pointer
; edx = temporary register
; esi = strips pointer
; edi = memory pointer
mov esi,pStrips
mov eax,[esi].ST_lNextScan
mov cjMajor,eax
mov eax,[esi].ST_pspEnd
mov pspEnd,eax
mov ebx,[esi].ST_pspStart
sub ebx,eax ;compute cjStyleDelta
sub ebx,4 ;make it exclusive
mov cjStyleDelta,ebx
mov edx,[esi].ST_spRemaining
mov ulNumPixels,edx
mov eax,[esi].ST_chAndXor
mov ecx,[esi].ST_psp
mov edx,[esi].ST_bIsGap
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
mov ebx,[esi]
add esi,4
or edx,edx
jz short sty0s_output_loop ;if working on a dash, start there
jmp short sty0s_skip_loop ;if working on a gap, start there
sty0s_prepare_for_output:
add edi,ulNumPixels ;adjust to do remainder of strip
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
mov ebx,ulNumPixels
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
neg ebx ;see if we also need a new strip
jz short sty0s_output_get_new_strip
sty0s_output_loop:
mov [edi],ah ;write pixel
inc edi ;move one pixel to right
dec ulNumPixels ;might have to go to next style element
jz short sty0s_prepare_for_skip
dec ebx
jnz short sty0s_output_loop
sty0s_output_get_new_strip:
add edi,cjMajor ;move up one scan
cmp esi,plStripEnd
jae short sty0s_output_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty0s_output_loop
sty0s_output_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0 ;we were working on a dash
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyledSet0
sty0s_prepare_for_skip:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
dec ebx
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
jz short sty0s_skip_get_new_strip
sty0s_skip_loop:
add edi,ebx ;assume we'll skip entire strip
sub ulNumPixels,ebx ; (we'll correct it if not)
jle short sty0s_prepare_for_output
sty0s_skip_get_new_strip:
add edi,cjMajor ;move up one scan
cmp esi,plStripEnd
jae short sty0s_skip_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty0s_skip_loop
sty0s_skip_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0ffh ;we were working on a gap
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyledSet0
endProc vStripStyledSet0
;--------------------------Private-Routine------------------------------;
; vStripStyledSet123
;
; Draws styled lines in the 2nd, 3rd and 4th half-octants.
;
;-----------------------------------------------------------------------;
cProc vStripStyledSet123,12,< \
uses esi edi ebx, \
pStrips: ptr STRIPS, \
pls: ptr LINESTATE, \
plStripEnd: ptr >
local ulNumPixels: dword ;# of pixels in current style
local pspEnd: dword ;pointer to end of style array
local cjMajor: dword ;delta to go in major direction
local cjMinor: dword ;delta to go in minor direction
local cjStyleDelta: dword ;delta from end of style array to start
; al = and mask
; ah = xor mask
; ebx = # of pixels in current strip
; ecx = style pointer
; edx = temporary register
; esi = strips pointer
; edi = memory pointer
mov esi,pStrips
; If in half-octant 3, cjMajor = cjDelta and cjMinor = 1
; If in half-octant 2, cjMajor = cjDelta + 1 and cjMinor = -1
; If in half-octant 1, cjMajor = cjDelta + 1 and cjMinor = -cjDelta
mov eax,[esi].ST_lNextScan
mov ebx,[esi].ST_flFlips
test ebx,FL_FLIP_HALF
jz short sty3s_halfoctant_3
inc eax
mov cjMajor,eax
mov cjMinor,-1
test ebx,FL_FLIP_D
jnz short sty3s_done_major_minor_comp
neg eax
inc eax
mov cjMinor,eax
jmp short sty3s_done_major_minor_comp
sty3s_halfoctant_3:
mov cjMajor,eax
mov cjMinor,1
sty3s_done_major_minor_comp:
mov eax,[esi].ST_pspEnd
mov pspEnd,eax
mov ebx,[esi].ST_pspStart
sub ebx,eax ;compute cjStyleDelta
sub ebx,4 ;make it exclusive
mov cjStyleDelta,ebx
mov edx,[esi].ST_spRemaining
mov ulNumPixels,edx
mov eax,[esi].ST_chAndXor
mov ecx,[esi].ST_psp
mov edx,[esi].ST_bIsGap
mov edi,[esi].ST_pjScreen
add esi,offset ST_alStrips
mov ebx,[esi]
add esi,4
or edx,edx
jz short sty3s_output_loop ;if working on a dash, start there
jmp short sty3s_skip_loop ;if working on a gap, start there
sty3s_prepare_for_output:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
mov ebx,ulNumPixels
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
neg ebx ;adjust to do remainder of strip
jz short sty3s_output_get_new_strip
sty3s_output_loop:
mov [edi],ah ;write pixel
add edi,cjMajor ;move to next scan
dec ulNumPixels ;might have to go to next style element
jz short sty3s_prepare_for_skip
dec ebx
jnz short sty3s_output_loop
sty3s_output_get_new_strip:
add edi,cjMinor ;move in minor direction
cmp esi,plStripEnd
jae short sty3s_output_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty3s_output_loop
sty3s_output_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0 ;we were working on a dash
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyledSet123
sty3s_prepare_for_skip:
add ecx,4
cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
sbb edx,edx ; then ecx = pspStart
and edx,cjStyleDelta
add ecx,edx
dec ebx
push eax
mov eax,[ecx] ;get next style array element
mov ulNumPixels,eax
pop eax
jz short sty3s_skip_get_new_strip
sty3s_skip_loop:
; compute min(left in strip, left in style)
sub ulNumPixels,ebx ;ulNumPixels = # style - # strip
sbb edx,edx
and edx,ulNumPixels
add ebx,edx ;ebx = min(pels left in strip,
; pels left in style)
mov edx,cjMajor
imul edx,ebx
add edi,edx ;adjust our pointer
cmp ulNumPixels,0
jle sty3s_prepare_for_output
sty3s_skip_get_new_strip:
add edi,cjMinor ;move in minor direction
cmp esi,plStripEnd
jae short sty3s_skip_all_done
mov ebx,[esi] ;get next strip
add esi,4
jmp short sty3s_skip_loop
sty3s_skip_all_done:
mov esi,pStrips
mov [esi].ST_pjScreen,edi
mov [esi].ST_bIsGap,0ffh ;we were working on a gap
mov edi,ulNumPixels
mov [esi].ST_spRemaining,edi
mov [esi].ST_psp,ecx
cRet vStripStyledSet123
endProc vStripStyledSet123
end