160 lines
6.5 KiB
HTML
160 lines
6.5 KiB
HTML
<HTML>
|
|
<HEAD>
|
|
<META name=vsisbn content="1576101746">
|
|
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
|
<META name=vsauthor content="Michael Abrash">
|
|
<META name=vspublisher content="The Coriolis Group">
|
|
<META name=vspubdate content="07/01/97">
|
|
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Those Way-Down Polygon Nomenclature Blues</TITLE>
|
|
|
|
<!-- HEADER -->
|
|
<!-- Empty Reference Subhead -->
|
|
|
|
<!--ISBN=1576101746//-->
|
|
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
|
<!--AUTHOR=Michael Abrash//-->
|
|
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
|
<!--CHAPTER=41//-->
|
|
<!--PAGES=764-766//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="41-02.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="41-04.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P><B>LISTING 41.3 L41-3.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
; 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
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>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.
|
|
</P><P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="41-02.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="41-04.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
|
|
<hr width="90%" size="1" noshade>
|
|
<div align="center">
|
|
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
|
</div>
|
|
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
|
<!-- reference_subfoot = footer -->
|
|
<!-- reference_footer = subfoot -->
|
|
|
|
<!-- BEGIN SUB FOOTER -->
|
|
</BODY>
|
|
</HTML>
|
|
|
|
<!-- END FOOTER -->
|
|
|
|
|