112 lines
5.3 KiB
Markdown
112 lines
5.3 KiB
Markdown
------------------------ --------------------------------- --------------------
|
||
[Previous](41-02.html) [Table of Contents](index.html) [Next](41-04.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
**LISTING 41.3 L41-3.ASM**
|
||
|
||
; Draws all pixels in list of horizontal lines passed in, in mode 13h, VGA’s
|
||
; 320x200 256-color mode. Uses REP STOS to fill each line.
|
||
; ******************************************************************
|
||
; NOTE: is able to reverse the X coords for a scan line, if necessary, to make
|
||
; XStart < XEnd. Expects whichever edge is rightmost on any scan line to be in
|
||
; +1 format; that is, XEnd is 1 greater than rightmost pixel to draw. If
|
||
; XStart == XEnd, nothing is drawn on that scan line.
|
||
; ******************************************************************
|
||
; C near-callable as:
|
||
; void DrawHorizontalLineList(struct HLineList * HLineListPtr, int Color);
|
||
; All assembly code tested with TASM and MASM
|
||
|
||
SCREEN_WIDTH equ 320
|
||
SCREEN_SEGMENT equ 0a000h
|
||
|
||
HLine struc
|
||
XStart dw ? ;X coordinate of leftmost pixel in line
|
||
XEnd dw ? ;X coordinate of rightmost pixel in line
|
||
HLine ends
|
||
|
||
HLineList struc
|
||
Lngth dw ? ;# of horizontal lines
|
||
YStart dw ? ;Y coordinate of topmost line
|
||
HLinePtr dw ? ;pointer to list of horz lines
|
||
HLineList ends
|
||
|
||
Parms struc
|
||
dw 2 dup(?) ;return address & pushed BP
|
||
HLineListPtr dw ? ;pointer to HLineList structure
|
||
Color dw ? ;color with which to fill
|
||
Parms ends
|
||
.model small
|
||
.code
|
||
public _DrawHorizontalLineList
|
||
align 2
|
||
_DrawHorizontalLineList proc
|
||
push bp ;preserve caller’s stack frame
|
||
mov bp,sp ;point to our stack frame
|
||
push si ;preserve caller’s register variables
|
||
push di
|
||
cld ;make string instructions inc pointers
|
||
|
||
mov ax,SCREEN_SEGMENT
|
||
mov es,ax ;point ES to display memory for REP STOS
|
||
|
||
mov si,[bp+HLineListPtr] ;point to the line list
|
||
mov ax,SCREEN_WIDTH ;point to the start of the first scan
|
||
mul [si+YStart] ; line in which to draw
|
||
mov dx,ax ;ES:DX points to first scan line to draw
|
||
mov bx,[si+HLinePtr] ;point to the XStart/XEnd descriptor
|
||
; for the first (top) horizontal line
|
||
mov si,[si+Lngth] ;# of scan lines to draw
|
||
and si,si ;are there any lines to draw?
|
||
jz FillDone ;no, so we’re done
|
||
mov al,byte ptr [bp+Color] ;color with which to fill
|
||
mov ah,al ;duplicate color for STOSW
|
||
FillLoop:
|
||
mov di,[bx+XStart] ;left edge of fill on this line
|
||
mov cx,[bx+XEnd] ;right edge of fill
|
||
cmp di,cx ;is XStart > XEnd?
|
||
jle NoSwap ;no, we’re all set
|
||
xchg di,cx ;yes, so swap edges
|
||
NoSwap:
|
||
sub cx,di ;width of fill on this line
|
||
jz LineFillDone ;skip if zero width
|
||
add di,dx ;offset of left edge of fill
|
||
test di,1 ;does fill start at an odd address?
|
||
jz MainFill ;no
|
||
stosb ;yes, draw the odd leading byte to
|
||
; word-align the rest of the fill
|
||
dec cx ;count off the odd leading byte
|
||
jz LineFillDone ;done if that was the only byte
|
||
MainFill:
|
||
shr cx,1 ;# of words in fill
|
||
rep stosw ;fill as many words as possible
|
||
adc cx,cx ;1 if there’s an odd trailing byte to
|
||
; do, 0 otherwise
|
||
rep stosb ;fill any odd trailing byte
|
||
LineFillDone:
|
||
add bx,size HLine ;point to the next line descriptor
|
||
add dx,SCREEN_WIDTH ;point to the next scan line
|
||
dec si ;count off lines to fill
|
||
jnz FillLoop
|
||
FillDone:
|
||
pop di ;restore caller’s register variables
|
||
pop si
|
||
pop bp ;restore caller’s stack frame
|
||
ret
|
||
_DrawHorizontalLineList endp
|
||
end
|
||
|
||
Listing 41.4 is almost identical to Listing 40.1 from Chapter 40. I’ve
|
||
modified Listing 40.1 to employ the vertical-monotone detection test
|
||
we’ve been talking about and use the fast vertical-monotone drawing code
|
||
whenever possible; that’s what Listing 41.4 is. Note well that Listing
|
||
40.5 from Chapter 40 is also required in order for this code to link.
|
||
Listing 41.5 is an appropriately updated version of the POLYGON.H header
|
||
file.
|
||
|
||
------------------------ --------------------------------- --------------------
|
||
[Previous](41-02.html) [Table of Contents](index.html) [Next](41-04.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
* * * * *
|
||
|
||
Graphics Programming Black Book © 2001 Michael Abrash
|