Change HTML4 entities to HTML5

&lt to <
&gt to >
&amp to &
This commit is contained in:
James Gregory 2013-12-30 14:33:39 +11:00
commit b8e7ce7165
105 changed files with 1117 additions and 1117 deletions

View file

@ -120,7 +120,7 @@ IRR equ20h
MPOPF macro MPOPF macro
local p1, p2 local p1, p2
jmp short p2 jmp short p2
p1: iret ; jump to pushed address &amp pop flags p1: iret ; jump to pushed address & pop flags
p2: push cs ; construct far return address to p2: push cs ; construct far return address to
call p1 ; the next instruction call p1 ; the next instruction
endm endm

View file

@ -117,7 +117,7 @@ pztime LST3-3.ASM
<P>In order to perform any of the timing tests in this book, enter Listing 3.1 and name it PZTIMER.ASM, enter Listing 3.2 and name it PZTEST.ASM, and enter Listing 3.4 and name it PZTIME.BAT. Then simply enter the listing you wish to run into the file <I>filename</I> and enter the command:</P> <P>In order to perform any of the timing tests in this book, enter Listing 3.1 and name it PZTIMER.ASM, enter Listing 3.2 and name it PZTEST.ASM, and enter Listing 3.4 and name it PZTIME.BAT. Then simply enter the listing you wish to run into the file <I>filename</I> and enter the command:</P>
<!-- CODE SNIP //--> <!-- CODE SNIP //-->
<PRE> <PRE>
pztime &ltfilename&gt pztime &lt;filename&gt;
</PRE> </PRE>
<!-- END CODE SNIP //--> <!-- END CODE SNIP //-->
<P>In fact, that&rsquo;s exactly how I timed each of the listings in this book. Code fragments you write yourself can be timed in just the same way. If you wish to time code directly in place in your programs, rather than in the test-bed program of Listing 3.2, simply insert calls to <B>ZTimerOn, ZTimerOff</B>, and <B>ZTimerReport</B> in the appropriate places and link PZTIMER to your program.</P> <P>In fact, that&rsquo;s exactly how I timed each of the listings in this book. Code fragments you write yourself can be timed in just the same way. If you wish to time code directly in place in your programs, rather than in the test-bed program of Listing 3.2, simply insert calls to <B>ZTimerOn, ZTimerOff</B>, and <B>ZTimerReport</B> in the appropriate places and link PZTIMER to your program.</P>

View file

@ -176,7 +176,7 @@ TIMER_COUNT equ46ch
MPOPF macro MPOPF macro
local p1, p2 local p1, p2
jmp short p2 jmp short p2
p1: iret ;jump to pushed address &amp pop flags p1: iret ;jump to pushed address &amp; pop flags
p2: pushcs ;construct far return address to p2: pushcs ;construct far return address to
call p1 ; the next instruction call p1 ; the next instruction
endm endm

View file

@ -41,7 +41,7 @@
<!-- CODE SNIP //--> <!-- CODE SNIP //-->
<PRE> <PRE>
ZTimerOn(): ZTimerOn():
for (i=0, x=0; i&lt100; i++) for (i=0, x=0; i&lt;100; i++)
x += i; x += i;
ZTimerOff(); ZTimerOff();
ZTimerReport(); ZTimerReport();

View file

@ -59,8 +59,8 @@
; ;
mov ax,0a000h mov ax,0a000h
mov ds,ax mov ds,ax
mov es,ax ;move to &amp from same segment mov es,ax ;move to &amp; from same segment
sub si,si ;move to &amp from same offset sub si,si ;move to &amp; from same offset
mov di,si mov di,si
mov cx,800h ;move 2K words mov cx,800h ;move 2K words
cld cld
@ -86,8 +86,8 @@
; memory. ; memory.
; ;
mov ax,ds mov ax,ds
mov es,ax ;move to &amp from same segment mov es,ax ;move to &amp; from same segment
sub si,si ;move to &amp from same offset sub si,si ;move to &amp; from same offset
mov di,si mov di,si
mov cx,800h ;move 2K words mov cx,800h ;move 2K words
cld cld

View file

@ -44,10 +44,10 @@
* argument. Performs the search by reading and searching blocks * argument. Performs the search by reading and searching blocks
* of size BLOCK_SIZE. */ * of size BLOCK_SIZE. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltfcntl.h&gt #include &lt;fcntl.h&gt;
#include &ltstring.h&gt #include &lt;string.h&gt;
#include &ltalloc.h&gt /* alloc.h for Borland compilers, #include &lt;alloc.h&gt; /* alloc.h for Borland compilers,
malloc.h for Microsoft compilers */ malloc.h for Microsoft compilers */
#define BLOCK_SIZE 0x4000 /* we&rsquo;ll process the file in 16K blocks */ #define BLOCK_SIZE 0x4000 /* we&rsquo;ll process the file in 16K blocks */
@ -164,7 +164,7 @@ main(int argc, char *argv[]) {
when that block is searched) when that block is searched)
*/ */
if ( (BlockSearchLength = if ( (BlockSearchLength =
WorkingLength - SearchStringLength + 1) &lt= 0 ) { WorkingLength - SearchStringLength + 1) &lt;= 0 ) {
Done = 1; /* Too few characters in this block for Done = 1; /* Too few characters in this block for
there to be any possible matches, so this there to be any possible matches, so this
is the final block and we&rsquo;re done without is the final block and we&rsquo;re done without
@ -182,7 +182,7 @@ main(int argc, char *argv[]) {
/* Copy any bytes from the end of the block that start /* Copy any bytes from the end of the block that start
potentially-matching sequences that would run off potentially-matching sequences that would run off
the end of the block over to the next block */ the end of the block over to the next block */
if ( SearchStringLength &gt 1 ) { if ( SearchStringLength &gt; 1 ) {
memcpy(WorkingBlock, memcpy(WorkingBlock,
WorkingBlock+BLOCK_SIZE - SearchStringLength + 1, WorkingBlock+BLOCK_SIZE - SearchStringLength + 1,
SearchStringLength - 1); SearchStringLength - 1);

View file

@ -98,7 +98,7 @@ Startendp
; specified byte or a zero byte is encountered. ; specified byte or a zero byte is encountered.
; Input: ; Input:
; AH = character to search for ; AH = character to search for
; CX = maximum length to be searched (must be &gt 0) ; CX = maximum length to be searched (must be &gt; 0)
; DS:SI = pointer to buffer to be searched ; DS:SI = pointer to buffer to be searched
; Output: ; Output:
; CX = 0 if and only if we ran out of bytes without finding ; CX = 0 if and only if we ran out of bytes without finding

View file

@ -106,7 +106,7 @@ Startendp
; specified byte or a zero byte is encountered. ; specified byte or a zero byte is encountered.
; Input: ; Input:
; AH = character to search for ; AH = character to search for
; CX = maximum length to be searched (must be &gt 0) ; CX = maximum length to be searched (must be &gt; 0)
; DS:SI = pointer to buffer to be searched ; DS:SI = pointer to buffer to be searched
; Output: ; Output:
; CX = 0 if and only if we ran out of bytes without finding ; CX = 0 if and only if we ran out of bytes without finding

View file

@ -45,11 +45,11 @@
the variable-sized blocks may contain any number of data entries, the variable-sized blocks may contain any number of data entries,
stored as an array of structures within the block. */ stored as an array of structures within the block. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#ifdef __TURBOC__ #ifdef __TURBOC__
#include &ltalloc.h&gt #include &lt;alloc.h&gt;
#else #else
#include &ltmalloc.h&gt #include &lt;malloc.h&gt;
#endif #endif
void main(void); void main(void);
@ -78,12 +78,12 @@ void main(void) {
struct BlockHeader **LastBlockPointer; struct BlockHeader **LastBlockPointer;
printf(&rdquo;ID # for which to find average: &ldquo;); printf(&rdquo;ID # for which to find average: &ldquo;);
scanf(&rdquo;%d&rdquo;,&ampIDToFind); scanf(&rdquo;%d&rdquo;,&amp;IDToFind);
/* Build an array across 5 blocks, for testing */ /* Build an array across 5 blocks, for testing */
/* Anchor the linked list to BaseArrayBlockPointer */ /* Anchor the linked list to BaseArrayBlockPointer */
LastBlockPointer = &ampBaseArrayBlockPointer; LastBlockPointer = &amp;BaseArrayBlockPointer;
/* Create 5 blocks of varying sizes */ /* Create 5 blocks of varying sizes */
for (i = 1; i &lt 6; i++) { for (i = 1; i &lt; 6; i++) {
/* Try to get memory for the next block */ /* Try to get memory for the next block */
if ((WorkingBlockPointer = if ((WorkingBlockPointer =
(struct BlockHeader *) malloc(sizeof(struct BlockHeader) + (struct BlockHeader *) malloc(sizeof(struct BlockHeader) +
@ -91,7 +91,7 @@ void main(void) {
exit(1); exit(1);
} }
/* Set the # of data elements in this block */ /* Set the # of data elements in this block */
WorkingBlockPointer-&gtBlockCount = i * 10; WorkingBlockPointer-&gt;BlockCount = i * 10;
/* Link the new block into the chain */ /* Link the new block into the chain */
*LastBlockPointer = WorkingBlockPointer; *LastBlockPointer = WorkingBlockPointer;
/* Point to the first data field */ /* Point to the first data field */
@ -99,16 +99,16 @@ void main(void) {
(struct DataElement *) ((char *)WorkingBlockPointer + (struct DataElement *) ((char *)WorkingBlockPointer +
sizeof(struct BlockHeader)); sizeof(struct BlockHeader));
/* Fill the data fields with ID numbers and values */ /* Fill the data fields with ID numbers and values */
for (j = 0; j &lt (i * 10); j++, WorkingDataPointer++) { for (j = 0; j &lt; (i * 10); j++, WorkingDataPointer++) {
WorkingDataPointer-&gtID = j; WorkingDataPointer-&gt;ID = j;
WorkingDataPointer-&gtValue = i * 1000 + j; WorkingDataPointer-&gt;Value = i * 1000 + j;
} }
/* Remember where to set link from this block to the next */ /* Remember where to set link from this block to the next */
LastBlockPointer = &ampWorkingBlockPointer-&gtNextBlock; LastBlockPointer = &amp;WorkingBlockPointer-&gt;NextBlock;
} }
/* Set the last block&rsquo;s &ldquo;next block&rdquo; pointer to NULL to indicate /* Set the last block&rsquo;s &ldquo;next block&rdquo; pointer to NULL to indicate
that there are no more blocks */ that there are no more blocks */
WorkingBlockPointer-&gtNextBlock = NULL; WorkingBlockPointer-&gt;NextBlock = NULL;
printf(&rdquo;Average of all elements with ID %d: %u\n&rdquo;, printf(&rdquo;Average of all elements with ID %d: %u\n&rdquo;,
IDToFind, FindIDAverage(IDToFind, BaseArrayBlockPointer)); IDToFind, FindIDAverage(IDToFind, BaseArrayBlockPointer));
exit(0); exit(0);
@ -140,18 +140,18 @@ unsigned int FindIDAverage(unsigned int SearchedForID,
/* Search all the DataElement entries within this block /* Search all the DataElement entries within this block
and accumulate data from all that match the desired ID */ and accumulate data from all that match the desired ID */
for (WorkingBlockCount=0; for (WorkingBlockCount=0;
WorkingBlockCount&ltBlockPointer-&gtBlockCount; WorkingBlockCount&lt;BlockPointer-&gt;BlockCount;
WorkingBlockCount++, DataPointer++) { WorkingBlockCount++, DataPointer++) {
/* If the ID matches, add in the value and increment the /* If the ID matches, add in the value and increment the
match counter */ match counter */
if (DataPointer-&gtID == SearchedForID) { if (DataPointer-&gt;ID == SearchedForID) {
IDMatchCount++; IDMatchCount++;
IDMatchSum += DataPointer-&gtValue; IDMatchSum += DataPointer-&gt;Value;
} }
} }
/* Point to the next block, and continue as long as that pointer /* Point to the next block, and continue as long as that pointer
isn&rsquo;t NULL */ isn&rsquo;t NULL */
} while ((BlockPointer = BlockPointer-&gtNextBlock) != NULL); } while ((BlockPointer = BlockPointer-&gt;NextBlock) != NULL);
/* Calculate the average of all matches */ /* Calculate the average of all matches */
if (IDMatchCount == 0) if (IDMatchCount == 0)
return(0); /* Avoid division by 0 */ return(0); /* Avoid division by 0 */
@ -170,7 +170,7 @@ unsigned int FindIDAverage(unsigned int SearchedForID,
<PRE> <PRE>
; Code generated by Microsoft C for inner loop of FindIDAverage. ; Code generated by Microsoft C for inner loop of FindIDAverage.
;|*** for (WorkingBlockCount=0; ;|*** for (WorkingBlockCount=0;
;|*** WorkingBlockCount&ltBlockPointer-&gtBlockCount; ;|*** WorkingBlockCount&lt;BlockPointer-&gt;BlockCount;
;|*** WorkingBlockCount++, DataPointer++) { ;|*** WorkingBlockCount++, DataPointer++) {
mov WORD PTR [bp-6],0 ;WorkingBlockCount mov WORD PTR [bp-6],0 ;WorkingBlockCount
mov bx,WORD PTR [bp+6] ;BlockPointer mov bx,WORD PTR [bp+6] ;BlockPointer
@ -181,13 +181,13 @@ unsigned int FindIDAverage(unsigned int SearchedForID,
mov di,WORD PTR [bp-2] ;IDMatchSum mov di,WORD PTR [bp-2] ;IDMatchSum
mov dx,WORD PTR [bp-4] ;IDMatchCount mov dx,WORD PTR [bp-4] ;IDMatchCount
$L20004: $L20004:
;|*** if (DataPointer-&gtID == SearchedForID) { ;|*** if (DataPointer-&gt;ID == SearchedForID) {
mov ax,WORD PTR [si] mov ax,WORD PTR [si]
cmp WORD PTR [bp+4],ax ;SearchedForID cmp WORD PTR [bp+4],ax ;SearchedForID
jne $I265 jne $I265
;|*** IDMatchCount++; ;|*** IDMatchCount++;
inc dx inc dx
;|*** IDMatchSum += DataPointer-&gtValue; ;|*** IDMatchSum += DataPointer-&gt;Value;
add di,WORD PTR [si+2] add di,WORD PTR [si+2]
;|*** } ;|*** }
;|*** } ;|*** }

View file

@ -128,7 +128,7 @@ IntraBlockLoop:
cmp [di+ID],ax ;Do we have an ID match? cmp [di+ID],ax ;Do we have an ID match?
jnz NoMatch ;No match jnz NoMatch ;No match
inc bx ;We have a match; IDMatchCount++; inc bx ;We have a match; IDMatchCount++;
add dx,[di+Value] ;IDMatchSum += DataPointer-&gtValue; add dx,[di+Value] ;IDMatchSum += DataPointer-&gt;Value;
NoMatch: NoMatch:
add di,DATA_ELEMENT_SIZE ;point to the next element add di,DATA_ELEMENT_SIZE ;point to the next element
loop IntraBlockLoop loop IntraBlockLoop
@ -205,12 +205,12 @@ LoopEntryTable label word
dw LoopEntry4,LoopEntry5,LoopEntry6,LoopEntry7 dw LoopEntry4,LoopEntry5,LoopEntry6,LoopEntry7
M_IBL macro P1 M_IBL macro P1
local NoMatch local NoMatch
LoopEntry&ampP1&amp: LoopEntry&amp;P1&amp;:
scasw ;Do we have an ID match? scasw ;Do we have an ID match?
jnz NoMatch ;No match jnz NoMatch ;No match
;We have a match ;We have a match
inc bx ;IDMatchCount++; inc bx ;IDMatchCount++;
add dx,[di] ;IDMatchSum += DataPointer-&gtValue; add dx,[di] ;IDMatchSum += DataPointer-&gt;Value;
NoMatch: NoMatch:
add di,DATA_ELEMENT_SIZE-2 ;point to the next element add di,DATA_ELEMENT_SIZE-2 ;point to the next element
; (SCASW advanced 2 bytes already) ; (SCASW advanced 2 bytes already)

View file

@ -47,11 +47,11 @@
stored in the form of two separate arrays, one for ID numbers and stored in the form of two separate arrays, one for ID numbers and
one for values. */ one for values. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#ifdef __TURBOC__ #ifdef __TURBOC__
#include &ltalloc.h&gt #include &lt;alloc.h&gt;
#else #else
#include &ltmalloc.h&gt #include &lt;malloc.h&gt;
#endif #endif
void main(void); void main(void);
@ -82,13 +82,13 @@ void main(void) {
struct BlockHeader **LastBlockPointer; struct BlockHeader **LastBlockPointer;
printf(&rdquo;ID # for which to find average: &ldquo;); printf(&rdquo;ID # for which to find average: &ldquo;);
scanf(&rdquo;%d&rdquo;,&ampIDToFind); scanf(&rdquo;%d&rdquo;,&amp;IDToFind);
/* Build an array across 5 blocks, for testing */ /* Build an array across 5 blocks, for testing */
/* Anchor the linked list to BaseArrayBlockPointer */ /* Anchor the linked list to BaseArrayBlockPointer */
LastBlockPointer = &ampBaseArrayBlockPointer; LastBlockPointer = &amp;BaseArrayBlockPointer;
/* Create 5 blocks of varying sizes */ /* Create 5 blocks of varying sizes */
for (i = 1; i &lt 6; i++) { for (i = 1; i &lt; 6; i++) {
/* Try to get memory for the next block */ /* Try to get memory for the next block */
if ((WorkingBlockPointer = if ((WorkingBlockPointer =
(struct BlockHeader *) malloc(sizeof(struct BlockHeader) + (struct BlockHeader *) malloc(sizeof(struct BlockHeader) +
@ -96,23 +96,23 @@ void main(void) {
exit(1); exit(1);
} }
/* Set the number of data elements in this block */ /* Set the number of data elements in this block */
WorkingBlockPointer-&gtBlockCount = i * 10; WorkingBlockPointer-&gt;BlockCount = i * 10;
/* Link the new block into the chain */ /* Link the new block into the chain */
*LastBlockPointer = WorkingBlockPointer; *LastBlockPointer = WorkingBlockPointer;
/* Point to the first data field */ /* Point to the first data field */
WorkingDataPointer = (int *) ((char *)WorkingBlockPointer + WorkingDataPointer = (int *) ((char *)WorkingBlockPointer +
sizeof(struct BlockHeader)); sizeof(struct BlockHeader));
/* Fill the data fields with ID numbers and values */ /* Fill the data fields with ID numbers and values */
for (j = 0; j &lt (i * 10); j++, WorkingDataPointer++) { for (j = 0; j &lt; (i * 10); j++, WorkingDataPointer++) {
*WorkingDataPointer = j; *WorkingDataPointer = j;
*(WorkingDataPointer + i * 10) = i * 1000 + j; *(WorkingDataPointer + i * 10) = i * 1000 + j;
} }
/* Remember where to set link from this block to the next */ /* Remember where to set link from this block to the next */
LastBlockPointer = &ampWorkingBlockPointer-&gtNextBlock; LastBlockPointer = &amp;WorkingBlockPointer-&gt;NextBlock;
} }
/* Set the last block&rsquo;s &ldquo;next block&rdquo; pointer to NULL to indicate /* Set the last block&rsquo;s &ldquo;next block&rdquo; pointer to NULL to indicate
that there are no more blocks */ that there are no more blocks */
WorkingBlockPointer-&gtNextBlock = NULL; WorkingBlockPointer-&gt;NextBlock = NULL;
printf(&rdquo;Average of all elements with ID %d: %u\n&rdquo;, printf(&rdquo;Average of all elements with ID %d: %u\n&rdquo;,
IDToFind, FindIDAverage2(IDToFind, BaseArrayBlockPointer)); IDToFind, FindIDAverage2(IDToFind, BaseArrayBlockPointer));
exit(0); exit(0);
@ -168,7 +168,7 @@ IntraBlockLoop:
repnz scasw ;Search for the ID repnz scasw ;Search for the ID
jnz DoNextBlock ;No match, the block is done jnz DoNextBlock ;No match, the block is done
inc bp ;We have a match; IDMatchCount++; inc bp ;We have a match; IDMatchCount++;
add dx,[di+bx-2];IDMatchSum += DataPointer-&gtValue; add dx,[di+bx-2];IDMatchSum += DataPointer-&gt;Value;
; (SCASW has advanced DI 2 bytes) ; (SCASW has advanced DI 2 bytes)
and cx,cx ;Is there more data to search through? and cx,cx ;Is there more data to search through?
jnz IntraBlockLoop ;yes jnz IntraBlockLoop ;yes

View file

@ -140,9 +140,9 @@ _FindStringendp
<P><B>LISTING 9.3 L9-3.C</B></P> <P><B>LISTING 9.3 L9-3.C</B></P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* Program to exercise buffer-search routines in Listings 9.1 &amp 9.2 */ /* Program to exercise buffer-search routines in Listings 9.1 &amp; 9.2 */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltstring.h&gt #include &lt;string.h&gt;
#define DISPLAY_LENGTH 40 #define DISPLAY_LENGTH 40
extern unsigned char * FindString(unsigned char *, unsigned int, extern unsigned char * FindString(unsigned char *, unsigned int,

View file

@ -71,7 +71,7 @@ _sort: pop dx ;get return address (entry point)
dec cx ;decrement count dec cx ;decrement count
push cx ;save count push cx ;save count
push dx ;restore return address push dx ;restore return address
jg top ;if cx &gt 0 jg top ;if cx &gt; 0
ret ret

View file

@ -50,7 +50,7 @@
; Tested with TASM 2. ; Tested with TASM 2.
parms struc parms struc
dw 2 dup (?) ;pushed BP &amp return address dw 2 dup (?) ;pushed BP &amp; return address
Dividend dw ? ;pointer to value to divide, stored in Intel Dividend dw ? ;pointer to value to divide, stored in Intel
; order, with lsb at lowest address, msb at ; order, with lsb at lowest address, msb at
; highest. Must be composed of an integral ; highest. Must be composed of an integral
@ -113,7 +113,7 @@ _Divendp
/* Sample use of Div function to perform division when the result /* Sample use of Div function to perform division when the result
doesn&rsquo;t fit in 16 bits */ doesn&rsquo;t fit in 16 bits */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
extern unsigned int Div(unsigned int * Dividend, extern unsigned int Div(unsigned int * Dividend,
int DividendLength, unsigned int Divisor, int DividendLength, unsigned int Divisor,
@ -123,7 +123,7 @@ main() {
unsigned long m, i = 0x20000001; unsigned long m, i = 0x20000001;
unsigned int k, j = 0x10; unsigned int k, j = 0x10;
k = Div((unsigned int *)&ampi, sizeof(i), j, (unsigned int *)&ampm); k = Div((unsigned int *)&amp;i, sizeof(i), j, (unsigned int *)&amp;m);
printf(&ldquo;%lu / %u = %lu r %u\n&rdquo;, i, j, m, k); printf(&ldquo;%lu / %u = %lu r %u\n&rdquo;, i, j, m, k);
} }
</PRE> </PRE>

View file

@ -47,7 +47,7 @@
<P>The floor really did look amazing. It was actually all white; the black lines had been grooves filled with dirt. We assured her that it looked terrific, it just wasn&rsquo;t that obvious until you knew to look for it; anyone would tell you that it wasn&rsquo;t the kind of thing that jumped out at you, but it really was great, no kidding. We had almost smoothed things over, when a friend walked in, looked around with a start, and said, &ldquo;Hey! Did you guys put in a new floor?&rdquo;</P> <P>The floor really did look amazing. It was actually all white; the black lines had been grooves filled with dirt. We assured her that it looked terrific, it just wasn&rsquo;t that obvious until you knew to look for it; anyone would tell you that it wasn&rsquo;t the kind of thing that jumped out at you, but it really was great, no kidding. We had almost smoothed things over, when a friend walked in, looked around with a start, and said, &ldquo;Hey! Did you guys put in a new floor?&rdquo;</P>
<P>As I said, sometimes everything you need to know is right in front of your nose. Which brings us to Boyer-Moore string searching.</P> <P>As I said, sometimes everything you need to know is right in front of your nose. Which brings us to Boyer-Moore string searching.</P>
<H3><A NAME="Heading3"></A>String Searching Refresher</H3> <H3><A NAME="Heading3"></A>String Searching Refresher</H3>
<P>I&rsquo;ve discussed string searching earlier in this book, in Chapters 5 and 9. You may want to refer back to these chapters for some background on string searching in general. I&rsquo;m also going to use some of the code from that chapter as part of this chapter&rsquo;s test suite. For further information, you may want to refer to the discussion of string searching in the excellent <I>Algorithms in C,</I> by Robert Sedgewick (Addison-Wesley), which served as the primary reference for this chapter. (If you look at Sedgewick, be aware that in the Boyer-Moore listing on page 288, there is a mistake: &ldquo;j &gt 0&rdquo; in the <B>for</B> loop should be &ldquo;j &gt= 0,&rdquo; unless I&rsquo;m missing something.)</P> <P>I&rsquo;ve discussed string searching earlier in this book, in Chapters 5 and 9. You may want to refer back to these chapters for some background on string searching in general. I&rsquo;m also going to use some of the code from that chapter as part of this chapter&rsquo;s test suite. For further information, you may want to refer to the discussion of string searching in the excellent <I>Algorithms in C,</I> by Robert Sedgewick (Addison-Wesley), which served as the primary reference for this chapter. (If you look at Sedgewick, be aware that in the Boyer-Moore listing on page 288, there is a mistake: &ldquo;j &gt; 0&rdquo; in the <B>for</B> loop should be &ldquo;j &gt;= 0,&rdquo; unless I&rsquo;m missing something.)</P>
<P>String searching is the simple matter of finding the first occurrence of a particular sequence of bytes (the pattern) within another sequence of bytes (the buffer). The obvious, brute-force approach is to try every possible match location, starting at the beginning of the buffer and advancing one position after each mismatch, until either a match is found or the buffer is exhausted. There&rsquo;s even a nifty string instruction, <B>REPZ CMPS,</B> that&rsquo;s perfect for comparing the pattern to the contents of the buffer at each location. What could be simpler?</P> <P>String searching is the simple matter of finding the first occurrence of a particular sequence of bytes (the pattern) within another sequence of bytes (the buffer). The obvious, brute-force approach is to try every possible match location, starting at the beginning of the buffer and advancing one position after each mismatch, until either a match is found or the buffer is exhausted. There&rsquo;s even a nifty string instruction, <B>REPZ CMPS,</B> that&rsquo;s perfect for comparing the pattern to the contents of the buffer at each location. What could be simpler?</P>
<P>We have some important information that we&rsquo;re not yet using, though. Typically, the buffer will contain a wide variety of bytes. Let&rsquo;s assume that the buffer contains text, in which case there will be dozens of different characters; and although the distribution of characters won&rsquo;t usually be even, neither will any one character constitute half the buffer, or anything close. A reasonable conclusion is that the first character of the pattern will rarely match the first character of the buffer location currently being checked. This allows us to use the speedy <B>REPNZ SCASB</B> to whiz through the buffer, eliminating most potential match locations with single repetitions of <B>SCASB.</B> Only when that first character does (infrequently) match must we drop back to the slower <B>REPZ CMPS</B> approach.</P> <P>We have some important information that we&rsquo;re not yet using, though. Typically, the buffer will contain a wide variety of bytes. Let&rsquo;s assume that the buffer contains text, in which case there will be dozens of different characters; and although the distribution of characters won&rsquo;t usually be even, neither will any one character constitute half the buffer, or anything close. A reasonable conclusion is that the first character of the pattern will rarely match the first character of the buffer location currently being checked. This allows us to use the speedy <B>REPNZ SCASB</B> to whiz through the buffer, eliminating most potential match locations with single repetitions of <B>SCASB.</B> Only when that first character does (infrequently) match must we drop back to the slower <B>REPZ CMPS</B> approach.</P>
<P>It&rsquo;s important to understand that we&rsquo;re assuming that the buffer is typical text. That&rsquo;s what I meant at the outset, when I said that the information you need may be under your nose.</P> <P>It&rsquo;s important to understand that we&rsquo;re assuming that the buffer is typical text. That&rsquo;s what I meant at the outset, when I said that the information you need may be under your nose.</P>

View file

@ -54,7 +54,7 @@
<TD VALIGN="TOP" ALIGN="LEFT">(16K) <TD VALIGN="TOP" ALIGN="LEFT">(16K)
<TD VALIGN="TOP" ALIGN="LEFT">(16K) <TD VALIGN="TOP" ALIGN="LEFT">(16K)
<TD VALIGN="TOP" ALIGN="LEFT">(16K) <TD VALIGN="TOP" ALIGN="LEFT">(16K)
<TD VALIGN="TOP" ALIGN="LEFT">(&lt1K) <TD VALIGN="TOP" ALIGN="LEFT">(&lt;1K)
<TD VALIGN="TOP" ALIGN="LEFT">(16K) <TD VALIGN="TOP" ALIGN="LEFT">(16K)
<TD VALIGN="TOP" ALIGN="LEFT">(16K) <TD VALIGN="TOP" ALIGN="LEFT">(16K)
<TR> <TR>
@ -98,7 +98,7 @@
<TD VALIGN="TOP" ALIGN="LEFT">4.0 <TD VALIGN="TOP" ALIGN="LEFT">4.0
<TD VALIGN="TOP" ALIGN="LEFT">2.0 <TD VALIGN="TOP" ALIGN="LEFT">2.0
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">&lt=255 pattern length + sentinelBoyer-Moore in ASM(Listing 14.4) <TD VALIGN="TOP" ALIGN="LEFT">&lt;=255 pattern length + sentinelBoyer-Moore in ASM(Listing 14.4)
<TD VALIGN="TOP" ALIGN="LEFT">8.1 <TD VALIGN="TOP" ALIGN="LEFT">8.1
<TD VALIGN="TOP" ALIGN="LEFT">5.2 <TD VALIGN="TOP" ALIGN="LEFT">5.2
<TD VALIGN="TOP" ALIGN="LEFT">4.6 <TD VALIGN="TOP" ALIGN="LEFT">4.6

View file

@ -46,7 +46,7 @@
no match is found. no match is found.
Tested with Borland C++ in C mode and the small model. */ Tested with Borland C++ in C mode and the small model. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
unsigned char * FindString(unsigned char * BufferPtr, unsigned char * FindString(unsigned char * BufferPtr,
unsigned int BufferLength, unsigned char * PatternPtr, unsigned int BufferLength, unsigned char * PatternPtr,
@ -57,7 +57,7 @@ unsigned char * FindString(unsigned char * BufferPtr,
int i; int i;
/* Reject if the buffer is too small */ /* Reject if the buffer is too small */
if (BufferLength &lt PatternLength) return(NULL); if (BufferLength &lt; PatternLength) return(NULL);
/* Return an instant match if the pattern is 0-length */ /* Return an instant match if the pattern is 0-length */
if (PatternLength == 0) return(BufferPtr); if (PatternLength == 0) return(BufferPtr);
@ -66,7 +66,7 @@ unsigned char * FindString(unsigned char * BufferPtr,
mismatches for every possible byte value */ mismatches for every possible byte value */
/* Initialize all skips to the pattern length; this is the skip /* Initialize all skips to the pattern length; this is the skip
distance for bytes that don&rsquo;t appear in the pattern */ distance for bytes that don&rsquo;t appear in the pattern */
for (i = 0; i &lt 256; i++) SkipTable[i] = PatternLength; for (i = 0; i &lt; 256; i++) SkipTable[i] = PatternLength;
/*Set the skip values for the bytes that do appear in the pattern /*Set the skip values for the bytes that do appear in the pattern
to the distance from the byte location to the end of the to the distance from the byte location to the end of the
pattern. When there are multiple instances of the same byte, pattern. When there are multiple instances of the same byte,
@ -75,7 +75,7 @@ unsigned char * FindString(unsigned char * BufferPtr,
if we get that value for a mismatch, we know for sure that the if we get that value for a mismatch, we know for sure that the
right end of the pattern has already passed the mismatch right end of the pattern has already passed the mismatch
location, so this is not a relevant byte for skipping purposes */ location, so this is not a relevant byte for skipping purposes */
for (i = 0; i &lt (PatternLength - 1); i++) for (i = 0; i &lt; (PatternLength - 1); i++)
SkipTable[PatternPtr[i]] = PatternLength - i - 1; SkipTable[PatternPtr[i]] = PatternLength - i - 1;
/* Point to rightmost byte of the pattern */ /* Point to rightmost byte of the pattern */
@ -110,7 +110,7 @@ unsigned char * FindString(unsigned char * BufferPtr,
just advance by 1 to the next potential match; otherwise, just advance by 1 to the next potential match; otherwise,
skip ahead from the mismatch location by the skip distance skip ahead from the mismatch location by the skip distance
for the mismatch character */ for the mismatch character */
if (SkipTable[*WorkingBufferPtr] &lt= DistanceMatched) if (SkipTable[*WorkingBufferPtr] &lt;= DistanceMatched)
Skip = 1; /* skip doesn&rsquo;t do any good, advance by 1 */ Skip = 1; /* skip doesn&rsquo;t do any good, advance by 1 */
else else
/* Use skip value, accounting for distance covered by the /* Use skip value, accounting for distance covered by the
@ -118,7 +118,7 @@ unsigned char * FindString(unsigned char * BufferPtr,
Skip = SkipTable[*WorkingBufferPtr] - DistanceMatched; Skip = SkipTable[*WorkingBufferPtr] - DistanceMatched;
/* If skipping ahead would exhaust the buffer, we&rsquo;re done /* If skipping ahead would exhaust the buffer, we&rsquo;re done
without a match */ without a match */
if (Skip &gt= BufferLength) return(NULL); if (Skip &gt;= BufferLength) return(NULL);
/* Skip ahead and perform the next comparison */ /* Skip ahead and perform the next comparison */
BufferLength -= Skip; BufferLength -= Skip;
BufferPtr += Skip; BufferPtr += Skip;
@ -129,13 +129,13 @@ unsigned char * FindString(unsigned char * BufferPtr,
<P><B>LISTING 14.2 L14-2.C</B></P> <P><B>LISTING 14.2 L14-2.C</B></P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* Program to exercise buffer-search routines in Listings 14.1 &amp 14.3. /* Program to exercise buffer-search routines in Listings 14.1 &amp; 14.3.
(Must be modified to put copy of pattern as sentinel at end of the (Must be modified to put copy of pattern as sentinel at end of the
search buffer in order to be used with Listing 14.4.) */ search buffer in order to be used with Listing 14.4.) */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltstring.h&gt #include &lt;string.h&gt;
#include &ltfcntl.h&gt #include &lt;fcntl.h&gt;
#define DISPLAY_LENGTH 40 #define DISPLAY_LENGTH 40
#define BUFFER_SIZE 0x8000 #define BUFFER_SIZE 0x8000

View file

@ -51,7 +51,7 @@
; unsigned int PatternLength); ; unsigned int PatternLength);
parms struc parms struc
dw 2 dup(?) ;pushed BP &amp return address dw 2 dup(?) ;pushed BP &amp; return address
BufferPtr dw ? ;pointer to buffer to be searched BufferPtr dw ? ;pointer to buffer to be searched
BufferLength dw ? ;# of bytes in buffer to be searched BufferLength dw ? ;# of bytes in buffer to be searched
PatternPtr dw ? ;pointer to pattern for which to search PatternPtr dw ? ;pointer to pattern for which to search

View file

@ -59,14 +59,14 @@
; unsigned int PatternLength); ; unsigned int PatternLength);
parms struc parms struc
dw 2 dup(?) ;pushed BP &amp return address dw 2 dup(?) ;pushed BP &amp; return address
BufferPtr dw ? ;pointer to buffer to be searched BufferPtr dw ? ;pointer to buffer to be searched
BufferLength dw ? ;# of bytes in buffer to be searched BufferLength dw ? ;# of bytes in buffer to be searched
; (not used, actually) ; (not used, actually)
PatternPtr dw ? ;pointer to pattern for which to search PatternPtr dw ? ;pointer to pattern for which to search
; (pattern *MUST* exist in the buffer) ; (pattern *MUST* exist in the buffer)
PatternLength dw ? ;length of pattern for which to search (must PatternLength dw ? ;length of pattern for which to search (must
; be &lt= 255) ; be &lt;= 255)
parms ends parms ends
.model small .model small

View file

@ -48,8 +48,8 @@
#include &ldquo;llist.h&rdquo; #include &ldquo;llist.h&rdquo;
struct LinkNode *DeleteNodeAfter(struct LinkNode *NodeToDeleteAfter) struct LinkNode *DeleteNodeAfter(struct LinkNode *NodeToDeleteAfter)
{ {
NodeToDeleteAfter-&gtNextNode = NodeToDeleteAfter-&gt;NextNode =
NodeToDeleteAfter-&gtNextNode-&gtNextNode; NodeToDeleteAfter-&gt;NextNode-&gt;NextNode;
return(NodeToDeleteAfter); return(NodeToDeleteAfter);
} }
</PRE> </PRE>
@ -88,10 +88,10 @@ struct LinkNode *DeleteNodeAfter(struct LinkNode **HeadOfListPtr,
/* Handle specially if the node to delete after is actually the /* Handle specially if the node to delete after is actually the
head of the list (delete the first element in the list) */ head of the list (delete the first element in the list) */
if (NodeToDeleteAfter == (struct LinkNode *)HeadOfListPtr) { if (NodeToDeleteAfter == (struct LinkNode *)HeadOfListPtr) {
*HeadOfListPtr = (*HeadOfListPtr)-&gtNextNode; *HeadOfListPtr = (*HeadOfListPtr)-&gt;NextNode;
} else { } else {
NodeToDeleteAfter-&gtNextNode = NodeToDeleteAfter-&gt;NextNode =
NodeToDeleteAfter-&gtNextNode-&gtNextNode; NodeToDeleteAfter-&gt;NextNode-&gt;NextNode;
} }
return(NodeToDeleteAfter); return(NodeToDeleteAfter);
} }
@ -118,22 +118,22 @@ struct LinkNode *DeleteNodeAfter(struct LinkNode **HeadOfListPtr,
preceding that node (to facilitate insertion and deletion), or a preceding that node (to facilitate insertion and deletion), or a
NULL pointer if no such value was found. Assumes the list is NULL pointer if no such value was found. Assumes the list is
terminated with a tail node pointing to itself as the next node. */ terminated with a tail node pointing to itself as the next node. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ldquo;llist.h&rdquo; #include &ldquo;llist.h&rdquo;
struct LinkNode *FindNodeBeforeValueNotLess( struct LinkNode *FindNodeBeforeValueNotLess(
struct LinkNode *HeadOfListNode, int SearchValue) struct LinkNode *HeadOfListNode, int SearchValue)
{ {
struct LinkNode *NodePtr = HeadOfListNode; struct LinkNode *NodePtr = HeadOfListNode;
while ( (NodePtr-&gtNextNode-&gtNextNode != NodePtr-&gtNextNode) &amp&amp while ( (NodePtr-&gt;NextNode-&gt;NextNode != NodePtr-&gt;NextNode) &amp;&amp;
(NodePtr-&gtNextNode-&gtValue &lt SearchValue) ) (NodePtr-&gt;NextNode-&gt;Value &lt; SearchValue) )
NodePtr = NodePtr-&gtNextNode; NodePtr = NodePtr-&gt;NextNode;
if (NodePtr-&gtNextNode-&gtNextNode == NodePtr-&gtNextNode) if (NodePtr-&gt;NextNode-&gt;NextNode == NodePtr-&gt;NextNode)
return(NULL); /* we found the sentinel; failed search */ return(NULL); /* we found the sentinel; failed search */
else else
return(NodePtr); /* success; return pointer to node preceding return(NodePtr); /* success; return pointer to node preceding
node that was &gt= */ node that was &gt;= */
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -47,19 +47,19 @@
found. Assumes the list is terminated with a sentinel tail node found. Assumes the list is terminated with a sentinel tail node
containing the largest possible Value field setting and pointing containing the largest possible Value field setting and pointing
to itself as the next node. */ to itself as the next node. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ldquo;llist.h&rdquo; #include &ldquo;llist.h&rdquo;
struct LinkNode *FindNodeBeforeValueNotLess( struct LinkNode *FindNodeBeforeValueNotLess(
struct LinkNode *HeadOfListNode, int SearchValue) struct LinkNode *HeadOfListNode, int SearchValue)
{ {
struct LinkNode *NodePtr = HeadOfListNode; struct LinkNode *NodePtr = HeadOfListNode;
while (NodePtr-&gtNextNode-&gtValue &lt SearchValue) while (NodePtr-&gt;NextNode-&gt;Value &lt; SearchValue)
NodePtr = NodePtr-&gtNextNode; NodePtr = NodePtr-&gt;NextNode;
if (NodePtr-&gtNextNode-&gtNextNode == NodePtr-&gtNextNode) if (NodePtr-&gt;NextNode-&gt;NextNode == NodePtr-&gt;NextNode)
return(NULL); /* we found the sentinel; failed search */ return(NULL); /* we found the sentinel; failed search */
else else
return(NodePtr); /* success; return pointer to node preceding return(NodePtr); /* success; return pointer to node preceding
node that was &gt= */ node that was &gt;= */
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->
@ -83,9 +83,9 @@ struct LinkNode *FindNodeBeforeValueNotLess(
is,it has a dummy node as both the head and the tail of the list. is,it has a dummy node as both the head and the tail of the list.
The dummy node is a sentinel, containing the largest possible The dummy node is a sentinel, containing the largest possible
Value field setting. Tested with Borland C++ in C mode. */ Value field setting. Tested with Borland C++ in C mode. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltstring.h&gt #include &lt;string.h&gt;
#include &ldquo;llist.h&rdquo; #include &ldquo;llist.h&rdquo;
/* Initializes an empty linked list of LinkNode structures, /* Initializes an empty linked list of LinkNode structures,
consisting of a single head/tail/sentinel node, and returns a consisting of a single head/tail/sentinel node, and returns a
@ -96,9 +96,9 @@ struct LinkNode *InitLinkedList()
if ((Sentinel = malloc(sizeof(struct LinkNode))) == NULL) if ((Sentinel = malloc(sizeof(struct LinkNode))) == NULL)
return(NULL); return(NULL);
Sentinel-&gtNextNode = Sentinel; Sentinel-&gt;NextNode = Sentinel;
Sentinel-&gtValue = SENTINEL; Sentinel-&gt;Value = SENTINEL;
strcpy(Sentinel-&gtText, &ldquo;*** sentinel ***&rdquo;); strcpy(Sentinel-&gt;Text, &ldquo;*** sentinel ***&rdquo;);
return(Sentinel); return(Sentinel);
} }
@ -113,12 +113,12 @@ int SearchValue)
{ {
struct LinkNode *NodePtr = HeadOfListNode; struct LinkNode *NodePtr = HeadOfListNode;
while (NodePtr-&gtNextNode-&gtValue &lt SearchValue) while (NodePtr-&gt;NextNode-&gt;Value &lt; SearchValue)
NodePtr = NodePtr-&gtNextNode; NodePtr = NodePtr-&gt;NextNode;
if (NodePtr-&gtNextNode-&gtValue == SearchValue) { if (NodePtr-&gt;NextNode-&gt;Value == SearchValue) {
/* Found the search value; success unless we found the /* Found the search value; success unless we found the
sentinel (can happen only if SearchValue == SENTINEL) */ sentinel (can happen only if SearchValue == SENTINEL) */
if (NodePtr-&gtNextNode == HeadOfListNode) { if (NodePtr-&gt;NextNode == HeadOfListNode) {
return(NULL); /* failure; we found the sentinel */ return(NULL); /* failure; we found the sentinel */
} else { } else {
return(NodePtr); /* success; return pointer to node return(NodePtr); /* success; return pointer to node
@ -136,11 +136,11 @@ struct LinkNode *InsertNodeSorted(struct LinkNode *HeadOfListNode,
struct LinkNode *NodeToInsert) struct LinkNode *NodeToInsert)
{ {
struct LinkNode *NodePtr = HeadOfListNode; struct LinkNode *NodePtr = HeadOfListNode;
int SearchValue = NodeToInsert-&gtValue; int SearchValue = NodeToInsert-&gt;Value;
while (NodePtr-&gtNextNode-&gtValue &lt SearchValue) while (NodePtr-&gt;NextNode-&gt;Value &lt; SearchValue)
NodePtr = NodePtr-&gtNextNode; NodePtr = NodePtr-&gt;NextNode;
NodeToInsert-&gtNextNode = NodePtr-&gtNextNode; NodeToInsert-&gt;NextNode = NodePtr-&gt;NextNode;
NodePtr-&gtNextNode = NodeToInsert; NodePtr-&gt;NextNode = NodeToInsert;
return(NodePtr); return(NodePtr);
} }
</PRE> </PRE>

View file

@ -63,7 +63,7 @@ LinkNode ends
; struct LinkNode *InsertNodeSorted(struct LinkNode *HeadOfListNode, ; struct LinkNode *InsertNodeSorted(struct LinkNode *HeadOfListNode,
; struct LinkNode *NodeToInsert) ; struct LinkNode *NodeToInsert)
parms struc parms struc
dw 2 dup (?) ;pushed return address &amp BP dw 2 dup (?) ;pushed return address &amp; BP
HeadOfListNode dw ? ;pointer to head node of list HeadOfListNode dw ? ;pointer to head node of list
NodeToInsert dw ? ;pointer to node to insert NodeToInsert dw ? ;pointer to node to insert
parms ends parms ends
@ -104,11 +104,11 @@ _InsertNodeSorted endp
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* Sample linked list program. Tested with Borland C++. */ /* Sample linked list program. Tested with Borland C++. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltctype.h&gt #include &lt;ctype.h&gt;
#include &ltstring.h&gt #include &lt;string.h&gt;
#include &ldquo;llist.h&rdquo; #include &ldquo;llist.h&rdquo;
void main() void main()
@ -121,7 +121,7 @@ void main()
exit(1); exit(1);
} }
while (!Done) { while (!Done) {
printf(&ldquo;\nA=add; D=delete; F=find; L=list all; Q=quit\n&gt&rdquo;); printf(&ldquo;\nA=add; D=delete; F=find; L=list all; Q=quit\n&gt;&rdquo;);
Char = toupper(getche()); Char = toupper(getche());
printf(&ldquo;\n&rdquo;); printf(&ldquo;\n&rdquo;);
switch (Char) { switch (Char) {
@ -132,24 +132,24 @@ void main()
exit(1); exit(1);
} }
printf(&ldquo;Node value: &rdquo;); printf(&ldquo;Node value: &rdquo;);
scanf(&ldquo;%d&rdquo;, &ampTempPtr-&gtValue); scanf(&ldquo;%d&rdquo;, &amp;TempPtr-&gt;Value);
if ((FindNodeBeforeValue(ListPtr,TempPtr-&gtValue))!=NULL) if ((FindNodeBeforeValue(ListPtr,TempPtr-&gt;Value))!=NULL)
{ printf(&ldquo;*** value already in list; try again ***\n&rdquo;); { printf(&ldquo;*** value already in list; try again ***\n&rdquo;);
free(TempPtr); free(TempPtr);
} else {printf(&ldquo;Node text: &rdquo;); } else {printf(&ldquo;Node text: &rdquo;);
TempBuffer[0] = MAX_TEXT_LENGTH; TempBuffer[0] = MAX_TEXT_LENGTH;
cgets(TempBuffer); cgets(TempBuffer);
strcpy(TempPtr-&gtText, &ampTempBuffer[2]); strcpy(TempPtr-&gt;Text, &amp;TempBuffer[2]);
InsertNodeSorted(ListPtr, TempPtr); InsertNodeSorted(ListPtr, TempPtr);
printf(&ldquo;\n&rdquo;); printf(&ldquo;\n&rdquo;);
} }
break; break;
case 'D': /* delete a node */ case 'D': /* delete a node */
printf(&ldquo;Value field of node to delete: &rdquo;); printf(&ldquo;Value field of node to delete: &rdquo;);
scanf(&ldquo;%d&rdquo;, &ampTempValue); scanf(&ldquo;%d&rdquo;, &amp;TempValue);
if ((TempPtr = FindNodeBeforeValue(ListPtr, TempValue)) if ((TempPtr = FindNodeBeforeValue(ListPtr, TempValue))
!= NULL) { != NULL) {
TempPtr2 = TempPtr-&gtNextNode; /* -&gt node to delete */ TempPtr2 = TempPtr-&gt;NextNode; /* -&gt; node to delete */
DeleteNodeAfter(TempPtr); /* delete it */ DeleteNodeAfter(TempPtr); /* delete it */
free(TempPtr2); /* free its memory */ free(TempPtr2); /* free its memory */
} else { } else {
@ -157,22 +157,22 @@ void main()
break; break;
case 'F': /* find a node */ case 'F': /* find a node */
printf(&ldquo;Value field of node to find: &rdquo;); printf(&ldquo;Value field of node to find: &rdquo;);
scanf(&ldquo;%d&rdquo;, &ampTempValue); scanf(&ldquo;%d&rdquo;, &amp;TempValue);
if ((TempPtr = FindNodeBeforeValue(ListPtr, TempValue)) if ((TempPtr = FindNodeBeforeValue(ListPtr, TempValue))
!= NULL) != NULL)
printf(&ldquo;Value: %d\nText: %s\n&rdquo;, printf(&ldquo;Value: %d\nText: %s\n&rdquo;,
TempPtr-&gtNextNode-&gtValue, TempPtr-&gtNextNode-&gtText); TempPtr-&gt;NextNode-&gt;Value, TempPtr-&gt;NextNode-&gt;Text);
else else
printf(&ldquo;*** no such value field in list ***\n&rdquo;); printf(&ldquo;*** no such value field in list ***\n&rdquo;);
break; break;
case 'L': /* list all nodes */ case 'L': /* list all nodes */
TempPtr = ListPtr-&gtNextNode; /* point to first node */ TempPtr = ListPtr-&gt;NextNode; /* point to first node */
if (TempPtr == ListPtr) { /* empty if at sentinel */ if (TempPtr == ListPtr) { /* empty if at sentinel */
printf(&ldquo;*** List is empty ***\n&rdquo;); printf(&ldquo;*** List is empty ***\n&rdquo;);
} else { } else {
do {printf(&ldquo;Value: %d\n Text: %s\n&rdquo;, TempPtr-&gtValue, do {printf(&ldquo;Value: %d\n Text: %s\n&rdquo;, TempPtr-&gt;Value,
TempPtr-&gtText); TempPtr-&gt;Text);
TempPtr = TempPtr-&gtNextNode; TempPtr = TempPtr-&gt;NextNode;
} while (TempPtr != ListPtr); } while (TempPtr != ListPtr);
} }
break; break;

View file

@ -67,10 +67,10 @@
<TD ALIGN="LEFT" VALIGN="TOP">16.1 (C) <TD ALIGN="LEFT" VALIGN="TOP">16.1 (C)
<TD ALIGN="LEFT" VALIGN="TOP">4.6 seconds <TD ALIGN="LEFT" VALIGN="TOP">4.6 seconds
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP">16.2 &amp 16.3 (C+ASM) <TD ALIGN="LEFT" VALIGN="TOP">16.2 &amp; 16.3 (C+ASM)
<TD ALIGN="LEFT" VALIGN="TOP">2.4 seconds <TD ALIGN="LEFT" VALIGN="TOP">2.4 seconds
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP">16.2 &amp 16.4 (C+ASM w/lookup) <TD ALIGN="LEFT" VALIGN="TOP">16.2 &amp; 16.4 (C+ASM w/lookup)
<TD ALIGN="LEFT" VALIGN="TOP">1.6 seconds <TD ALIGN="LEFT" VALIGN="TOP">1.6 seconds
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP" COLSPAN="2"><SMALL>These are the times taken to search a file containing 104,448 words, timed from a RAM disk on a 20 MHz 386.</SMALL> <TD ALIGN="LEFT" VALIGN="TOP" COLSPAN="2"><SMALL>These are the times taken to search a file containing 104,448 words, timed from a RAM disk on a 20 MHz 386.</SMALL>
@ -85,11 +85,11 @@
/* Word-counting program. Tested with Borland C++ in C /* Word-counting program. Tested with Borland C++ in C
compilation mode and the small model. */ compilation mode and the small model. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltfcntl.h&gt #include &lt;fcntl.h&gt;
#include &ltsys\stat.h&gt #include &lt;sys\stat.h&gt;
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltio.h&gt #include &lt;io.h&gt;
#define <I>B</I> UFFER_SIZE 0x8000 /* largest chunk of file worked #define <I>B</I> UFFER_SIZE 0x8000 /* largest chunk of file worked
with at any one time */ with at any one time */
@ -103,7 +103,7 @@
char *Buffer, CharFlag = 0, PredCharFlag, *BufferPtr, Ch; char *Buffer, CharFlag = 0, PredCharFlag, *BufferPtr, Ch;
if (argc != 2) { if (argc != 2) {
printf(&ldquo;usage: wc &ltfilename&gt\n&rdquo;); printf(&ldquo;usage: wc &lt;filename&gt;\n&rdquo;);
exit(1); exit(1);
} }
@ -123,7 +123,7 @@
} }
/* Process the file in chunks */ /* Process the file in chunks */
while (FileSize &gt 0) { while (FileSize &gt; 0) {
/* Get the next chunk */ /* Get the next chunk */
FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE)); FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE));
if (read(Handle, Buffer, BlockSize) == -1) { if (read(Handle, Buffer, BlockSize) == -1) {
@ -134,14 +134,14 @@
BufferPtr = Buffer; BufferPtr = Buffer;
do { do {
PredCharFlag = CharFlag; PredCharFlag = CharFlag;
Ch = *BufferPtr++ &amp 0x7F; /* strip high bit, which some Ch = *BufferPtr++ &amp; 0x7F; /* strip high bit, which some
word processors set as an word processors set as an
internal flag */ internal flag */
CharFlag = ((Ch &gt= &lsquo;a&rsquo;) &amp&amp (Ch &lt= &lsquo;z&rsquo;)) || CharFlag = ((Ch &gt;= &lsquo;a&rsquo;) &amp;&amp; (Ch &lt;= &lsquo;z&rsquo;)) ||
((Ch &gt= &lsquo;A&rsquo;) &amp&amp (Ch &lt= &lsquo;Z&rsquo;)) || ((Ch &gt;= &lsquo;A&rsquo;) &amp;&amp; (Ch &lt;= &lsquo;Z&rsquo;)) ||
((Ch &gt= &lsquo;0&rsquo;) &amp&amp (Ch &lt= &lsquo;9&rsquo;)) || ((Ch &gt;= &lsquo;0&rsquo;) &amp;&amp; (Ch &lt;= &lsquo;9&rsquo;)) ||
(Ch == &lsquo;\&rsquo;&rsquo;); (Ch == &lsquo;\&rsquo;&rsquo;);
if ((!CharFlag) &amp&amp PredCharFlag) { if ((!CharFlag) &amp;&amp; PredCharFlag) {
WordCo <I>u</I> nt++; WordCo <I>u</I> nt++;
} }
} while (&mdash;BlockSize); } while (&mdash;BlockSize);

View file

@ -42,13 +42,13 @@
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* Word-counting program incorporating assembly language. Tested /* Word-counting program incorporating assembly language. Tested
with Borland C<SMALL>++</SMALL> in C compilation mode &amp the small model. */ with Borland C<SMALL>++</SMALL> in C compilation mode &amp; the small model. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltfcntl.h&gt #include &lt;fcntl.h&gt;
#include &ltsys\stat.h&gt #include &lt;sys\stat.h&gt;
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltio.h&gt #include &lt;io.h&gt;
#define BUFFER_SIZE 0x8000 /* largest chunk of file worked #define BUFFER_SIZE 0x8000 /* largest chunk of file worked
with at any one time */ with at any one time */
@ -63,7 +63,7 @@
char *Buffer, CharFlag = 0; char *Buffer, CharFlag = 0;
if (argc != 2) { if (argc != 2) {
printf(&ldquo;usage: wc &ltfilename&gt\n&rdquo;); printf(&ldquo;usage: wc &lt;filename&gt;\n&rdquo;);
exit(1); exit(1);
} }
@ -83,13 +83,13 @@
} }
CharFlag = 0; CharFlag = 0;
while (FileSize &gt 0) { while (FileSize &gt; 0) {
FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE)); FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE));
if (read(Handle, Buffer, BlockSize) == -1) { if (read(Handle, Buffer, BlockSize) == -1) {
printf(&ldquo;Error reading file %s\n&rdquo;, argv[1]); printf(&ldquo;Error reading file %s\n&rdquo;, argv[1]);
exit(1); exit(1);
} }
ScanBuffer(Buffer, BlockSize, &ampCharFlag, &ampWordCount); ScanBuffer(Buffer, BlockSize, &amp;CharFlag, &amp;WordCount);
} }
/* Catch the last word, if any */ /* Catch the last word, if any */
@ -106,14 +106,14 @@
<PRE> <PRE>
; Assembly subroutine for Listing 16.2. Scans through Buffer, of ; Assembly subroutine for Listing 16.2. Scans through Buffer, of
; length BufferLength, counting words and updating WordCount as ; length BufferLength, counting words and updating WordCount as
; appropriate. BufferLength must be &gt 0. *CharFlag and *WordCount ; appropriate. BufferLength must be &gt; 0. *CharFlag and *WordCount
; should equal 0 on the first call. Tested with TASM. ; should equal 0 on the first call. Tested with TASM.
; C near-callable as: ; C near-callable as:
; void ScanBuffer(char *Buffer, unsigned int BufferLength, ; void ScanBuffer(char *Buffer, unsigned int BufferLength,
; char *CharFlag, unsigned long *WordCount); ; char *CharFlag, unsigned long *WordCount);
parms struc parms struc
dw 2 dup(?) ;pushed return address &amp BP dw 2 dup(?) ;pushed return address &amp; BP
Buffer dw ? ;buffer to scan Buffer dw ? ;buffer to scan
BufferLength dw ? ;length of buffer to scan BufferLength dw ? ;length of buffer to scan
CharFlag dw ? ;pointer to flag for state of last CharFlag dw ? ;pointer to flag for state of last
@ -141,7 +141,7 @@
mov di,[bp+BufferLength];get # of bytes to scan mov di,[bp+BufferLength];get # of bytes to scan
ScanLoop: ScanLoop:
mov bh,bl ;PredCharFlag = CharFlag; mov bh,bl ;PredCharFlag = CharFlag;
lodsb ;Ch = *BufferPtr++ &amp 0x7F; lodsb ;Ch = *BufferPtr++ &amp; 0x7F;
and al,7fh ;strip high bit for word processors and al,7fh ;strip high bit for word processors
; that set it as an internal flag ; that set it as an internal flag
mov bl,1 ;assume this is a char; CharFlag = 1; mov bl,1 ;assume this is a char; CharFlag = 1;
@ -164,7 +164,7 @@
jz IsAChar jz IsAChar
sub bl,bl ;not a char; CharFlag = 0; sub bl,bl ;not a char; CharFlag = 0;
and bh,bh and bh,bh
jz ScanLoopBottom ;if ((!CharFlag) &amp&amp PredCharFlag) { jz ScanLoopBottom ;if ((!CharFlag) &amp;&amp; PredCharFlag) {
add cx,1 ; (WordCount)++; add cx,1 ; (WordCount)++;
adc dx,0 ;} adc dx,0 ;}
IsAChar: IsAChar:

View file

@ -42,14 +42,14 @@
; Assembly subroutine for Listing 16.2. Scans through Buffer, of ; Assembly subroutine for Listing 16.2. Scans through Buffer, of
; length BufferLength, counting words and updating WordCount as ; length BufferLength, counting words and updating WordCount as
; appropriate, using a lookup table-based approach. BufferLength ; appropriate, using a lookup table-based approach. BufferLength
; must be &gt 0. *CharFlag and *WordCount should equal 0 on the ; must be &gt; 0. *CharFlag and *WordCount should equal 0 on the
; first call. Tested with TASM. ; first call. Tested with TASM.
; C near-callable as: ; C near-callable as:
; void ScanBuffer(char *Buffer, unsigned int BufferLength, ; void ScanBuffer(char *Buffer, unsigned int BufferLength,
; char *CharFlag, unsigned long *WordCount); ; char *CharFlag, unsigned long *WordCount);
parms struc parms struc
dw 2 dup(?) ;pushed return address &amp BP dw 2 dup(?) ;pushed return address &amp; BP
Buffer dw ? ;buffer to scan Buffer dw ? ;buffer to scan
BufferLength dw ? ;length of buffer to scan BufferLength dw ? ;length of buffer to scan
CharFlag dw ? ;pointer to flag for state of last CharFlag dw ? ;pointer to flag for state of last

View file

@ -139,14 +139,14 @@ jumping.
.code .code
Test1 macro x,y ;9 or 10 bytes Test1 macro x,y ;9 or 10 bytes
Addr&ampx: mov di,[bp+y] ;3 or 4 bytes Addr&amp;x: mov di,[bp+y] ;3 or 4 bytes
adc di,di adc di,di
or ax,si or ax,si
add al,[di] add al,[di]
endm endm
Test2 macro x,y ;7 or 8 bytes Test2 macro x,y ;7 or 8 bytes
Addr&ampx: mov di,[bp+y] ;3 or 4 bytes Addr&amp;x: mov di,[bp+y] ;3 or 4 bytes
adc di,di adc di,di
add ah,[di] add ah,[di]
endm endm
@ -264,7 +264,7 @@ jumping.
.data .data
Address macro X Address macro X
dw Addr&ampX dw Addr&amp;X
endm endm
LoopEntry label word LoopEntry label word

View file

@ -67,10 +67,10 @@
<PRE> <PRE>
// MAKETAB.C &mdash; Build QSCAN3.INC for QSCAN3.ASM // MAKETAB.C &mdash; Build QSCAN3.INC for QSCAN3.ASM
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltctype.h&gt #include &lt;ctype.h&gt;
#define ChType( c ) (((c) &amp 0x7f) == &lsquo;\&rsquo;&rsquo; || isalnum((c) &amp 0x7f)) #define ChType( c ) (((c) &amp; 0x7f) == &lsquo;\&rsquo;&rsquo; || isalnum((c) &amp; 0x7f))
int NoCarry[ 4 ] = { 0, 0x80, 1, 0x80 }; int NoCarry[ 4 ] = { 0, 0x80, 1, 0x80 };
int Carry[ 4 ] = { 1, 0x81, 1, 0x80 }; int Carry[ 4 ] = { 1, 0x81, 1, 0x80 };
@ -82,9 +82,9 @@
printf( &ldquo;Building table. Please wait...&rdquo; ); printf( &ldquo;Building table. Please wait...&rdquo; );
for( ahChar = 0; ahChar &lt 128; ahChar++ ) for( ahChar = 0; ahChar &lt; 128; ahChar++ )
{ {
for( alChar = 0; alChar &lt 256; alChar++ ) for( alChar = 0; alChar &lt; 256; alChar++ )
{ {
i = ChType( alChar ) * 2 + ChType( ahChar ); i = ChType( alChar ) * 2 + ChType( ahChar );

View file

@ -42,14 +42,14 @@
/* C++ Game of Life implementation for any mode for which mode set /* C++ Game of Life implementation for any mode for which mode set
and draw pixel functions can be provided. and draw pixel functions can be provided.
Tested with Borland C++ in the small model. */ Tested with Borland C++ in the small model. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltiostream.h&gt #include &lt;iostream.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &lttime.h&gt #include &lt;time.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ltbios.h&gt #include &lt;bios.h&gt;
#include &ltmem.h&gt #include &lt;mem.h&gt;
#define ON_COLOR 15 // on-cell pixel color #define ON_COLOR 15 // on-cell pixel color
#define OFF_COLOR 0 // off-cell pixel color #define OFF_COLOR 0 // off-cell pixel color
@ -68,11 +68,11 @@ private:
public: public:
cellmap(unsigned int h, unsigned int v); cellmap(unsigned int h, unsigned int v);
~cellmap(void); ~cellmap(void);
void copy_cells(cellmap &ampsourcemap); void copy_cells(cellmap &amp;sourcemap);
void set_cell(unsigned int x, unsigned int y); void set_cell(unsigned int x, unsigned int y);
void clear_cell(unsigned int x, unsigned int y); void clear_cell(unsigned int x, unsigned int y);
int cell_state(int x, int y); int cell_state(int x, int y);
void next_generation(cellmap&amp dest_map); void next_generation(cellmap&amp; dest_map);
}; };
extern void enter_display_mode(void); extern void enter_display_mode(void);
@ -86,7 +86,7 @@ extern void show_text(int x, int y, char *text);
display at right. */ display at right. */
unsigned int cellmap_width = 96; unsigned int cellmap_width = 96;
unsigned int cellmap_height = 96; unsigned int cellmap_height = 96;
/* Width &amp height in pixels of each cell as displayed on screen. */ /* Width &amp; height in pixels of each cell as displayed on screen. */
unsigned int magnifier = 2; unsigned int magnifier = 2;
void main() void main()
@ -100,12 +100,12 @@ void main()
cellmap next_map(cellmap_height, cellmap_width); cellmap next_map(cellmap_height, cellmap_width);
// Get the seed; seed randomly if 0 entered // Get the seed; seed randomly if 0 entered
cout &lt&lt &ldquo;Seed (0 for random seed): &rdquo;; cout &lt;&lt; &ldquo;Seed (0 for random seed): &rdquo;;
cin &gt&gt seed; cin &gt;&gt; seed;
if (seed == 0) seed = (unsigned) time(NULL); if (seed == 0) seed = (unsigned) time(NULL);
// Randomly initialize the initial cell map // Randomly initialize the initial cell map
cout &lt&lt &ldquo;Initializing...&rdquo;; cout &lt;&lt; &ldquo;Initializing...&rdquo;;
srand(seed); srand(seed);
init_length = (cellmap_height * cellmap_width) / 2; init_length = (cellmap_height * cellmap_width) / 2;
do { do {
@ -120,7 +120,7 @@ void main()
// Keep recalculating and redisplaying generations until a key // Keep recalculating and redisplaying generations until a key
// is pressed // is pressed
show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;); show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;);
start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time); start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &amp;bios_time);
do { do {
generation++; generation++;
sprintf(gen_text, &ldquo;%10lu&rdquo;, generation); sprintf(gen_text, &ldquo;%10lu&rdquo;, generation);
@ -132,15 +132,15 @@ void main()
#if LIMIT_18_HZ #if LIMIT_18_HZ
// Limit to a maximum of 18.2 frames per second,for visibility // Limit to a maximum of 18.2 frames per second,for visibility
do { do {
_bios_timeofday(_TIME_GETCLOCK, &ampbios_time); _bios_timeofday(_TIME_GETCLOCK, &amp;bios_time);
} while (start_bios_time == bios_time); } while (start_bios_time == bios_time);
start_bios_time = bios_time; start_bios_time = bios_time;
#endif #endif
} while (!kbhit()); } while (!kbhit());
getch(); // clear keypress getch(); // clear keypress
exit_display_mode(); exit_display_mode();
cout &lt&lt &ldquo;Total generations: &rdquo; &lt&lt generation &lt&lt &ldquo;\nSeed: &rdquo; &lt&lt cout &lt;&lt; &ldquo;Total generations: &rdquo; &lt;&lt; generation &lt;&lt; &ldquo;\nSeed: &rdquo; &lt;&lt;
seed &lt&lt &ldquo;\n&rdquo;; seed &lt;&lt; &ldquo;\n&rdquo;;
} }
/* cellmap constructor. */ /* cellmap constructor. */
@ -162,7 +162,7 @@ cellmap::~cellmap(void)
/* Copies one cellmap&rsquo;s cells to another cellmap. Both cellmaps are /* Copies one cellmap&rsquo;s cells to another cellmap. Both cellmaps are
assumed to be the same size. */ assumed to be the same size. */
void cellmap::copy_cells(cellmap &ampsourcemap) void cellmap::copy_cells(cellmap &amp;sourcemap)
{ {
memcpy(cells, sourcemap.cells, length_in_bytes); memcpy(cells, sourcemap.cells, length_in_bytes);
} }
@ -173,7 +173,7 @@ void cellmap::set_cell(unsigned int x, unsigned int y)
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells + (y * width_in_bytes) + (x / 8); cells + (y * width_in_bytes) + (x / 8);
*(cell_ptr) |= 0x80 &gt&gt (x &amp 0x07); *(cell_ptr) |= 0x80 &gt;&gt; (x &amp; 0x07);
} }
/* Turns cell off. */ /* Turns cell off. */
@ -182,7 +182,7 @@ void cellmap::clear_cell(unsigned int x, unsigned int y)
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells + (y * width_in_bytes) + (x / 8); cells + (y * width_in_bytes) + (x / 8);
*(cell_ptr) &amp= ~(0x80 &gt&gt (x &amp 0x07)); *(cell_ptr) &amp;= ~(0x80 &gt;&gt; (x &amp; 0x07));
} }
/* Returns cell state (1=on or 0=off), optionally wrapping at the /* Returns cell state (1=on or 0=off), optionally wrapping at the
@ -192,26 +192,26 @@ int cellmap::cell_state(int x, int y)
unsigned char *cell_ptr; unsigned char *cell_ptr;
#if WRAP_EDGES #if WRAP_EDGES
while (x &lt 0) x += width; // wrap, if necessary while (x &lt; 0) x += width; // wrap, if necessary
while (x &gt= width) x -= width; while (x &gt;= width) x -= width;
while (y &lt 0) y += height; while (y &lt; 0) y += height;
while (y &gt= height) y -= height; while (y &gt;= height) y -= height;
#else #else
if ((x &lt 0) || (x &gt= width) || (y &lt 0) || (y &gt= height)) if ((x &lt; 0) || (x &gt;= width) || (y &lt; 0) || (y &gt;= height))
return 0; // return 0 for off edges if no wrapping return 0; // return 0 for off edges if no wrapping
#endif #endif
cell_ptr = cells + (y * width_in_bytes) + (x / 8); cell_ptr = cells + (y * width_in_bytes) + (x / 8);
return (*cell_ptr &amp (0x80 &gt&gt (x &amp 0x07))) ? 1 : 0; return (*cell_ptr &amp; (0x80 &gt;&gt; (x &amp; 0x07))) ? 1 : 0;
} }
/* Calculates the next generation of a cellmap and stores it in /* Calculates the next generation of a cellmap and stores it in
next_map. */ next_map. */
void cellmap::next_generation(cellmap&amp next_map) void cellmap::next_generation(cellmap&amp; next_map)
{ {
unsigned int x, y, neighbor_count; unsigned int x, y, neighbor_count;
for (y=0; y&ltheight; y++) { for (y=0; y&lt;height; y++) {
for (x=0; x&ltwidth; x++) { for (x=0; x&lt;width; x++) {
// Figure out how many neighbors this cell has // Figure out how many neighbors this cell has
neighbor_count = cell_state(x-1, y-1) + cell_state(x, y-1) + neighbor_count = cell_state(x-1, y-1) + cell_state(x, y-1) +
cell_state(x+1, y-1) + cell_state(x-1, y) + cell_state(x+1, y-1) + cell_state(x-1, y) +
@ -219,7 +219,7 @@ void cellmap::next_generation(cellmap&amp next_map)
cell_state(x, y+1) + cell_state(x+1, y+1); cell_state(x, y+1) + cell_state(x+1, y+1);
if (cell_state(x, y) == 1) { if (cell_state(x, y) == 1) {
// The cell is on; does it stay on? // The cell is on; does it stay on?
if ((neighbor_count != 2) &amp&amp (neighbor_count != 3)) { if ((neighbor_count != 2) &amp;&amp; (neighbor_count != 3)) {
next_map.clear_cell(x, y); // turn it off next_map.clear_cell(x, y); // turn it off
draw_pixel(x, y, OFF_COLOR); draw_pixel(x, y, OFF_COLOR);
} }
@ -240,17 +240,17 @@ void cellmap::next_generation(cellmap&amp next_map)
<PRE> <PRE>
/* VGA mode 13h functions for Game of Life. /* VGA mode 13h functions for Game of Life.
Tested with Borland C++. */ Tested with Borland C++. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#define TEXT_X_OFFSET 27 #define TEXT_X_OFFSET 27
#define SCREEN_WIDTH_IN_BYTES 320 #define SCREEN_WIDTH_IN_BYTES 320
/* Width &amp height in pixels of each cell. */ /* Width &amp; height in pixels of each cell. */
extern unsigned int magnifier; extern unsigned int magnifier;
/* Mode 13h draw pixel function. Pixels are of width &amp height /* Mode 13h draw pixel function. Pixels are of width &amp; height
specified by magnifier. */ specified by magnifier. */
void draw_pixel(unsigned int x, unsigned int y, unsigned int color) void draw_pixel(unsigned int x, unsigned int y, unsigned int color)
{ {
@ -261,8 +261,8 @@ void draw_pixel(unsigned int x, unsigned int y, unsigned int color)
FP_SEG(screen_ptr) = SCREEN_SEGMENT; FP_SEG(screen_ptr) = SCREEN_SEGMENT;
FP_OFF(screen_ptr) = FP_OFF(screen_ptr) =
y * magnifier * SCREEN_WIDTH_IN_BYTES + x * magnifier; y * magnifier * SCREEN_WIDTH_IN_BYTES + x * magnifier;
for (i=0; i&ltmagnifier; i++) { for (i=0; i&lt;magnifier; i++) {
for (j=0; j&ltmagnifier; j++) { for (j=0; j&lt;magnifier; j++) {
*(screen_ptr+j) = color; *(screen_ptr+j) = color;
} }
screen_ptr += SCREEN_WIDTH_IN_BYTES; screen_ptr += SCREEN_WIDTH_IN_BYTES;
@ -275,7 +275,7 @@ void enter_display_mode()
union REGS regset; union REGS regset;
regset.x.ax = 0x0013; regset.x.ax = 0x0013;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
/* Text mode mode-set function. */ /* Text mode mode-set function. */
@ -284,7 +284,7 @@ void exit_display_mode()
union REGS regset; union REGS regset;
regset.x.ax = 0x0003; regset.x.ax = 0x0003;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
/* Text display function. Offsets text to non-graphics area of /* Text display function. Offsets text to non-graphics area of

View file

@ -75,19 +75,19 @@
<TD VALIGN="TOP" ALIGN="LEFT">2 <TD VALIGN="TOP" ALIGN="LEFT">2
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT"><B>set_cell()</B> <TD VALIGN="TOP" ALIGN="LEFT"><B>set_cell()</B>
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT"><B>clear_cell()</B> <TD VALIGN="TOP" ALIGN="LEFT"><B>clear_cell()</B>
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT"><B>copy_cells()</B> <TD VALIGN="TOP" ALIGN="LEFT"><B>copy_cells()</B>
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TD VALIGN="TOP" ALIGN="LEFT">&lt1 <TD VALIGN="TOP" ALIGN="LEFT">&lt;1
<TR> <TR>
<TD COLSPAN="4"><HR> <TD COLSPAN="4"><HR>
<TR> <TR>

View file

@ -65,12 +65,12 @@ private:
public: public:
cellmap(unsigned int h, unsigned int v); cellmap(unsigned int h, unsigned int v);
~cellmap(void); ~cellmap(void);
void copy_cells(cellmap &ampsourcemap); void copy_cells(cellmap &amp;sourcemap);
void set_cell(unsigned int x, unsigned int y); void set_cell(unsigned int x, unsigned int y);
void clear_cell(unsigned int x, unsigned int y); void clear_cell(unsigned int x, unsigned int y);
int cell_state(int x, int y); int cell_state(int x, int y);
int count_neighbors(int x, int y); int count_neighbors(int x, int y);
void next_generation(cellmap&amp dest_map); void next_generation(cellmap&amp; dest_map);
}; };
/* cellmap constructor. Pads around cell storage area with 1 extra /* cellmap constructor. Pads around cell storage area with 1 extra
@ -92,7 +92,7 @@ cellmap::cellmap(unsigned int h, unsigned int w)
source first, so that the padding bytes off each edge have the source first, so that the padding bytes off each edge have the
same values as would be found by wrapping around to the opposite same values as would be found by wrapping around to the opposite
edge. Both cellmaps are assumed to be the same size. */ edge. Both cellmaps are assumed to be the same size. */
void cellmap::copy_cells(cellmap &ampsourcemap) void cellmap::copy_cells(cellmap &amp;sourcemap)
{ {
unsigned char *cell_ptr; unsigned char *cell_ptr;
int i; int i;
@ -100,7 +100,7 @@ void cellmap::copy_cells(cellmap &ampsourcemap)
#if WRAP_EDGES #if WRAP_EDGES
// Copy left and right edges into padding bytes on right and left // Copy left and right edges into padding bytes on right and left
cell_ptr = sourcemap.cells + width_in_bytes; cell_ptr = sourcemap.cells + width_in_bytes;
for (i=0; i&ltheight; i++) { for (i=0; i&lt;height; i++) {
*cell_ptr = *(cell_ptr + width_in_bytes - 2); *cell_ptr = *(cell_ptr + width_in_bytes - 2);
*(cell_ptr + width_in_bytes - 1) = *(cell_ptr + 1); *(cell_ptr + width_in_bytes - 1) = *(cell_ptr + 1);
cell_ptr += width_in_bytes; cell_ptr += width_in_bytes;
@ -122,7 +122,7 @@ void cellmap::set_cell(unsigned int x, unsigned int y)
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1); cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1);
*(cell_ptr) |= 0x80 &gt&gt (x &amp 0x07); *(cell_ptr) |= 0x80 &gt;&gt; (x &amp; 0x07);
} }
/* Turns cell off. x and y are offset by 1 byte down and to the right, /* Turns cell off. x and y are offset by 1 byte down and to the right,
@ -132,7 +132,7 @@ void cellmap::clear_cell(unsigned int x, unsigned int y)
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1); cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1);
*(cell_ptr) &amp= ~(0x80 &gt&gt (x &amp 0x07)); *(cell_ptr) &amp;= ~(0x80 &gt;&gt; (x &amp; 0x07));
} }
/* Returns cell state (1=on or 0=off). x and y are offset by 1 byte /* Returns cell state (1=on or 0=off). x and y are offset by 1 byte
@ -144,7 +144,7 @@ int cellmap::cell_state(int x, int y)
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1); cells + ((y + 1) * width_in_bytes) + ((x / 8) + 1);
return (*cell_ptr &amp (0x80 &gt&gt (x &amp 0x07))) ? 1 : 0; return (*cell_ptr &amp; (0x80 &gt;&gt; (x &amp; 0x07))) ? 1 : 0;
} }
/* Counts the number of neighboring on-cells for specified cell. */ /* Counts the number of neighboring on-cells for specified cell. */
@ -155,50 +155,50 @@ int cellmap::count_neighbors(int x, int y)
// Point to upper left neighbor // Point to upper left neighbor
cell_ptr = cells + ((y * width_in_bytes) + ((x + 7) / 8)); cell_ptr = cells + ((y * width_in_bytes) + ((x + 7) / 8));
mask = 0x80 &gt&gt ((x - 1) &amp 0x07); mask = 0x80 &gt;&gt; ((x - 1) &amp; 0x07);
// Count upper left neighbor // Count upper left neighbor
neighbor_count = (*cell_ptr &amp mask) ? 1 : 0; neighbor_count = (*cell_ptr &amp; mask) ? 1 : 0;
// Count left neighbor // Count left neighbor
if ((*(cell_ptr + width_in_bytes) &amp mask)) neighbor_count++; if ((*(cell_ptr + width_in_bytes) &amp; mask)) neighbor_count++;
// Count lower left neighbor // Count lower left neighbor
if ((*(cell_ptr + (width_in_bytes * 2)) &amp mask)) neighbor_count++; if ((*(cell_ptr + (width_in_bytes * 2)) &amp; mask)) neighbor_count++;
// Point to upper neighbor // Point to upper neighbor
if ((mask &gt&gt= 1) == 0) { if ((mask &gt;&gt;= 1) == 0) {
mask = 0x80; mask = 0x80;
cell_ptr++; cell_ptr++;
} }
// Count upper neighbor // Count upper neighbor
if ((*cell_ptr &amp mask)) neighbor_count++; if ((*cell_ptr &amp; mask)) neighbor_count++;
// Count lower neighbor // Count lower neighbor
if ((*(cell_ptr + (width_in_bytes * 2)) &amp mask)) neighbor_count++; if ((*(cell_ptr + (width_in_bytes * 2)) &amp; mask)) neighbor_count++;
// Point to upper right neighbor // Point to upper right neighbor
if ((mask &gt&gt= 1) == 0) { if ((mask &gt;&gt;= 1) == 0) {
mask = 0x80; mask = 0x80;
cell_ptr++; cell_ptr++;
} }
// Count upper right neighbor // Count upper right neighbor
if ((*cell_ptr &amp mask)) neighbor_count++; if ((*cell_ptr &amp; mask)) neighbor_count++;
// Count right neighbor // Count right neighbor
if ((*(cell_ptr + width_in_bytes) &amp mask)) neighbor_count++; if ((*(cell_ptr + width_in_bytes) &amp; mask)) neighbor_count++;
// Count lower right neighbor // Count lower right neighbor
if ((*(cell_ptr + (width_in_bytes * 2)) &amp mask)) neighbor_count++; if ((*(cell_ptr + (width_in_bytes * 2)) &amp; mask)) neighbor_count++;
return neighbor_count; return neighbor_count;
} }
/* Calculates the next generation of current_map and stores it in /* Calculates the next generation of current_map and stores it in
next_map. */ next_map. */
void cellmap::next_generation(cellmap&amp next_map) void cellmap::next_generation(cellmap&amp; next_map)
{ {
unsigned int x, y, neighbor_count; unsigned int x, y, neighbor_count;
for (y=0; y&ltheight; y++) { for (y=0; y&lt;height; y++) {
for (x=0; x&ltwidth; x++) { for (x=0; x&lt;width; x++) {
neighbor_count = count_neighbors(x, y); neighbor_count = count_neighbors(x, y);
if (cell_state(x, y) == 1) { if (cell_state(x, y) == 1) {
if ((neighbor_count != 2) &amp&amp (neighbor_count != 3)) { if ((neighbor_count != 2) &amp;&amp; (neighbor_count != 3)) {
next_map.clear_cell(x, y); // turn it off next_map.clear_cell(x, y); // turn it off
draw_pixel(x, y, OFF_COLOR); draw_pixel(x, y, OFF_COLOR);
} }

View file

@ -50,10 +50,10 @@
/* Calculates the next generation of current_map and stores it in /* Calculates the next generation of current_map and stores it in
next_map. */ next_map. */
void cellmap::next_generation(cellmap&amp next_map) void cellmap::next_generation(cellmap&amp; next_map)
{ {
unsigned int x, y, neighbor_count; unsigned int x, y, neighbor_count;
unsigned int width_in_bytesX2 = width_in_bytes &lt&lt 1; unsigned int width_in_bytesX2 = width_in_bytes &lt;&lt; 1;
unsigned char *cell_ptr, *current_cell_ptr, mask, current_mask; unsigned char *cell_ptr, *current_cell_ptr, mask, current_mask;
unsigned char *base_cell_ptr, *row_cell_ptr, base_mask; unsigned char *base_cell_ptr, *row_cell_ptr, base_mask;
unsigned char *dest_cell_ptr = next_map.cells; unsigned char *dest_cell_ptr = next_map.cells;
@ -61,24 +61,24 @@ void cellmap::next_generation(cellmap&amp next_map)
// Process all cells in the current cellmap // Process all cells in the current cellmap
row_cell_ptr = cells; // point to upper left neighbor of row_cell_ptr = cells; // point to upper left neighbor of
// first cell in cell map // first cell in cell map
for (y=0; y&ltheight; y++) { // repeat for each row of cells for (y=0; y&lt;height; y++) { // repeat for each row of cells
// Cell pointer and cell bit mask for first cell in row // Cell pointer and cell bit mask for first cell in row
base_cell_ptr = row_cell_ptr; // to access upper left neighbor base_cell_ptr = row_cell_ptr; // to access upper left neighbor
base_mask = 0x01; // of first cell in row base_mask = 0x01; // of first cell in row
for (x=0; x&ltwidth; x++) { // repeat for each cell in row for (x=0; x&lt;width; x++) { // repeat for each cell in row
// First, count neighbors // First, count neighbors
// Point to upper left neighbor of current cell // Point to upper left neighbor of current cell
cell_ptr = base_cell_ptr; // pointer and bit mask for cell_ptr = base_cell_ptr; // pointer and bit mask for
mask = base_mask; // upper left neighbor mask = base_mask; // upper left neighbor
// Count upper left neighbor // Count upper left neighbor
neighbor_count = (*cell_ptr &amp mask) ? 1 : 0; neighbor_count = (*cell_ptr &amp; mask) ? 1 : 0;
// Count left neighbor // Count left neighbor
if ((*(cell_ptr + width_in_bytes) &amp mask)) neighbor_count++; if ((*(cell_ptr + width_in_bytes) &amp; mask)) neighbor_count++;
// Count lower left neighbor // Count lower left neighbor
if ((*(cell_ptr + width_in_bytesX2) &amp mask)) if ((*(cell_ptr + width_in_bytesX2) &amp; mask))
neighbor_count++; neighbor_count++;
// Point to upper neighbor // Point to upper neighbor
if ((mask &gt&gt= 1) == 0) { if ((mask &gt;&gt;= 1) == 0) {
mask = 0x80; mask = 0x80;
cell_ptr++; cell_ptr++;
} }
@ -86,25 +86,25 @@ neighbor_count++;
current_cell_ptr = cell_ptr + width_in_bytes; current_cell_ptr = cell_ptr + width_in_bytes;
current_mask = mask; current_mask = mask;
// Count upper neighbor // Count upper neighbor
if ((*cell_ptr &amp mask)) neighbor_count++; if ((*cell_ptr &amp; mask)) neighbor_count++;
// Count lower neighbor // Count lower neighbor
if ((*(cell_ptr + width_in_bytesX2) &amp mask)) if ((*(cell_ptr + width_in_bytesX2) &amp; mask))
neighbor_count++; neighbor_count++;
// Point to upper right neighbor // Point to upper right neighbor
if ((mask &gt&gt= 1) == 0) { if ((mask &gt;&gt;= 1) == 0) {
mask = 0x80; mask = 0x80;
cell_ptr++; cell_ptr++;
} }
// Count upper right neighbor // Count upper right neighbor
if ((*cell_ptr &amp mask)) neighbor_count++; if ((*cell_ptr &amp; mask)) neighbor_count++;
// Count right neighbor // Count right neighbor
if ((*(cell_ptr + width_in_bytes) &amp mask)) neighbor_count++; if ((*(cell_ptr + width_in_bytes) &amp; mask)) neighbor_count++;
// Count lower right neighbor // Count lower right neighbor
if ((*(cell_ptr + width_in_bytesX2) &amp mask)) if ((*(cell_ptr + width_in_bytesX2) &amp; mask))
neighbor_count++; neighbor_count++;
if (*current_cell_ptr &amp current_mask) { if (*current_cell_ptr &amp; current_mask) {
if ((neighbor_count != 2) &amp&amp (neighbor_count != 3)) { if ((neighbor_count != 2) &amp;&amp; (neighbor_count != 3)) {
*(dest_cell_ptr + (current_cell_ptr - cells)) &amp= *(dest_cell_ptr + (current_cell_ptr - cells)) &amp;=
~current_mask; // turn off cell ~current_mask; // turn off cell
draw_pixel(x, y, OFF_COLOR); draw_pixel(x, y, OFF_COLOR);
} }
@ -116,7 +116,7 @@ neighbor_count++;
} }
} }
// Advance to the next cell on row // Advance to the next cell on row
if ((base_mask &gt&gt= 1) == 0) { if ((base_mask &gt;&gt;= 1) == 0) {
base_mask = 0x80; base_mask = 0x80;
base_cell_ptr++; // advance to the next cell byte base_cell_ptr++; // advance to the next cell byte
} }

View file

@ -46,14 +46,14 @@
in this implementation. in this implementation.
Tested with Borland C++. To run, link with Listing 17.2 Tested with Borland C++. To run, link with Listing 17.2
in the large model. */ in the large model. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltiostream.h&gt #include &lt;iostream.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &lttime.h&gt #include &lt;time.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ltbios.h&gt #include &lt;bios.h&gt;
#include &ltmem.h&gt #include &lt;mem.h&gt;
#define ON_COLOR 15 // on-cell pixel color #define ON_COLOR 15 // on-cell pixel color
#define OFF_COLOR 0 // off-cell pixel color #define OFF_COLOR 0 // off-cell pixel color
@ -91,7 +91,7 @@ extern void show_text(int x, int y, char *text);
unsigned int cellmap_width = 96; unsigned int cellmap_width = 96;
unsigned int cellmap_height = 96; unsigned int cellmap_height = 96;
/* Width &amp height in pixels of each cell. */ /* Width &amp; height in pixels of each cell. */
unsigned int magnifier = 2; unsigned int magnifier = 2;
/* Randomizing seed */ /* Randomizing seed */
@ -112,7 +112,7 @@ void main()
// Keep recalculating and redisplaying generations until any key // Keep recalculating and redisplaying generations until any key
// is pressed // is pressed
show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;); show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;);
start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time); start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &amp;bios_time);
do { do {
generation++; generation++;
sprintf(gen_text, &ldquo;%10lu&rdquo;, generation); sprintf(gen_text, &ldquo;%10lu&rdquo;, generation);
@ -122,7 +122,7 @@ void main()
#if LIMIT_18_HZ #if LIMIT_18_HZ
// Limit to a maximum of 18.2 frames per second, for visibility // Limit to a maximum of 18.2 frames per second, for visibility
do { do {
_bios_timeofday(_TIME_GETCLOCK, &ampbios_time); _bios_timeofday(_TIME_GETCLOCK, &amp;bios_time);
} while (start_bios_time == bios_time); } while (start_bios_time == bios_time);
start_bios_time = bios_time; start_bios_time = bios_time;
#endif #endif
@ -130,8 +130,8 @@ void main()
getch(); // clear keypress getch(); // clear keypress
exit_display_mode(); exit_display_mode();
cout &lt&lt &ldquo;Total generations: &rdquo; &lt&lt generation &lt&lt &ldquo;\nSeed: &rdquo; &lt&lt cout &lt;&lt; &ldquo;Total generations: &rdquo; &lt;&lt; generation &lt;&lt; &ldquo;\nSeed: &rdquo; &lt;&lt;
seed &lt&lt &ldquo;\n&rdquo;; seed &lt;&lt; &ldquo;\n&rdquo;;
} }
/* cellmap constructor. */ /* cellmap constructor. */
@ -221,7 +221,7 @@ void cellmap::clear_cell(unsigned int x, unsigned int y)
else else
yobelow = w; yobelow = w;
*(cell_ptr) &amp= ~0x01; *(cell_ptr) &amp;= ~0x01;
*(cell_ptr + yoabove + xoleft) -= 2; *(cell_ptr + yoabove + xoleft) -= 2;
*(cell_ptr + yoabove ) -= 2; *(cell_ptr + yoabove ) -= 2;
*(cell_ptr + yoabove + xoright) -= 2; *(cell_ptr + yoabove + xoright) -= 2;
@ -238,7 +238,7 @@ int cellmap::cell_state(int x, int y)
unsigned char *cell_ptr; unsigned char *cell_ptr;
cell_ptr = cells + (y * width) + x; cell_ptr = cells + (y * width) + x;
return *cell_ptr &amp 0x01; return *cell_ptr &amp; 0x01;
} }
/* Calculates and displays the next generation of current_map */ /* Calculates and displays the next generation of current_map */
@ -254,7 +254,7 @@ void cellmap::next_generation()
// Process all cells in the current cell map // Process all cells in the current cell map
cell_ptr = temp_cells; // first cell in cell map cell_ptr = temp_cells; // first cell in cell map
for (y=0; y&lth; y++) { // repeat for each row of cells for (y=0; y&lt;h; y++) { // repeat for each row of cells
// Process all cells in the current row of the cell map // Process all cells in the current row of the cell map
x = 0; x = 0;
do { // repeat for each cell in row do { // repeat for each cell in row
@ -262,15 +262,15 @@ void cellmap::next_generation()
// neighbors as possible // neighbors as possible
while (*cell_ptr == 0) { while (*cell_ptr == 0) {
cell_ptr++; // advance to the next cell cell_ptr++; // advance to the next cell
if (++x &gt= w) goto RowDone; if (++x &gt;= w) goto RowDone;
} }
// Found a cell that&rsquo;s either on or has on-neighbors, // Found a cell that&rsquo;s either on or has on-neighbors,
// so see if its state needs to be changed // so see if its state needs to be changed
count = *cell_ptr &gt&gt 1; // # of neighboring on-cells count = *cell_ptr &gt;&gt; 1; // # of neighboring on-cells
if (*cell_ptr &amp 0x01) { if (*cell_ptr &amp; 0x01) {
// Cell is on; turn it off if it doesn&rsquo;t have // Cell is on; turn it off if it doesn&rsquo;t have
// 2 or 3 neighbors // 2 or 3 neighbors
if ((count != 2) &amp&amp (count != 3)) { if ((count != 2) &amp;&amp; (count != 3)) {
clear_cell(x, y); clear_cell(x, y);
draw_pixel(x, y, OFF_COLOR); draw_pixel(x, y, OFF_COLOR);
} }
@ -283,7 +283,7 @@ void cellmap::next_generation()
} }
// Advance to the next cell // Advance to the next cell
cell_ptr++; // advance to the next cell byte cell_ptr++; // advance to the next cell byte
} while (++x &lt w); } while (++x &lt; w);
RowDone: RowDone:
} }
} }
@ -294,14 +294,14 @@ void cellmap::init()
unsigned int x, y, init_length; unsigned int x, y, init_length;
// Get the seed; seed randomly if 0 entered // Get the seed; seed randomly if 0 entered
cout &lt&lt &ldquo;Seed (0 for random seed): &rdquo;; cout &lt;&lt; &ldquo;Seed (0 for random seed): &rdquo;;
cin &gt&gt seed; cin &gt;&gt; seed;
if (seed == 0) seed = (unsigned) time(NULL); if (seed == 0) seed = (unsigned) time(NULL);
// Randomly initialize the initial cell map to 50% on-pixels // Randomly initialize the initial cell map to 50% on-pixels
// (actually generally fewer, because some coordinates will be // (actually generally fewer, because some coordinates will be
// randomly selected more than once) // randomly selected more than once)
cout &lt&lt &ldquo;Initializing...&rdquo;; cout &lt;&lt; &ldquo;Initializing...&rdquo;;
srand(seed); srand(seed);
init_length = (height * width) / 2; init_length = (height * width) / 2;
do { do {

View file

@ -146,43 +146,43 @@ void BuildMaps( void )
do do
{ {
// Current cell states // Current cell states
C1 = (x &amp 0x0800) &gt;&gt; 11; C1 = (x &amp; 0x0800) &gt;&gt; 11;
C2 = (x &amp 0x0400) &gt;&gt; 10; C2 = (x &amp; 0x0400) &gt;&gt; 10;
C3 = (x &amp 0x0200) &gt;&gt; 9; C3 = (x &amp; 0x0200) &gt;&gt; 9;
// Neighbor counts // Neighbor counts
N1 = (x &amp 0x01C0) &gt;&gt; 6; N1 = (x &amp; 0x01C0) &gt;&gt; 6;
N2 = (x &amp 0x0038) &gt;&gt; 3; N2 = (x &amp; 0x0038) &gt;&gt; 3;
N3 = (x &amp 0x0007); N3 = (x &amp; 0x0007);
y = x &amp 0x8FFF; // Preserve all but the next generation states y = x &amp; 0x8FFF; // Preserve all but the next generation states
if( C1 &amp&amp ((N1 + C2 == 2) || (N1 + C2 == 3)) ) if( C1 &amp;&amp; ((N1 + C2 == 2) || (N1 + C2 == 3)) )
{ {
y |= 0x4000; y |= 0x4000;
} }
if( !C1 &amp&amp (N1 + C2 == 3) ) if( !C1 &amp;&amp; (N1 + C2 == 3) )
{ {
y |= 0x4000; y |= 0x4000;
} }
if( C2 &amp&amp ((N2 + C1 + C3 == 2) || (N2 + C1 + C3 == 3)) ) if( C2 &amp;&amp; ((N2 + C1 + C3 == 2) || (N2 + C1 + C3 == 3)) )
{ {
y |= 0x2000; y |= 0x2000;
} }
if( !C2 &amp&amp (N2 + C1 + C3 == 3) ) if( !C2 &amp;&amp; (N2 + C1 + C3 == 3) )
{ {
y |= 0x2000; y |= 0x2000;
} }
if( C3 &amp&amp ((N3 + C2 == 2) || (N3 + C2 == 3)) ) if( C3 &amp;&amp; ((N3 + C2 == 2) || (N3 + C2 == 3)) )
{ {
y |= 0x1000; y |= 0x1000;
} }
if( !C3 &amp&amp (N3 + C2 == 3) ) if( !C3 &amp;&amp; (N3 + C2 == 3) )
{ {
y |= 0x1000; y |= 0x1000;
} }
@ -227,58 +227,58 @@ void FirstPass( void )
printf( &ldquo;mov bh,0\n&rdquo; ); printf( &ldquo;mov bh,0\n&rdquo; );
printf( &ldquo;add bx,ax\n&rdquo; ); // bx = screen offset printf( &ldquo;add bx,ax\n&rdquo; ); // bx = screen offset
if( ((New ^ Old) &amp 6) == 6 ) if( ((New ^ Old) &amp; 6) == 6 )
{ {
printf( &ldquo;mov word ptr fs:[bx],0%02x%02xh\n&rdquo;, printf( &ldquo;mov word ptr fs:[bx],0%02x%02xh\n&rdquo;,
(New &amp 2) ? 15 : 0, (New &amp; 2) ? 15 : 0,
(New &amp 4) ? 15 : 0 ); (New &amp; 4) ? 15 : 0 );
if( (New ^ Old) &amp 1 ) if( (New ^ Old) &amp; 1 )
{ {
printf( &ldquo;mov byte ptr fs:[bx+2],%s\n&rdquo;, printf( &ldquo;mov byte ptr fs:[bx+2],%s\n&rdquo;,
(New &amp 1) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; ); (New &amp; 1) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; );
} }
} }
else else
{ {
if( ((New ^ Old) &amp 3) == 3 ) if( ((New ^ Old) &amp; 3) == 3 )
{ {
printf( &ldquo;mov word ptr fs:[bx+1],0%02x%02xh\n&rdquo;, printf( &ldquo;mov word ptr fs:[bx+1],0%02x%02xh\n&rdquo;,
(New &amp 1) ? 15 : 0, (New &amp; 1) ? 15 : 0,
(New &amp 2) ? 15 : 0 ); (New &amp; 2) ? 15 : 0 );
} }
else else
{ {
if( (New ^ Old) &amp 2 ) if( (New ^ Old) &amp; 2 )
{ {
printf( &ldquo;mov byte ptr fs:[bx+1],%s\n&rdquo;, printf( &ldquo;mov byte ptr fs:[bx+1],%s\n&rdquo;,
(New &amp 2) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; ); (New &amp; 2) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; );
} }
if( (New ^ Old) &amp 1 ) if( (New ^ Old) &amp; 1 )
{ {
printf( &ldquo;mov byte ptr fs:[bx+2],%s\n&rdquo;, printf( &ldquo;mov byte ptr fs:[bx+2],%s\n&rdquo;,
(New &amp 1) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; ); (New &amp; 1) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; );
} }
} }
if( (New ^ Old) &amp 4 ) if( (New ^ Old) &amp; 4 )
{ {
printf( &ldquo;mov byte ptr fs:[bx],%s\n&rdquo;, printf( &ldquo;mov byte ptr fs:[bx],%s\n&rdquo;,
(New &amp 4) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; ); (New &amp; 4) ? &ldquo;15&rdquo; : &ldquo;dl&rdquo; );
} }
} }
#endif #endif
if( (New ^ Old) &amp 4 ) UpDown += (New &amp 4) ? 0x48 : -0x48; if( (New ^ Old) &amp; 4 ) UpDown += (New &amp; 4) ? 0x48 : -0x48;
if( (New ^ Old) &amp 2 ) UpDown += (New &amp 2) ? 0x49 : -0x49; if( (New ^ Old) &amp; 2 ) UpDown += (New &amp; 2) ? 0x49 : -0x49;
if( (New ^ Old) &amp 1 ) UpDown += (New &amp 1) ? 0x09 : -0x09; if( (New ^ Old) &amp; 1 ) UpDown += (New &amp; 1) ? 0x09 : -0x09;
if( Edge ) if( Edge )
{ {
GetUpAndDown(); // ah = row, al = col, cx = up, dx = down GetUpAndDown(); // ah = row, al = col, cx = up, dx = down
if( (New ^ Old) &amp 4 ) if( (New ^ Old) &amp; 4 )
{ {
printf( &ldquo;mov di,%d\n&rdquo;, WRAPLEFT ); // di = left printf( &ldquo;mov di,%d\n&rdquo;, WRAPLEFT ); // di = left
printf( &ldquo;cmp al,0\n&rdquo; ); printf( &ldquo;cmp al,0\n&rdquo; );
@ -286,7 +286,7 @@ void FirstPass( void )
printf( &ldquo;mov di,%d\n&rdquo;, LEFT ); printf( &ldquo;mov di,%d\n&rdquo;, LEFT );
printf( &ldquo;L%d:\n&rdquo;, Label ); printf( &ldquo;L%d:\n&rdquo;, Label );
if( New &amp 4 ) Op = &ldquo;inc&rdquo;; if( New &amp; 4 ) Op = &ldquo;inc&rdquo;;
else Op = &ldquo;dec&rdquo;; else Op = &ldquo;dec&rdquo;;
printf( &ldquo;%s word ptr [bp+di]\n&rdquo;, Op ); printf( &ldquo;%s word ptr [bp+di]\n&rdquo;, Op );
@ -297,7 +297,7 @@ void FirstPass( void )
printf( &ldquo;%s word ptr [bp+di]\n&rdquo;, Op ); printf( &ldquo;%s word ptr [bp+di]\n&rdquo;, Op );
} }
if( (New ^ Old) &amp 1 ) if( (New ^ Old) &amp; 1 )
{ {
printf( &ldquo;mov di,%d\n&rdquo;, WRAPRIGHT ); // di = right printf( &ldquo;mov di,%d\n&rdquo;, WRAPRIGHT ); // di = right
printf( &ldquo;cmp al,%d\n&rdquo;, (WIDTH - 1) * 3 ); printf( &ldquo;cmp al,%d\n&rdquo;, (WIDTH - 1) * 3 );
@ -305,7 +305,7 @@ void FirstPass( void )
printf( &ldquo;mov di,%d\n&rdquo;, RIGHT ); printf( &ldquo;mov di,%d\n&rdquo;, RIGHT );
printf( &ldquo;R%d:\n&rdquo;, Label ); printf( &ldquo;R%d:\n&rdquo;, Label );
if( New &amp 1 ) Op = &ldquo;add&rdquo;; if( New &amp; 1 ) Op = &ldquo;add&rdquo;;
else Op = &ldquo;sub&rdquo;; else Op = &ldquo;sub&rdquo;;
printf( &ldquo;%s word ptr [bp+di],40h\n&rdquo;, Op ); printf( &ldquo;%s word ptr [bp+di],40h\n&rdquo;, Op );
@ -325,9 +325,9 @@ void FirstPass( void )
} }
else else
{ {
if( (New ^ Old) &amp 4 ) if( (New ^ Old) &amp; 4 )
{ {
if( New &amp 4 ) Op = &ldquo;inc&rdquo;; if( New &amp; 4 ) Op = &ldquo;inc&rdquo;;
else Op = &ldquo;dec&rdquo;; else Op = &ldquo;dec&rdquo;;
printf( &ldquo;%s byte ptr [bp+%d]\n&rdquo;, Op, LEFT ); printf( &ldquo;%s byte ptr [bp+%d]\n&rdquo;, Op, LEFT );
@ -335,9 +335,9 @@ void FirstPass( void )
printf( &ldquo;%s byte ptr [bp+%d]\n&rdquo;, Op, LOWERLEFT ); printf( &ldquo;%s byte ptr [bp+%d]\n&rdquo;, Op, LOWERLEFT );
} }
if( (New ^ Old) &amp 1 ) if( (New ^ Old) &amp; 1 )
{ {
if( New &amp 1 ) Op = &ldquo;add&rdquo;; if( New &amp; 1 ) Op = &ldquo;add&rdquo;;
else Op = &ldquo;sub&rdquo;; else Op = &ldquo;sub&rdquo;;
printf( &ldquo;%s word ptr [bp+%d],40h\n&rdquo;, Op, RIGHT ); printf( &ldquo;%s word ptr [bp+%d],40h\n&rdquo;, Op, RIGHT );
@ -393,7 +393,7 @@ void SecondPass( void )
if( Edge ) if( Edge )
{ {
// finished with second pass // finished with second pass
if( New == 7 &amp&amp Old == 0 ) if( New == 7 &amp;&amp; Old == 0 )
{ {
printf( &ldquo;cmp bp,offset DGROUP:ChangeCell\n&rdquo; ); printf( &ldquo;cmp bp,offset DGROUP:ChangeCell\n&rdquo; );
printf( &ldquo;jne short NotEnd\n&rdquo; ); printf( &ldquo;jne short NotEnd\n&rdquo; );

View file

@ -70,9 +70,9 @@ void InitCellmap( void )
for( i = j = 0; i &lt; WIDTH * HEIGHT; i++ ) for( i = j = 0; i &lt; WIDTH * HEIGHT; i++ )
{ {
if( CellMap[ i ] &amp 0x7000 ) if( CellMap[ i ] &amp; 0x7000 )
{ {
ChangeList1[ j++ ] = (short)&ampCellMap[ i ]; ChangeList1[ j++ ] = (short)&amp;CellMap[ i ];
} }
} }
@ -87,7 +87,7 @@ void main( void )
unsigned int seed; unsigned int seed;
printf( &ldquo;Seed (0 for random seed): &rdquo; ); printf( &ldquo;Seed (0 for random seed): &rdquo; );
scanf( &ldquo;%d&rdquo;, &ampseed ); scanf( &ldquo;%d&rdquo;, &amp;seed );
if( seed == 0 ) seed = (unsigned) time(NULL); if( seed == 0 ) seed = (unsigned) time(NULL);
srand( seed ); srand( seed );
@ -98,7 +98,7 @@ void main( void )
InitCellmap(); // randomly initialize cell map InitCellmap(); // randomly initialize cell map
_bios_timeofday( _TIME_GETCLOCK, &ampstart_time ); _bios_timeofday( _TIME_GETCLOCK, &amp;start_time );
do do
{ {
@ -116,7 +116,7 @@ void main( void )
while( !kbhit() ); while( !kbhit() );
#endif #endif
_bios_timeofday( _TIME_GETCLOCK, &ampend_time ); _bios_timeofday( _TIME_GETCLOCK, &amp;end_time );
end_time -= start_time; end_time -= start_time;
#ifndef NODRAW #ifndef NODRAW
@ -151,7 +151,7 @@ void enter_display_mode()
union REGS regset; union REGS regset;
regset.x.ax = 0x0013; regset.x.ax = 0x0013;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
/* Text mode mode-set function. */ /* Text mode mode-set function. */
@ -160,7 +160,7 @@ void exit_display_mode()
union REGS regset; union REGS regset;
regset.x.ax = 0x0003; regset.x.ax = 0x0003;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
/* Text display function. Offsets text to non-graphics area of /* Text display function. Offsets text to non-graphics area of

View file

@ -48,7 +48,7 @@
; Returns checksum in AX. ; Returns checksum in AX.
; ECX and ESI destroyed. ; ECX and ESI destroyed.
; All cycle counts assume 32-bit protected mode. ; All cycle counts assume 32-bit protected mode.
; Assumes buffer length &gt 0. ; Assumes buffer length &gt; 0.
; Note that timing indicates that the pipe sequence and ; Note that timing indicates that the pipe sequence and
; cycle counts shown (based on documented execution rules) ; cycle counts shown (based on documented execution rules)
; differ from the actual execution sequence and cycle counts; ; differ from the actual execution sequence and cycle counts;

View file

@ -46,7 +46,7 @@
; Returns checksum in AX. ; Returns checksum in AX.
; High word of EAX, DX, ECX and ESI destroyed. ; High word of EAX, DX, ECX and ESI destroyed.
; All cycle counts assume 32-bit protected mode. ; All cycle counts assume 32-bit protected mode.
; Assumes buffer length &gt 0. ; Assumes buffer length &gt; 0.
sub eax,eax ;initialize the checksum sub eax,eax ;initialize the checksum
mov dx,[esi] ;first word to checksum mov dx,[esi] ;first word to checksum
@ -78,7 +78,7 @@ ckloopend:
; Returns checksum in AX. ; Returns checksum in AX.
; High word of EAX, BX, EDX, ECX and ESI destroyed. ; High word of EAX, BX, EDX, ECX and ESI destroyed.
; All cycle counts assume 32-bit protected mode. ; All cycle counts assume 32-bit protected mode.
; Assumes buffer length &gt 0. ; Assumes buffer length &gt; 0.
sub eax,eax ;initialize the checksum sub eax,eax ;initialize the checksum
sub edx,edx ;prepare for later ORing sub edx,edx ;prepare for later ORing

View file

@ -45,7 +45,7 @@
; High word of EAX, ECX, EDX, and ESI destroyed. ; High word of EAX, ECX, EDX, and ESI destroyed.
; All cycle counts assume 32-bit protected mode. ; All cycle counts assume 32-bit protected mode.
; Assumes buffer starts on a dword boundary, is a dword multiple ; Assumes buffer starts on a dword boundary, is a dword multiple
; in length, and length &gt 0. ; in length, and length &gt; 0.
sub eax,eax ;initialize the checksum sub eax,eax ;initialize the checksum
shr ecx,1 ;we&rsquo;ll do two words per loop shr ecx,1 ;we&rsquo;ll do two words per loop
@ -82,7 +82,7 @@ ckloopend:
; High word of EAX, EBX, ECX, EDX, and ESI destroyed. ; High word of EAX, EBX, ECX, EDX, and ESI destroyed.
; All cycle counts assume 32-bit protected mode. ; All cycle counts assume 32-bit protected mode.
; Assumes buffer starts on a dword boundary, is a dword multiple ; Assumes buffer starts on a dword boundary, is a dword multiple
; in length, and length &gt 0. ; in length, and length &gt; 0.
sub eax,eax ;initialize the checksum sub eax,eax ;initialize the checksum
shr ecx,2 ;we&rsquo;ll do two dwords per loop shr ecx,2 ;we&rsquo;ll do two dwords per loop

View file

@ -189,7 +189,7 @@ PanningXInc dw 1 ;x panning factor
PanningYInc dw 0 ;y panning factor PanningYInc dw 0 ;y panning factor
HPan db 0 ;horizontal pel panning setting HPan db 0 ;horizontal pel panning setting
PanningStartOffset dw 0 ;start offset adjustment to produce vertical PanningStartOffset dw 0 ;start offset adjustment to produce vertical
; panning &amp coarse horizontal panning ; panning &amp; coarse horizontal panning
dseg ends dseg ends
; ;
; Macro to set indexed register P2 of chip with index register ; Macro to set indexed register P2 of chip with index register

View file

@ -190,7 +190,7 @@ BackgroundLoop:
TEXT_UP FillPatternVert, FILL_PATTERN_VERT_LENGTH, 15, 42 TEXT_UP FillPatternVert, FILL_PATTERN_VERT_LENGTH, 15, 42
TEXT_UP FillPatternHorz, FILL_PATTERN_HORZ_LENGTH, 21, 42 TEXT_UP FillPatternHorz, FILL_PATTERN_HORZ_LENGTH, 21, 42
; ;
; Wait until a key&rsquo;s been hit to reset screen mode &amp exit. ; Wait until a key&rsquo;s been hit to reset screen mode &amp; exit.
; ;
WaitForKey: WaitForKey:
mov ah,1 mov ah,1

View file

@ -146,7 +146,7 @@ Start endp
; DS:SI = pointer to chunky image to draw, as follows: ; DS:SI = pointer to chunky image to draw, as follows:
; word at 0: width of image, in pixels ; word at 0: width of image, in pixels
; word at 2: height of image, in pixels ; word at 2: height of image, in pixels
; byte at 4: msb/lsb = first &amp second chunky pixels, ; byte at 4: msb/lsb = first &amp; second chunky pixels,
; repeating for the remainder of the scan line ; repeating for the remainder of the scan line
; of the image, then for all scan lines. Images ; of the image, then for all scan lines. Images
; with odd widths have an unused null nibble ; with odd widths have an unused null nibble

View file

@ -80,7 +80,7 @@ ImagePlane1 db 32*4 dup (?)
ImagePlane2 db 32*4 dup (?) ImagePlane2 db 32*4 dup (?)
ImagePlane3 db 32*4 dup (?) ImagePlane3 db 32*4 dup (?)
; ;
; Current image location &amp direction. ; Current image location &amp; direction.
; ;
ImageX dw 40 ;in bytes ImageX dw 40 ;in bytes
ImageY dw 100 ;in pixels ImageY dw 100 ;in pixels

View file

@ -107,7 +107,7 @@ loopVLineLoop
mov al,GRAPHICS_MODE mov al,GRAPHICS_MODE
out dx,al ;point GC Index to Graphics Mode register out dx,al ;point GC Index to Graphics Mode register
inc dx ;point to GC Data inc dx ;point to GC Data
mov al,00001000b ;bit 3=1 is read mode 1, bits 1 &amp 0=00 mov al,00001000b ;bit 3=1 is read mode 1, bits 1 &amp; 0=00
; is write mode 0 ; is write mode 0
out dx,al ;set Graphics Mode to read mode 1, out dx,al ;set Graphics Mode to read mode 1,
; write mode 0 ; write mode 0

View file

@ -79,7 +79,7 @@ Startprocnear
inc dx inc dx
in al,dx ;VGA registers are readable, bless them! in al,dx ;VGA registers are readable, bless them!
or al,00001011b ;bit 3=1 selects read mode 1, and or al,00001011b ;bit 3=1 selects read mode 1, and
; bits 1 &amp 0=11 selects write mode 3 ; bits 1 &amp; 0=11 selects write mode 3
jmp $+2 ;delay between IN and OUT to same port jmp $+2 ;delay between IN and OUT to same port
out dx,al out dx,al
dec dx dec dx

View file

@ -86,15 +86,15 @@ LineControl ends
; List of descriptors for lines to draw. ; List of descriptors for lines to draw.
; ;
LineList label LineControl LineList label LineControl
LineControl &lt130,110,1,0,60,0&gt LineControl &lt;130,110,1,0,60,0&gt;
LineControl &lt190,110,1,1,60,1&gt LineControl &lt;190,110,1,1,60,1&gt;
LineControl &lt250,170,0,1,60,2&gt LineControl &lt;250,170,0,1,60,2&gt;
LineControl &lt250,230,-1,1,60,3&gt LineControl &lt;250,230,-1,1,60,3&gt;
LineControl &lt190,290,-1,0,60,4&gt LineControl &lt;190,290,-1,0,60,4&gt;
LineControl &lt130,290,-1,-1,60,5&gt LineControl &lt;130,290,-1,-1,60,5&gt;
LineControl &lt70,230,0,-1,60,6&gt LineControl &lt;70,230,0,-1,60,6&gt;
LineControl &lt70,170,1,-1,60,7&gt LineControl &lt;70,170,1,-1,60,7&gt;
LineControl &lt-1,0,0,0,0,0&gt LineControl &lt;-1,0,0,0,0,0&gt;
Data ends Data ends
; ;
; Macro to output a word value to a port. ; Macro to output a word value to a port.

View file

@ -85,7 +85,7 @@ int Color; /* color in which to draw line */
while ( DeltaX-- ) { while ( DeltaX-- ) {
/* See if it&rsquo;s time to advance the Y coordinate */ /* See if it&rsquo;s time to advance the Y coordinate */
if ( ErrorTerm &gt;= 0 ) { if ( ErrorTerm &gt;= 0 ) {
/* Advance the Y coordinate &amp adjust the error term /* Advance the Y coordinate &amp; adjust the error term
back down */ back down */
Y0++; Y0++;
ErrorTerm += DeltaYx2MinusDeltaXx2; ErrorTerm += DeltaYx2MinusDeltaXx2;
@ -122,7 +122,7 @@ int Color; /* color in which to draw line */
while ( DeltaY-- ) { while ( DeltaY-- ) {
/* See if it&rsquo;s time to advance the X coordinate */ /* See if it&rsquo;s time to advance the X coordinate */
if ( ErrorTerm &gt;= 0 ) { if ( ErrorTerm &gt;= 0 ) {
/* Advance the X coordinate &amp adjust the error term /* Advance the X coordinate &amp; adjust the error term
back down */ back down */
X0 += XDirection; X0 += XDirection;
ErrorTerm += DeltaXx2MinusDeltaYx2; ErrorTerm += DeltaXx2MinusDeltaYx2;
@ -233,7 +233,7 @@ void main()
VectorsUp(X_MAX * 3 / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 4); VectorsUp(X_MAX * 3 / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 4);
/* Wait for the enter key to be pressed */ /* Wait for the enter key to be pressed */
scanf(&ldquo;%c&rdquo;, &amptemp); scanf(&ldquo;%c&rdquo;, &amp;temp);
/* Back to text mode */ /* Back to text mode */
_AX = TEXT_MODE; _AX = TEXT_MODE;

View file

@ -86,7 +86,7 @@ unsigned int Y0; /* (0,0) at the upper left of the screen */
/* Generate a mask with a 1 bit in the pixel&rsquo;s position within the /* Generate a mask with a 1 bit in the pixel&rsquo;s position within the
screen byte */ screen byte */
PixelMask = 0x80 &gt;&gt; ( X0 &amp 0x07 ); PixelMask = 0x80 &gt;&gt; ( X0 &amp; 0x07 );
/* Set up the Graphics Controller&rsquo;s Bit Mask register to allow /* Set up the Graphics Controller&rsquo;s Bit Mask register to allow
only the bit corresponding to the pixel being drawn to only the bit corresponding to the pixel being drawn to
@ -124,7 +124,7 @@ int XDirection; /* 1 if line is drawn left to right,
while ( DeltaX&mdash; ) { while ( DeltaX&mdash; ) {
/* See if it&rsquo;s time to advance the Y coordinate */ /* See if it&rsquo;s time to advance the Y coordinate */
if ( ErrorTerm &gt;= 0 ) { if ( ErrorTerm &gt;= 0 ) {
/* Advance the Y coordinate &amp adjust the error term /* Advance the Y coordinate &amp; adjust the error term
back down */ back down */
Y0++; Y0++;
ErrorTerm += DeltaYx2MinusDeltaXx2; ErrorTerm += DeltaYx2MinusDeltaXx2;
@ -159,7 +159,7 @@ int XDirection; /* 1 if line is drawn left to right,
while ( DeltaY&mdash; ) { while ( DeltaY&mdash; ) {
/* See if it&rsquo;s time to advance the X coordinate */ /* See if it&rsquo;s time to advance the X coordinate */
if ( ErrorTerm &gt;= 0 ) { if ( ErrorTerm &gt;= 0 ) {
/* Advance the X coordinate &amp adjust the error term /* Advance the X coordinate &amp; adjust the error term
back down */ back down */
X0 += XDirection; X0 += XDirection;
ErrorTerm += DeltaXx2MinusDeltaYx2; ErrorTerm += DeltaXx2MinusDeltaYx2;

View file

@ -116,7 +116,7 @@ void main()
Y_MAX / 4, 4); Y_MAX / 4, 4);
/* Wait for the enter key to be pressed */ /* Wait for the enter key to be pressed */
scanf(&ldquo;%c&rdquo;, &amptemp); scanf(&ldquo;%c&rdquo;, &amp;temp);
/* Return back to text mode */ /* Return back to text mode */
_AX = TEXT_MODE; _AX = TEXT_MODE;

View file

@ -156,7 +156,7 @@ endif
; in this byte when pixel mask wraps. ; in this byte when pixel mask wraps.
; ;
MoveXCoord: MoveXCoord:
add bp,bx ;increment error term &amp keep same add bp,bx ;increment error term &amp; keep same
if MOVE_LEFT if MOVE_LEFT
rol ah,1 ;move pixel mask 1 pixel to the left rol ah,1 ;move pixel mask 1 pixel to the left
else else
@ -218,7 +218,7 @@ LINE2 macro MOVE_LEFT
sub bx,si ;DeltaX * 2 - DeltaY * 2 (used in loop) sub bx,si ;DeltaX * 2 - DeltaY * 2 (used in loop)
add si,bx ;DeltaX * 2 (used in loop) add si,bx ;DeltaX * 2 (used in loop)
; ;
; Set up initial bit mask &amp write initial pixel. ; Set up initial bit mask &amp; write initial pixel.
; ;
out dx,al out dx,al
xchg byte ptr [di],ah xchg byte ptr [di],ah
@ -232,7 +232,7 @@ LineLoop:
; ;
and bp,bp ;see if error term is negative and bp,bp ;see if error term is negative
jns ETermAction ;no, advance X coordinate jns ETermAction ;no, advance X coordinate
add bp,si ;increment error term &amp keep same add bp,si ;increment error term &amp; keep same
jmp short MoveYCoord ; X coordinate jmp short MoveYCoord ; X coordinate
ETermAction: ETermAction:
; ;

View file

@ -48,10 +48,10 @@
<P>Second, when performance matters, never have your code perform the same calculation more than once. This sounds obvious, but it&rsquo;s astonishing how often it&rsquo;s ignored. For example, consider this snippet of code:</P> <P>Second, when performance matters, never have your code perform the same calculation more than once. This sounds obvious, but it&rsquo;s astonishing how often it&rsquo;s ignored. For example, consider this snippet of code:</P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
for (i=0; i&ltRunLength; i++) for (i=0; i&lt;RunLength; i++)
{ {
*WorkingScreenPtr = Color; *WorkingScreenPtr = Color;
if (XDelta &gt 0) if (XDelta &gt; 0)
{ {
WorkingScreenPtr++; WorkingScreenPtr++;
} }
@ -67,16 +67,16 @@ for (i=0; i&ltRunLength; i++)
</P> </P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
if (XDelta &gt 0) if (XDelta &gt; 0)
{ {
for (i=0; i&ltRunLength; i++) for (i=0; i&lt;RunLength; i++)
{ {
*WorkingScreenPtr++ = Color; *WorkingScreenPtr++ = Color;
} }
} }
else else
{ {
for (i=0; i&ltRunLength; i++) for (i=0; i&lt;RunLength; i++)
{ {
*WorkingScreenPtr-- = Color; *WorkingScreenPtr-- = Color;
} }

View file

@ -53,7 +53,7 @@
320x200 256-color mode. Not optimized! Tested with Borland C++ in 320x200 256-color mode. Not optimized! Tested with Borland C++ in
the small model. */ the small model. */
#include &ltdos.h&gt #include &lt;dos.h&gt;
#define SCREEN_WIDTH 320 #define SCREEN_WIDTH 320
#define SCREEN_SEGMENT 0xA000 #define SCREEN_SEGMENT 0xA000
@ -71,7 +71,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
/* We&rsquo;ll always draw top to bottom, to reduce the number of cases we have to /* We&rsquo;ll always draw top to bottom, to reduce the number of cases we have to
handle, and to make lines between the same endpoints draw the same pixels */ handle, and to make lines between the same endpoints draw the same pixels */
if (YStart &gt YEnd) { if (YStart &gt; YEnd) {
Temp = YStart; Temp = YStart;
YStart = YEnd; YStart = YEnd;
YEnd = Temp; YEnd = Temp;
@ -84,7 +84,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
/* Figure out whether we&rsquo;re going left or right, and how far we&rsquo;re /* Figure out whether we&rsquo;re going left or right, and how far we&rsquo;re
going horizontally */ going horizontally */
if ((XDelta = XEnd - XStart) &lt 0) if ((XDelta = XEnd - XStart) &lt; 0)
{ {
XAdvance = -1; XAdvance = -1;
XDelta = -XDelta; XDelta = -XDelta;
@ -101,7 +101,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
if (XDelta == 0) if (XDelta == 0)
{ {
/* Vertical line */ /* Vertical line */
for (i=0; i&lt=YDelta; i++) for (i=0; i&lt;=YDelta; i++)
{ {
*ScreenPtr = Color; *ScreenPtr = Color;
ScreenPtr += SCREEN_WIDTH; ScreenPtr += SCREEN_WIDTH;
@ -111,7 +111,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
if (YDelta == 0) if (YDelta == 0)
{ {
/* Horizontal line */ /* Horizontal line */
for (i=0; i&lt=XDelta; i++) for (i=0; i&lt;=XDelta; i++)
{ {
*ScreenPtr = Color; *ScreenPtr = Color;
ScreenPtr += XAdvance; ScreenPtr += XAdvance;
@ -121,7 +121,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
if (XDelta == YDelta) if (XDelta == YDelta)
{ {
/* Diagonal line */ /* Diagonal line */
for (i=0; i&lt=XDelta; i++) for (i=0; i&lt;=XDelta; i++)
{ {
*ScreenPtr = Color; *ScreenPtr = Color;
ScreenPtr += XAdvance + SCREEN_WIDTH; ScreenPtr += XAdvance + SCREEN_WIDTH;
@ -130,7 +130,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
} }
/* Determine whether the line is X or Y major, and handle accordingly */ /* Determine whether the line is X or Y major, and handle accordingly */
if (XDelta &gt= YDelta) if (XDelta &gt;= YDelta)
{ {
/* X major line */ /* X major line */
/* Minimum # of pixels in a run in this line */ /* Minimum # of pixels in a run in this line */
@ -159,35 +159,35 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
advance, we have one pixel that could go to either the initial advance, we have one pixel that could go to either the initial
or last partial run, which we&rsquo;ll arbitrarily allocate to the or last partial run, which we&rsquo;ll arbitrarily allocate to the
last run */ last run */
if ((AdjUp == 0) &amp&amp ((WholeStep &amp 0x01) == 0)) if ((AdjUp == 0) &amp;&amp; ((WholeStep &amp; 0x01) == 0))
{ {
InitialPixelCount--; InitialPixelCount--;
} }
/* If there&rsquo;re an odd number of pixels per run, we have 1 pixel that can&rsquo;t /* If there&rsquo;re an odd number of pixels per run, we have 1 pixel that can&rsquo;t
be allocated to either the initial or last partial run, so we&rsquo;ll add 0.5 be allocated to either the initial or last partial run, so we&rsquo;ll add 0.5
to error term so this pixel will be handled by the normal full-run loop */ to error term so this pixel will be handled by the normal full-run loop */
if ((WholeStep &amp 0x01) != 0) if ((WholeStep &amp; 0x01) != 0)
{ {
ErrorTerm += YDelta; ErrorTerm += YDelta;
} }
/* Draw the first, partial run of pixels */ /* Draw the first, partial run of pixels */
DrawHorizontalRun(&ampScreenPtr, XAdvance, InitialPixelCount, Color); DrawHorizontalRun(&amp;ScreenPtr, XAdvance, InitialPixelCount, Color);
/* Draw all full runs */ /* Draw all full runs */
for (i=0; i&lt(YDelta-1); i++) for (i=0; i&lt;(YDelta-1); i++)
{ {
RunLength = WholeStep; /* run is at least this long */ RunLength = WholeStep; /* run is at least this long */
/* Advance the error term and add an extra pixel if the error /* Advance the error term and add an extra pixel if the error
term so indicates */ term so indicates */
if ((ErrorTerm += AdjUp) &gt 0) if ((ErrorTerm += AdjUp) &gt; 0)
{ {
RunLength++; RunLength++;
ErrorTerm -= AdjDown; /* reset the error term */ ErrorTerm -= AdjDown; /* reset the error term */
} }
/* Draw this scan line&rsquo;s run */ /* Draw this scan line&rsquo;s run */
DrawHorizontalRun(&ampScreenPtr, XAdvance, RunLength, Color); DrawHorizontalRun(&amp;ScreenPtr, XAdvance, RunLength, Color);
} }
/* Draw the final run of pixels */ /* Draw the final run of pixels */
DrawHorizontalRun(&ampScreenPtr, XAdvance, FinalPixelCount, Color); DrawHorizontalRun(&amp;ScreenPtr, XAdvance, FinalPixelCount, Color);
return; return;
} }
else else
@ -218,7 +218,7 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
/* If the basic run length is even and there&rsquo;s no fractional advance, we /* If the basic run length is even and there&rsquo;s no fractional advance, we
have 1 pixel that could go to either the initial or last partial run, have 1 pixel that could go to either the initial or last partial run,
which we&rsquo;ll arbitrarily allocate to the last run */ which we&rsquo;ll arbitrarily allocate to the last run */
if ((AdjUp == 0) &amp&amp ((WholeStep &amp 0x01) == 0)) if ((AdjUp == 0) &amp;&amp; ((WholeStep &amp; 0x01) == 0))
{ {
InitialPixelCount--; InitialPixelCount--;
} }
@ -226,29 +226,29 @@ void LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
that can&rsquo;t be allocated to either the initial or last partial that can&rsquo;t be allocated to either the initial or last partial
run, so we&rsquo;ll add 0.5 to the error term so this pixel will be run, so we&rsquo;ll add 0.5 to the error term so this pixel will be
handled by the normal full-run loop */ handled by the normal full-run loop */
if ((WholeStep &amp 0x01) != 0) if ((WholeStep &amp; 0x01) != 0)
{ {
ErrorTerm += XDelta; ErrorTerm += XDelta;
} }
/* Draw the first, partial run of pixels */ /* Draw the first, partial run of pixels */
DrawVerticalRun(&ampScreenPtr, XAdvance, InitialPixelCount, Color); DrawVerticalRun(&amp;ScreenPtr, XAdvance, InitialPixelCount, Color);
/* Draw all full runs */ /* Draw all full runs */
for (i=0; i&lt(XDelta-1); i++) for (i=0; i&lt;(XDelta-1); i++)
{ {
RunLength = WholeStep; /* run is at least this long */ RunLength = WholeStep; /* run is at least this long */
/* Advance the error term and add an extra pixel if the error /* Advance the error term and add an extra pixel if the error
term so indicates */ term so indicates */
if ((ErrorTerm += AdjUp) &gt 0) if ((ErrorTerm += AdjUp) &gt; 0)
{ {
RunLength++; RunLength++;
ErrorTerm -= AdjDown; /* reset the error term */ ErrorTerm -= AdjDown; /* reset the error term */
} }
/* Draw this scan line&rsquo;s run */ /* Draw this scan line&rsquo;s run */
DrawVerticalRun(&ampScreenPtr, XAdvance, RunLength, Color); DrawVerticalRun(&amp;ScreenPtr, XAdvance, RunLength, Color);
} }
/* Draw the final run of pixels */ /* Draw the final run of pixels */
DrawVerticalRun(&ampScreenPtr, XAdvance, FinalPixelCount, Color); DrawVerticalRun(&amp;ScreenPtr, XAdvance, FinalPixelCount, Color);
return; return;
} }
} }
@ -260,7 +260,7 @@ void DrawHorizontalRun(char far **ScreenPtr, int XAdvance,
int i; int i;
char far *WorkingScreenPtr = *ScreenPtr; char far *WorkingScreenPtr = *ScreenPtr;
for (i=0; i&ltRunLength; i++) for (i=0; i&lt;RunLength; i++)
{ {
*WorkingScreenPtr = Color; *WorkingScreenPtr = Color;
WorkingScreenPtr += XAdvance; WorkingScreenPtr += XAdvance;
@ -277,7 +277,7 @@ void DrawVerticalRun(char far **ScreenPtr, int XAdvance,
int i; int i;
char far *WorkingScreenPtr = *ScreenPtr; char far *WorkingScreenPtr = *ScreenPtr;
for (i=0; i&ltRunLength; i++) for (i=0; i&lt;RunLength; i++)
{ {
*WorkingScreenPtr = Color; *WorkingScreenPtr = Color;
WorkingScreenPtr += SCREEN_WIDTH; WorkingScreenPtr += SCREEN_WIDTH;

View file

@ -44,7 +44,7 @@
line-drawing functions coded in LListing L36.1.C. line-drawing functions coded in LListing L36.1.C.
Tested with Borland C++ in the small model. */ Tested with Borland C++ in the small model. */
#include &ltdos.h&gt #include &lt;dos.h&gt;
#define GRAPHICS_MODE 0x13 #define GRAPHICS_MODE 0x13
#define TEXT_MODE 0x03 #define TEXT_MODE 0x03
@ -66,28 +66,28 @@ int Color; /* color to draw lines in */
/* lines from center to top of rectangle */ /* lines from center to top of rectangle */
WorkingX = XCenter - XLength; WorkingX = XCenter - XLength;
WorkingY = YCenter - YLength; WorkingY = YCenter - YLength;
for ( ; WorkingX &lt ( XCenter + XLength ); WorkingX++ ) for ( ; WorkingX &lt; ( XCenter + XLength ); WorkingX++ )
{ {
LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color); LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color);
} }
/* lines from center to right of rectangle */ /* lines from center to right of rectangle */
WorkingX = XCenter + XLength - 1; WorkingX = XCenter + XLength - 1;
WorkingY = YCenter - YLength; WorkingY = YCenter - YLength;
for ( ; WorkingY &lt ( YCenter + YLength ); WorkingY++ ) for ( ; WorkingY &lt; ( YCenter + YLength ); WorkingY++ )
{ {
LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color); LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color);
} }
/* lines from center to bottom of rectangle */ /* lines from center to bottom of rectangle */
WorkingX = XCenter + XLength - 1; WorkingX = XCenter + XLength - 1;
WorkingY = YCenter + YLength - 1; WorkingY = YCenter + YLength - 1;
for ( ; WorkingX &gt= ( XCenter - XLength ); WorkingX-- ) for ( ; WorkingX &gt;= ( XCenter - XLength ); WorkingX-- )
{ {
LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color); LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color);
} }
/* lines from center to left of rectangle */ /* lines from center to left of rectangle */
WorkingX = XCenter - XLength; WorkingX = XCenter - XLength;
WorkingY = YCenter + YLength - 1; WorkingY = YCenter + YLength - 1;
for ( ; WorkingY &gt= ( YCenter - YLength ); WorkingY-- ) for ( ; WorkingY &gt;= ( YCenter - YLength ); WorkingY-- )
{ {
LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color); LineDraw(XCenter, YCenter, WorkingX, WorkingY, Color);
} }
@ -99,7 +99,7 @@ int main()
/* Set graphics mode */ /* Set graphics mode */
regs.x.ax = GRAPHICS_MODE; regs.x.ax = GRAPHICS_MODE;
int86(BIOS_VIDEO_INT, &ampregs, &ampregs); int86(BIOS_VIDEO_INT, &amp;regs, &amp;regs);
/* Draw each of four rectangles full of vectors */ /* Draw each of four rectangles full of vectors */
VectorsUp(X_MAX / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 1); VectorsUp(X_MAX / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 1);
@ -112,7 +112,7 @@ int main()
/* Return back to text mode */ /* Return back to text mode */
regs.x.ax = TEXT_MODE; regs.x.ax = TEXT_MODE;
int86(BIOS_VIDEO_INT, &ampregs, &ampregs); int86(BIOS_VIDEO_INT, &amp;regs, &amp;regs);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -63,7 +63,7 @@
the polygon at any point would cross exactly two active edges the polygon at any point would cross exactly two active edges
(neither horizontal lines nor zero-length edges count as active (neither horizontal lines nor zero-length edges count as active
edges; both are acceptable anywhere in the polygon), and that the edges; both are acceptable anywhere in the polygon), and that the
right &amp left edges never cross. (It&rsquo;s OK for them to touch, though, right &amp; left edges never cross. (It&rsquo;s OK for them to touch, though,
so long as the right edge never crosses over to the left of the so long as the right edge never crosses over to the left of the
left edge.) Nonconvex polygons won&rsquo;t be drawn properly. Returns 1 left edge.) Nonconvex polygons won&rsquo;t be drawn properly. Returns 1
for success, 0 if memory allocation failed. */ for success, 0 if memory allocation failed. */
@ -201,7 +201,7 @@
ScanEdge(VertexPtr[PreviousIndex].X + XOffset, ScanEdge(VertexPtr[PreviousIndex].X + XOffset,
VertexPtr[PreviousIndex].Y, VertexPtr[PreviousIndex].Y,
VertexPtr[CurrentIndex].X + XOffset, VertexPtr[CurrentIndex].X + XOffset,
VertexPtr[CurrentIndex].Y, 1, SkipFirst, &ampEdgePointPtr); VertexPtr[CurrentIndex].Y, 1, SkipFirst, &amp;EdgePointPtr);
PreviousIndex = CurrentIndex; PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */ SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex); } while (CurrentIndex != MaxIndex);
@ -218,13 +218,13 @@
ScanEdge(VertexPtr[PreviousIndex].X + XOffset - 1, ScanEdge(VertexPtr[PreviousIndex].X + XOffset - 1,
VertexPtr[PreviousIndex].Y, VertexPtr[PreviousIndex].Y,
VertexPtr[CurrentIndex].X + XOffset - 1, VertexPtr[CurrentIndex].X + XOffset - 1,
VertexPtr[CurrentIndex].Y, 0, SkipFirst, &ampEdgePointPtr); VertexPtr[CurrentIndex].Y, 0, SkipFirst, &amp;EdgePointPtr);
PreviousIndex = CurrentIndex; PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */ SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex); } while (CurrentIndex != MaxIndex);
/* Draw the line list representing the scan converted polygon */ /* Draw the line list representing the scan converted polygon */
DrawHorizontalLineList(&ampWorkingHLineList, Color); DrawHorizontalLineList(&amp;WorkingHLineList, Color);
/* Release the line list&rsquo;s memory and we&rsquo;re successfully done */ /* Release the line list&rsquo;s memory and we&rsquo;re successfully done */
free(WorkingHLineList.HLinePtr); free(WorkingHLineList.HLinePtr);

View file

@ -52,7 +52,7 @@
#define DRAW_POLYGON(PointList,Color,X,Y) \ #define DRAW_POLYGON(PointList,Color,X,Y) \
Polygon.Length = sizeof(PointList)/sizeof(struct Point); \ Polygon.Length = sizeof(PointList)/sizeof(struct Point); \
Polygon.PointPtr = PointList; \ Polygon.PointPtr = PointList; \
FillConvexPolygon(&ampPolygon, Color, X, Y); FillConvexPolygon(&amp;Polygon, Color, X, Y);
void main(void); void main(void);
extern int FillConvexPolygon(struct PointListHeader *, int, int, int); extern int FillConvexPolygon(struct PointListHeader *, int, int, int);
@ -78,7 +78,7 @@
regset.x.ax = 0x0013; /* AH = 0 selects mode set function, regset.x.ax = 0x0013; /* AH = 0 selects mode set function,
AL = 0x13 selects mode 0x13 AL = 0x13 selects mode 0x13
when set as parameters for INT 0x10 */ when set as parameters for INT 0x10 */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
/* Clear the screen to cyan */ /* Clear the screen to cyan */
DRAW_POLYGON(ScreenRectangle, 3, 0, 0); DRAW_POLYGON(ScreenRectangle, 3, 0, 0);
@ -128,7 +128,7 @@
/* Return to text mode and exit */ /* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -54,27 +54,27 @@
<TD VALIGN="TOP" ALIGN="LEFT">11.69 <TD VALIGN="TOP" ALIGN="LEFT">11.69
<TD VALIGN="TOP" ALIGN="LEFT">5.80 seconds<BR>(50% of total) <TD VALIGN="TOP" ALIGN="LEFT">5.80 seconds<BR>(50% of total)
<TD VALIGN="TOP" ALIGN="LEFT">5.86<BR>(50%) <TD VALIGN="TOP" ALIGN="LEFT">5.86<BR>(50%)
<TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(&lt1%) <TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(&lt;1%)
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">C floating point scan/memset drawing (Listing 39.1, compact model) <TD VALIGN="TOP" ALIGN="LEFT">C floating point scan/memset drawing (Listing 39.1, compact model)
<TD VALIGN="TOP" ALIGN="LEFT">6.64 <TD VALIGN="TOP" ALIGN="LEFT">6.64
<TD VALIGN="TOP" ALIGN="LEFT">0.49<BR>(7%) <TD VALIGN="TOP" ALIGN="LEFT">0.49<BR>(7%)
<TD VALIGN="TOP" ALIGN="LEFT">6.11<BR>(92%) <TD VALIGN="TOP" ALIGN="LEFT">6.11<BR>(92%)
<TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(&lt1%) <TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(&lt;1%)
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">C integer scan/memset drawing (Listing 39.1 &amp Listing 39.2, compact model) <TD VALIGN="TOP" ALIGN="LEFT">C integer scan/memset drawing (Listing 39.1 &amp; Listing 39.2, compact model)
<TD VALIGN="TOP" ALIGN="LEFT">0.60 <TD VALIGN="TOP" ALIGN="LEFT">0.60
<TD VALIGN="TOP" ALIGN="LEFT">0.49<BR>(82%) <TD VALIGN="TOP" ALIGN="LEFT">0.49<BR>(82%)
<TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(12%) <TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(12%)
<TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(7%) <TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(7%)
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">C integer scan/ASM drawing (Listing 39.2 &amp Listing 39.3, small model) <TD VALIGN="TOP" ALIGN="LEFT">C integer scan/ASM drawing (Listing 39.2 &amp; Listing 39.3, small model)
<TD VALIGN="TOP" ALIGN="LEFT">0.45 <TD VALIGN="TOP" ALIGN="LEFT">0.45
<TD VALIGN="TOP" ALIGN="LEFT">0.36<BR>(80%) <TD VALIGN="TOP" ALIGN="LEFT">0.36<BR>(80%)
<TD VALIGN="TOP" ALIGN="LEFT">0.06<BR>(13%) <TD VALIGN="TOP" ALIGN="LEFT">0.06<BR>(13%)
<TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(7%) <TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(7%)
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">ASM integer scan/ASM drawing (Listing 40.3 &amp Listing 40.4,small model) <TD VALIGN="TOP" ALIGN="LEFT">ASM integer scan/ASM drawing (Listing 40.3 &amp; Listing 40.4,small model)
<TD VALIGN="TOP" ALIGN="LEFT">0.42 <TD VALIGN="TOP" ALIGN="LEFT">0.42
<TD VALIGN="TOP" ALIGN="LEFT">0.36<BR>(86%) <TD VALIGN="TOP" ALIGN="LEFT">0.36<BR>(86%)
<TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(7%) <TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(7%)
@ -82,13 +82,13 @@
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT" COLSPAN="5"><SMALL>Drawing to system memory</SMALL> <TD VALIGN="TOP" ALIGN="LEFT" COLSPAN="5"><SMALL>Drawing to system memory</SMALL>
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">C integer scan/memset drawing (Listing 39.1 &amp Listing 39.2,compact model) <TD VALIGN="TOP" ALIGN="LEFT">C integer scan/memset drawing (Listing 39.1 &amp; Listing 39.2,compact model)
<TD VALIGN="TOP" ALIGN="LEFT">0.31 <TD VALIGN="TOP" ALIGN="LEFT">0.31
<TD VALIGN="TOP" ALIGN="LEFT">0.20<BR>(65%) <TD VALIGN="TOP" ALIGN="LEFT">0.20<BR>(65%)
<TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(23%) <TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(23%)
<TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(13%) <TD VALIGN="TOP" ALIGN="LEFT">0.04<BR>(13%)
<TR> <TR>
<TD VALIGN="TOP" ALIGN="LEFT">ASM integer scan/ASM drawing (Listing 39.3 &amp Listing 39.4,small model) <TD VALIGN="TOP" ALIGN="LEFT">ASM integer scan/ASM drawing (Listing 39.3 &amp; Listing 39.4,small model)
<TD VALIGN="TOP" ALIGN="LEFT">0.13 <TD VALIGN="TOP" ALIGN="LEFT">0.13
<TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(54%) <TD VALIGN="TOP" ALIGN="LEFT">0.07<BR>(54%)
<TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(23%) <TD VALIGN="TOP" ALIGN="LEFT">0.03<BR>(23%)
@ -113,8 +113,8 @@
running in real mode or 286 protected mode. running in real mode or 286 protected mode.
All C code tested with Borland C++. */ All C code tested with Borland C++. */
#include &ltstring.h&gt #include &lt;string.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
#define SCREEN_WIDTH 320 #define SCREEN_WIDTH 320
@ -129,18 +129,18 @@ void DrawHorizontalLineList(struct HLineList * HLineListPtr,
/* Point to the start of the first scan line on which to draw */ /* Point to the start of the first scan line on which to draw */
ScreenPtr = MK_FP(SCREEN_SEGMENT, ScreenPtr = MK_FP(SCREEN_SEGMENT,
HLineListPtr-&gtYStart * SCREEN_WIDTH); HLineListPtr-&gt;YStart * SCREEN_WIDTH);
/* Point to the XStart/XEnd descriptor for the first (top) /* Point to the XStart/XEnd descriptor for the first (top)
horizontal line */ horizontal line */
HLinePtr = HLineListPtr-&gtHLinePtr; HLinePtr = HLineListPtr-&gt;HLinePtr;
/* Draw each horizontal line in turn, starting with the top one and /* Draw each horizontal line in turn, starting with the top one and
advancing one line each time */ advancing one line each time */
Length = HLineListPtr-&gtLength; Length = HLineListPtr-&gt;Length;
while (Length-- &gt 0) { while (Length-- &gt; 0) {
/* Draw the whole horizontal line if it has a positive width */ /* Draw the whole horizontal line if it has a positive width */
if ((Width = HLinePtr-&gtXEnd - HLinePtr-&gtXStart + 1) &gt 0) if ((Width = HLinePtr-&gt;XEnd - HLinePtr-&gt;XStart + 1) &gt; 0)
memset(ScreenPtr + HLinePtr-&gtXStart, Color, Width); memset(ScreenPtr + HLinePtr-&gt;XStart, Color, Width);
HLinePtr++; /* point to next scan line X info */ HLinePtr++; /* point to next scan line X info */
ScreenPtr += SCREEN_WIDTH; /* point to next scan line start */ ScreenPtr += SCREEN_WIDTH; /* point to next scan line start */
} }

View file

@ -49,7 +49,7 @@
scanned edge is chosen. Uses an all-integer approach for speed and scanned edge is chosen. Uses an all-integer approach for speed and
precision. */ precision. */
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart, void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
@ -60,11 +60,11 @@ void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
struct HLine *WorkingEdgePointPtr; struct HLine *WorkingEdgePointPtr;
WorkingEdgePointPtr = *EdgePointPtr; /* avoid double dereference */ WorkingEdgePointPtr = *EdgePointPtr; /* avoid double dereference */
AdvanceAmt = ((DeltaX = X2 - X1) &gt 0) ? 1 : -1; AdvanceAmt = ((DeltaX = X2 - X1) &gt; 0) ? 1 : -1;
/* direction in which X moves (Y2 is /* direction in which X moves (Y2 is
always &gt Y1, so Y always counts up) */ always &gt; Y1, so Y always counts up) */
if ((Height = Y2 - Y1) &lt= 0) /* Y length of the edge */ if ((Height = Y2 - Y1) &lt;= 0) /* Y length of the edge */
return; /* guard against 0-length and horizontal edges */ return; /* guard against 0-length and horizontal edges */
/* Figure out whether the edge is vertical, diagonal, X-major /* Figure out whether the edge is vertical, diagonal, X-major
@ -74,12 +74,12 @@ void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
/* The edge is vertical; special-case by just storing the same /* The edge is vertical; special-case by just storing the same
X coordinate for every scan line */ X coordinate for every scan line */
/* Scan the edge for each scan line in turn */ /* Scan the edge for each scan line in turn */
for (i = Height - SkipFirst; i-- &gt 0; WorkingEdgePointPtr++) { for (i = Height - SkipFirst; i-- &gt; 0; WorkingEdgePointPtr++) {
/* Store the X coordinate in the appropriate edge list */ /* Store the X coordinate in the appropriate edge list */
if (SetXStart == 1) if (SetXStart == 1)
WorkingEdgePointPtr-&gtXStart = X1; WorkingEdgePointPtr-&gt;XStart = X1;
else else
WorkingEdgePointPtr-&gtXEnd = X1; WorkingEdgePointPtr-&gt;XEnd = X1;
} }
} else if (Width == Height) { } else if (Width == Height) {
/* The edge is diagonal; special-case by advancing the X /* The edge is diagonal; special-case by advancing the X
@ -87,36 +87,36 @@ void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
if (SkipFirst) /* skip the first point if so indicated */ if (SkipFirst) /* skip the first point if so indicated */
X1 += AdvanceAmt; /* move 1 pixel to the left or right */ X1 += AdvanceAmt; /* move 1 pixel to the left or right */
/* Scan the edge for each scan line in turn */ /* Scan the edge for each scan line in turn */
for (i = Height - SkipFirst; i-- &gt 0; WorkingEdgePointPtr++) { for (i = Height - SkipFirst; i-- &gt; 0; WorkingEdgePointPtr++) {
/* Store the X coordinate in the appropriate edge list */ /* Store the X coordinate in the appropriate edge list */
if (SetXStart == 1) if (SetXStart == 1)
WorkingEdgePointPtr-&gtXStart = X1; WorkingEdgePointPtr-&gt;XStart = X1;
else else
WorkingEdgePointPtr-&gtXEnd = X1; WorkingEdgePointPtr-&gt;XEnd = X1;
X1 += AdvanceAmt; /* move 1 pixel to the left or right */ X1 += AdvanceAmt; /* move 1 pixel to the left or right */
} }
} else if (Height &gt Width) { } else if (Height &gt; Width) {
/* Edge is closer to vertical than horizontal (Y-major) */ /* Edge is closer to vertical than horizontal (Y-major) */
if (DeltaX &gt= 0) if (DeltaX &gt;= 0)
ErrorTerm = 0; /* initial error term going left-&gtright */ ErrorTerm = 0; /* initial error term going left-&gt;right */
else else
ErrorTerm = -Height + 1; /* going right-&gtleft */ ErrorTerm = -Height + 1; /* going right-&gt;left */
if (SkipFirst) { /* skip the first point if so indicated */ if (SkipFirst) { /* skip the first point if so indicated */
/* Determine whether it&rsquo;s time for the X coord to advance */ /* Determine whether it&rsquo;s time for the X coord to advance */
if ((ErrorTerm += Width) &gt 0) { if ((ErrorTerm += Width) &gt; 0) {
X1 += AdvanceAmt; /* move 1 pixel to the left or right */ X1 += AdvanceAmt; /* move 1 pixel to the left or right */
ErrorTerm -= Height; /* advance ErrorTerm to next point */ ErrorTerm -= Height; /* advance ErrorTerm to next point */
} }
} }
/* Scan the edge for each scan line in turn */ /* Scan the edge for each scan line in turn */
for (i = Height - SkipFirst; i-- &gt 0; WorkingEdgePointPtr++) { for (i = Height - SkipFirst; i-- &gt; 0; WorkingEdgePointPtr++) {
/* Store the X coordinate in the appropriate edge list */ /* Store the X coordinate in the appropriate edge list */
if (SetXStart == 1) if (SetXStart == 1)
WorkingEdgePointPtr-&gtXStart = X1; WorkingEdgePointPtr-&gt;XStart = X1;
else else
WorkingEdgePointPtr-&gtXEnd = X1; WorkingEdgePointPtr-&gt;XEnd = X1;
/* Determine whether it&rsquo;s time for the X coord to advance */ /* Determine whether it&rsquo;s time for the X coord to advance */
if ((ErrorTerm += Width) &gt 0) { if ((ErrorTerm += Width) &gt; 0) {
X1 += AdvanceAmt; /* move 1 pixel to the left or right */ X1 += AdvanceAmt; /* move 1 pixel to the left or right */
ErrorTerm -= Height; /* advance ErrorTerm to correspond */ ErrorTerm -= Height; /* advance ErrorTerm to correspond */
} }
@ -127,28 +127,28 @@ void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
XMajorAdvanceAmt = (Width / Height) * AdvanceAmt; XMajorAdvanceAmt = (Width / Height) * AdvanceAmt;
/* Error term advance for deciding when to advance X 1 extra */ /* Error term advance for deciding when to advance X 1 extra */
ErrorTermAdvance = Width % Height; ErrorTermAdvance = Width % Height;
if (DeltaX &gt= 0) if (DeltaX &gt;= 0)
ErrorTerm = 0; /* initial error term going left-&gtright */ ErrorTerm = 0; /* initial error term going left-&gt;right */
else else
ErrorTerm = -Height + 1; /* going right-&gtleft */ ErrorTerm = -Height + 1; /* going right-&gt;left */
if (SkipFirst) { /* skip the first point if so indicated */ if (SkipFirst) { /* skip the first point if so indicated */
X1 += XMajorAdvanceAmt; /* move X minimum distance */ X1 += XMajorAdvanceAmt; /* move X minimum distance */
/* Determine whether it&rsquo;s time for X to advance one extra */ /* Determine whether it&rsquo;s time for X to advance one extra */
if ((ErrorTerm += ErrorTermAdvance) &gt 0) { if ((ErrorTerm += ErrorTermAdvance) &gt; 0) {
X1 += AdvanceAmt; /* move X one more */ X1 += AdvanceAmt; /* move X one more */
ErrorTerm -= Height; /* advance ErrorTerm to correspond */ ErrorTerm -= Height; /* advance ErrorTerm to correspond */
} }
} }
/* Scan the edge for each scan line in turn */ /* Scan the edge for each scan line in turn */
for (i = Height - SkipFirst; i-- &gt 0; WorkingEdgePointPtr++) { for (i = Height - SkipFirst; i-- &gt; 0; WorkingEdgePointPtr++) {
/* Store the X coordinate in the appropriate edge list */ /* Store the X coordinate in the appropriate edge list */
if (SetXStart == 1) if (SetXStart == 1)
WorkingEdgePointPtr-&gtXStart = X1; WorkingEdgePointPtr-&gt;XStart = X1;
else else
WorkingEdgePointPtr-&gtXEnd = X1; WorkingEdgePointPtr-&gt;XEnd = X1;
X1 += XMajorAdvanceAmt; /* move X minimum distance */ X1 += XMajorAdvanceAmt; /* move X minimum distance */
/* Determine whether it&rsquo;s time for X to advance one extra */ /* Determine whether it&rsquo;s time for X to advance one extra */
if ((ErrorTerm += ErrorTermAdvance) &gt 0) { if ((ErrorTerm += ErrorTermAdvance) &gt; 0) {
X1 += AdvanceAmt; /* move X one more */ X1 += AdvanceAmt; /* move X one more */
ErrorTerm -= Height; /* advance ErrorTerm to correspond */ ErrorTerm -= Height; /* advance ErrorTerm to correspond */
} }

View file

@ -70,7 +70,7 @@ HLinePtr dw ? ;pointer to list of horz lines
HLineList ends HLineList ends
Parms struc Parms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
HLineListPtr dw ? ;pointer to HLineList structure HLineListPtr dw ? ;pointer to HLineList structure
Color dw ? ;color with which to fill Color dw ? ;color with which to fill
Parms ends Parms ends

View file

@ -43,11 +43,11 @@
; point at (X2,Y2). If SkipFirst == 1, the point at (X1,Y1) isn&rsquo;t ; point at (X2,Y2). If SkipFirst == 1, the point at (X1,Y1) isn&rsquo;t
; drawn; if SkipFirst == 0, it is. For each scan line, the pixel ; drawn; if SkipFirst == 0, it is. For each scan line, the pixel
; closest to the scanned edge without being to the left of the scanned ; closest to the scanned edge without being to the left of the scanned
; edge is chosen. Uses an all-integer approach for speed &amp precision. ; edge is chosen. Uses an all-integer approach for speed &amp; precision.
; C near-callable as: ; C near-callable as:
; void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart, ; void ScanEdge(int X1, int Y1, int X2, int Y2, int SetXStart,
; int SkipFirst, struct HLine **EdgePointPtr); ; int SkipFirst, struct HLine **EdgePointPtr);
; Edges must not go bottom to top; that is, Y1 must be &lt= Y2. ; Edges must not go bottom to top; that is, Y1 must be &lt;= Y2.
; Updates the pointer pointed to by EdgePointPtr to point to the next ; Updates the pointer pointed to by EdgePointPtr to point to the next
; free entry in the array of HLine structures. ; free entry in the array of HLine structures.
@ -57,7 +57,7 @@ XEnd dw ? ;X coordinate of rightmost pixel in scan line
HLine ends HLine ends
Parms struc Parms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
X1 dw ? ;X start coord of edge X1 dw ? ;X start coord of edge
Y1 dw ? ;Y start coord of edge Y1 dw ? ;Y start coord of edge
X2 dw ? ;X end coord of edge X2 dw ? ;X end coord of edge
@ -96,7 +96,7 @@ _ScanEdge proc
HLinePtrSet: HLinePtrSet:
mov bx,[bp+Y2] mov bx,[bp+Y2]
sub bx,[bp+Y1] ;edge height sub bx,[bp+Y1] ;edge height
jle ToScanEdgeExit ;guard against 0-length &amp horz edges jle ToScanEdgeExit ;guard against 0-length &amp; horz edges
mov [bp+Height],bx ;Height = Y2 - Y1 mov [bp+Height],bx ;Height = Y2 - Y1
sub cx,cx ;assume ErrorTerm starts at 0 (true if sub cx,cx ;assume ErrorTerm starts at 0 (true if
; we&rsquo;re moving right as we draw) ; we&rsquo;re moving right as we draw)
@ -104,8 +104,8 @@ HLinePtrSet:
mov ax,[bp+X2] mov ax,[bp+X2]
sub ax,[bp+X1] ;DeltaX = X2 - X1 sub ax,[bp+X1] ;DeltaX = X2 - X1
jz IsVertical ;it&rsquo;s a vertical edge--special case it jz IsVertical ;it&rsquo;s a vertical edge--special case it
jns SetAdvanceAmt ;DeltaX &gt= 0 jns SetAdvanceAmt ;DeltaX &gt;= 0
mov cx,1 ;DeltaX &lt 0 (move left as we draw) mov cx,1 ;DeltaX &lt; 0 (move left as we draw)
sub cx,bx ;ErrorTerm = -Height + 1 sub cx,bx ;ErrorTerm = -Height + 1
neg dx ;AdvanceAmt = -1 (move left) neg dx ;AdvanceAmt = -1 (move left)
neg ax ;Width = abs(DeltaX) neg ax ;Width = abs(DeltaX)

View file

@ -123,7 +123,7 @@ void main()
getch(); /* wait for a key press */ getch(); /* wait for a key press */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); /* return to text mode */ int86(0x10, &amp;regset, &amp;regset); /* return to text mode */
} }
/* Sets up the palette for antialiasing with the specified colors. /* Sets up the palette for antialiasing with the specified colors.
@ -163,7 +163,7 @@ void SetPalette(struct WuColor * WColors)
regset.x.dx = (unsigned int)PaletteBlock; /* offset of array from which regset.x.dx = (unsigned int)PaletteBlock; /* offset of array from which
to load RGB settings */ to load RGB settings */
sregset.es = _DS; /* segment of array from which to load settings */ sregset.es = _DS; /* segment of array from which to load settings */
int86x(0x10, &ampregset, &ampregset, &ampsregset); /* load the palette block */ int86x(0x10, &amp;regset, &amp;regset, &amp;sregset); /* load the palette block */
} }
} }
</PRE> </PRE>
@ -198,7 +198,7 @@ void SetMode()
/* Set to 320x200 256-color graphics mode */ /* Set to 320x200 256-color graphics mode */
regset.x.ax = 0x0013; regset.x.ax = 0x0013;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -79,10 +79,10 @@ void DrawLine(int X0, int Y0, int X1, int Y1, int Color)
/* Draw all pixels between the first and last */ /* Draw all pixels between the first and last */
do { do {
ErrorAcc += ErrorAdj; /* calculate error for this pixel */ ErrorAcc += ErrorAdj; /* calculate error for this pixel */
if (ErrorAcc &amp ~0xFFFFL) { if (ErrorAcc &amp; ~0xFFFFL) {
/* The error accumulator turned over, so advance the X coord */ /* The error accumulator turned over, so advance the X coord */
X0 += XDir; X0 += XDir;
ErrorAcc &amp= 0xFFFFL; /* clear integer part of result */ ErrorAcc &amp;= 0xFFFFL; /* clear integer part of result */
} }
Y0++; /* Y-major, so always advance Y */ Y0++; /* Y-major, so always advance Y */
DrawPixel(X0, Y0, Color); DrawPixel(X0, Y0, Color);
@ -96,10 +96,10 @@ void DrawLine(int X0, int Y0, int X1, int Y1, int Color)
/* Draw all remaining pixels */ /* Draw all remaining pixels */
do { do {
ErrorAcc += ErrorAdj; /* calculate error for this pixel */ ErrorAcc += ErrorAdj; /* calculate error for this pixel */
if (ErrorAcc &amp ~0xFFFFL) { if (ErrorAcc &amp; ~0xFFFFL) {
/* The error accumulator turned over, so advance the Y coord */ /* The error accumulator turned over, so advance the Y coord */
Y0++; Y0++;
ErrorAcc &amp= 0xFFFFL; /* clear integer part of result */ ErrorAcc &amp;= 0xFFFFL; /* clear integer part of result */
} }
X0 += XDir; /* X-major, so always advance X */ X0 += XDir; /* X-major, so always advance X */
DrawPixel(X0, Y0, Color); DrawPixel(X0, Y0, Color);
@ -149,7 +149,7 @@ void SetMode()
/* Set to 640x480 256-color graphics mode */ /* Set to 640x480 256-color graphics mode */
regset.x.ax = 0x002E; regset.x.ax = 0x002E;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -117,19 +117,19 @@ Data segment word &lsquo;DATA&rsquo;
Colors db 000h ;background color=black Colors db 000h ;background color=black
db 03ch ;plane 0 only=red db 03ch ;plane 0 only=red
db 03ah ;plane 1 only=green db 03ah ;plane 1 only=green
db 03ch ;planes 0&amp1=red (plane 0 priority) db 03ch ;planes 0&amp;1=red (plane 0 priority)
db 039h ;plane 2 only=blue db 039h ;plane 2 only=blue
db 03ch ;planes 0&amp2=red (plane 0 priority) db 03ch ;planes 0&amp;2=red (plane 0 priority)
db 03ah ;planes 1&amp2=green (plane 1 priority) db 03ah ;planes 1&amp;2=green (plane 1 priority)
db 03ch ;planes 0&amp1&amp2=red (plane 0 priority) db 03ch ;planes 0&amp;1&amp;2=red (plane 0 priority)
db 03fh ;plane 3 only=white db 03fh ;plane 3 only=white
db 03ch ;planes 0&amp3=red (plane 0 priority) db 03ch ;planes 0&amp;3=red (plane 0 priority)
db 03ah ;planes 1&amp3=green (plane 1 priority) db 03ah ;planes 1&amp;3=green (plane 1 priority)
db 03ch ;planes 0&amp1&amp3=red (plane 0 priority) db 03ch ;planes 0&amp;1&amp;3=red (plane 0 priority)
db 039h ;planes 2&amp3=blue (plane 2 priority) db 039h ;planes 2&amp;3=blue (plane 2 priority)
db 03ch ;planes 0&amp2&amp3=red (plane 0 priority) db 03ch ;planes 0&amp;2&amp;3=red (plane 0 priority)
db 03ah ;planes 1&amp2&amp3=green (plane 1 priority) db 03ah ;planes 1&amp;2&amp;3=green (plane 1 priority)
db 03ch ;planes 0&amp1&amp2&amp3=red (plane 0 priority) db 03ch ;planes 0&amp;1&amp;2&amp;3=red (plane 0 priority)
db 000h ;border color=black db 000h ;border color=black
; ;
; Image of a hollow square. ; Image of a hollow square.
@ -234,19 +234,19 @@ Diamond label byte
even;word-align for better 286 performance even;word-align for better 286 performance
; ;
ObjectListlabelObjectStructure ObjectListlabelObjectStructure
ObjectStructure &lt1,21,Diamond,88,8,80,512,16,0,0,350,RED&gt ObjectStructure &lt;1,21,Diamond,88,8,80,512,16,0,0,350,RED&gt;
ObjectStructure &lt1,15,Square,296,8,112,480,144,0,0,350,RED&gt ObjectStructure &lt;1,15,Square,296,8,112,480,144,0,0,350,RED&gt;
ObjectStructure &lt1,23,Diamond,88,8,80,512,256,0,0,350,RED&gt ObjectStructure &lt;1,23,Diamond,88,8,80,512,256,0,0,350,RED&gt;
ObjectStructure &lt1,13,Square,120,0,0,640,144,4,0,280,BLUE&gt ObjectStructure &lt;1,13,Square,120,0,0,640,144,4,0,280,BLUE&gt;
ObjectStructure &lt1,11,Diamond,208,0,0,640,144,4,0,280,BLUE&gt ObjectStructure &lt;1,11,Diamond,208,0,0,640,144,4,0,280,BLUE&gt;
ObjectStructure &lt1,8,Square,296,0,0,640,144,4,0,288,BLUE&gt ObjectStructure &lt;1,8,Square,296,0,0,640,144,4,0,288,BLUE&gt;
ObjectStructure &lt1,9,Diamond,384,0,0,640,144,4,0,288,BLUE&gt ObjectStructure &lt;1,9,Diamond,384,0,0,640,144,4,0,288,BLUE&gt;
ObjectStructure &lt1,14,Square,472,0,0,640,144,4,0,280,BLUE&gt ObjectStructure &lt;1,14,Square,472,0,0,640,144,4,0,280,BLUE&gt;
ObjectStructure &lt1,8,Diamond,200,8,0,576,48,6,0,280,GREEN&gt ObjectStructure &lt;1,8,Diamond,200,8,0,576,48,6,0,280,GREEN&gt;
ObjectStructure &lt1,8,Square,248,8,0,576,96,6,0,280,GREEN&gt ObjectStructure &lt;1,8,Square,248,8,0,576,96,6,0,280,GREEN&gt;
ObjectStructure &lt1,8,Diamond,296,8,0,576,144,6,0,280,GREEN&gt ObjectStructure &lt;1,8,Diamond,296,8,0,576,144,6,0,280,GREEN&gt;
ObjectStructure &lt1,8,Square,344,8,0,576,192,6,0,280,GREEN&gt ObjectStructure &lt;1,8,Square,344,8,0,576,192,6,0,280,GREEN&gt;
ObjectStructure &lt1,8,Diamond,392,8,0,576,240,6,0,280,GREEN&gt ObjectStructure &lt;1,8,Diamond,392,8,0,576,240,6,0,280,GREEN&gt;
ObjectListEndlabelObjectStructure ObjectListEndlabelObjectStructure
; ;
Dataends Dataends
@ -290,8 +290,8 @@ Start proc near
int 10h ;BIOS video interrupt int 10h ;BIOS video interrupt
; ;
; Set the palette up to provide bit-plane precedence. If ; Set the palette up to provide bit-plane precedence. If
; planes 0 &amp 1 overlap, the plane 0 color will be shown; ; planes 0 &amp; 1 overlap, the plane 0 color will be shown;
; if planes 1 &amp 2 overlap, the plane 1 color will be ; if planes 1 &amp; 2 overlap, the plane 1 color will be
; shown; and so on. ; shown; and so on.
; ;
mov ax,(10h shl 8) + 2 ;AH = 10h means mov ax,(10h shl 8) + 2 ;AH = 10h means
@ -368,7 +368,7 @@ CheckXRightLimit:
neg [bx+XInc] ;yes-reverse neg [bx+XInc] ;yes-reverse
SetNewX: SetNewX:
add cx,[bx+XInc] ;move the X coord add cx,[bx+XInc] ;move the X coord
mov [bx+XCoord],cx ; &amp save it mov [bx+XCoord],cx ; &amp; save it
; ;
; Advance the Y coordinate, reversing direction if either ; Advance the Y coordinate, reversing direction if either
; of the Y margins has been reached. ; of the Y margins has been reached.
@ -383,7 +383,7 @@ CheckYBottomLimit:
neg [bx+YInc] ;yes-reverse neg [bx+YInc] ;yes-reverse
SetNewY: SetNewY:
add dx,[bx+YInc] ;move the Y coord add dx,[bx+YInc] ;move the Y coord
mov [bx+YCoord],dx ; &amp save it mov [bx+YCoord],dx ; &amp; save it
; ;
; Draw at the new location. Because of the plane select ; Draw at the new location. Because of the plane select
; above, only one plane will be affected. ; above, only one plane will be affected.
@ -417,7 +417,7 @@ CheckKey:
int 16h ;is a key waiting? int 16h ;is a key waiting?
jz AnimationLoop ;no jz AnimationLoop ;no
sub ah,ah sub ah,ah
int 16h ;yes-clear the key &amp done int 16h ;yes-clear the key &amp; done
; ;
; Back to text mode. ; Back to text mode.
; ;

View file

@ -44,10 +44,10 @@ top portion of the screen while displaying non-page flipped
information in the split screen at the bottom of the screen. information in the split screen at the bottom of the screen.
Compiled with Borland C++ in C compilation mode. */ Compiled with Borland C++ in C compilation mode. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ltmath.h&gt #include &lt;math.h&gt;
#define SCREEN-SEG 0xA000 #define SCREEN-SEG 0xA000
#define SCREEN-PIXWIDTH 640 /* in pixels */ #define SCREEN-PIXWIDTH 640 /* in pixels */
@ -141,7 +141,7 @@ image BouncerRotation4 = {3, 20, -BouncerRotation4};
/* Initial settings for bouncing object. Only 2 rotations are needed /* Initial settings for bouncing object. Only 2 rotations are needed
because the object moves 4 pixels horizontally at a time */ because the object moves 4 pixels horizontally at a time */
bouncer Bouncer = {156,60,20,20,4,4,156,156,60,60,BOUNCER-COLOR, bouncer Bouncer = {156,60,20,20,4,4,156,156,60,60,BOUNCER-COLOR,
&ampBouncerRotation0,NULL,NULL,NULL,&ampBouncerRotation4,NULL,NULL,NULL}; &amp;BouncerRotation0,NULL,NULL,NULL,&amp;BouncerRotation4,NULL,NULL,NULL};
unsigned int PageStartOffsets[2] = unsigned int PageStartOffsets[2] =
{PAGE0-START-OFFSET,PAGE1-START-OFFSET}; {PAGE0-START-OFFSET,PAGE1-START-OFFSET};
unsigned int BounceCount; unsigned int BounceCount;
@ -151,7 +151,7 @@ void main() {
union REGS regset; union REGS regset;
regset.x.ax = 0x0012; /* set display to 640x480 16-color mode */ regset.x.ax = 0x0012; /* set display to 640x480 16-color mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
SetBIOS8x8Font(); /* set the pointer to the BIOS 8x8 font */ SetBIOS8x8Font(); /* set the pointer to the BIOS 8x8 font */
EnableSplitScreen(); /* turn on the split screen */ EnableSplitScreen(); /* turn on the split screen */
@ -159,7 +159,7 @@ void main() {
ShowPage(PageStartOffsets[DisplayedPage = 0]); ShowPage(PageStartOffsets[DisplayedPage = 0]);
/* Clear both pages to background and draw bumpers in each page */ /* Clear both pages to background and draw bumpers in each page */
for (i=0; i&lt2; i++) { for (i=0; i&lt;2; i++) {
DrawRect(0,0,SCREEN-PIXWIDTH-1,NONSPLIT-LINES-1,BACK-COLOR, DrawRect(0,0,SCREEN-PIXWIDTH-1,NONSPLIT-LINES-1,BACK-COLOR,
PageStartOffsets[i],SCREEN-SEG); PageStartOffsets[i],SCREEN-SEG);
DrawBumperList(Bumpers,NUM-BUMPERS,PageStartOffsets[i]); DrawBumperList(Bumpers,NUM-BUMPERS,PageStartOffsets[i]);
@ -170,7 +170,7 @@ void main() {
ShowBounceCount(); /* put up the initial zero count */ ShowBounceCount(); /* put up the initial zero count */
/* Draw the bouncing object at its initial location */ /* Draw the bouncing object at its initial location */
DrawImage(Bouncer.LeftX,Bouncer.TopY,&ampBouncer.Rotation0, DrawImage(Bouncer.LeftX,Bouncer.TopY,&amp;Bouncer.Rotation0,
Bouncer.Color,PageStartOffsets[DisplayedPage],SCREEN-SEG); Bouncer.Color,PageStartOffsets[DisplayedPage],SCREEN-SEG);
/* Move the object, draw it in the nondisplayed page, and flip the /* Move the object, draw it in the nondisplayed page, and flip the
@ -185,9 +185,9 @@ void main() {
Bouncer.CurrentY[NonDisplayedPage]+Bouncer.Height-1, Bouncer.CurrentY[NonDisplayedPage]+Bouncer.Height-1,
BACK-COLOR,PageStartOffsets[NonDisplayedPage],SCREEN-SEG); BACK-COLOR,PageStartOffsets[NonDisplayedPage],SCREEN-SEG);
/* Move the bouncer */ /* Move the bouncer */
MoveBouncer(&ampBouncer, Bumpers, NUM-BUMPERS); MoveBouncer(&amp;Bouncer, Bumpers, NUM-BUMPERS);
/* Draw at the new location in the nondisplayed page */ /* Draw at the new location in the nondisplayed page */
DrawImage(Bouncer.LeftX,Bouncer.TopY,&ampBouncer.Rotation0, DrawImage(Bouncer.LeftX,Bouncer.TopY,&amp;Bouncer.Rotation0,
Bouncer.Color,PageStartOffsets[NonDisplayedPage], Bouncer.Color,PageStartOffsets[NonDisplayedPage],
SCREEN-SEG); SCREEN-SEG);
/* Remember where the bouncer is in the nondisplayed page */ /* Remember where the bouncer is in the nondisplayed page */
@ -220,7 +220,7 @@ void main() {
/* Restore text mode and done */ /* Restore text mode and done */
regset.x.ax = 0x0003; regset.x.ax = 0x0003;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
/* Draws the specified list of bumpers into the specified page */ /* Draws the specified list of bumpers into the specified page */
@ -229,9 +229,9 @@ void DrawBumperList(bumper * Bumpers, int NumBumpers,
{ {
int i; int i;
for (i=0; i&ltNumBumpers; i++,Bumpers++) { for (i=0; i&lt;NumBumpers; i++,Bumpers++) {
DrawRect(Bumpers-&gtLeftX,Bumpers-&gtTopY,Bumpers-&gtRightX, DrawRect(Bumpers-&gt;LeftX,Bumpers-&gt;TopY,Bumpers-&gt;RightX,
Bumpers-&gtBottomY,Bumpers-&gtColor,PageStartOffset, Bumpers-&gt;BottomY,Bumpers-&gt;Color,PageStartOffset,
SCREEN-SEG); SCREEN-SEG);
} }
} }
@ -271,13 +271,13 @@ void DrawSplitScreen() {
Overflow register, and bit 9 is in the Maximum Scan Line reg) */ Overflow register, and bit 9 is in the Maximum Scan Line reg) */
void EnableSplitScreen() { void EnableSplitScreen() {
outp(CRTC-INDEX, LINE-COMPARE); outp(CRTC-INDEX, LINE-COMPARE);
outp(CRTC-DATA, (SPLIT-START-LINE - 1) &amp 0xFF); outp(CRTC-DATA, (SPLIT-START-LINE - 1) &amp; 0xFF);
outp(CRTC-INDEX, OVERFLOW); outp(CRTC-INDEX, OVERFLOW);
outp(CRTC-DATA, (((((SPLIT-START-LINE - 1) &amp 0x100) &gt&gt 8) &lt&lt 4) | outp(CRTC-DATA, (((((SPLIT-START-LINE - 1) &amp; 0x100) &gt;&gt; 8) &lt;&lt; 4) |
(inp(CRTC-DATA) &amp ~0x10))); (inp(CRTC-DATA) &amp; ~0x10)));
outp(CRTC-INDEX, MAX-SCAN); outp(CRTC-INDEX, MAX-SCAN);
outp(CRTC-DATA, (((((SPLIT-START-LINE - 1) &amp 0x200) &gt&gt 9) &lt&lt 6) | outp(CRTC-DATA, (((((SPLIT-START-LINE - 1) &amp; 0x200) &gt;&gt; 9) &lt;&lt; 6) |
(inp(CRTC-DATA) &amp ~0x40))); (inp(CRTC-DATA) &amp; ~0x40)));
} }
/* Moves the bouncer, bouncing if bumpers are hit */ /* Moves the bouncer, bouncing if bumpers are hit */
@ -285,37 +285,37 @@ void MoveBouncer(bouncer *Bouncer, bumper *BumperPtr, int NumBumpers) {
int NewLeftX, NewTopY, NewRightX, NewBottomY, i; int NewLeftX, NewTopY, NewRightX, NewBottomY, i;
/* Move to new location, bouncing if necessary */ /* Move to new location, bouncing if necessary */
NewLeftX = Bouncer-&gtLeftX + Bouncer-&gtDirX; /* new coords */ NewLeftX = Bouncer-&gt;LeftX + Bouncer-&gt;DirX; /* new coords */
NewTopY = Bouncer-&gtTopY + Bouncer-&gtDirY; NewTopY = Bouncer-&gt;TopY + Bouncer-&gt;DirY;
NewRightX = NewLeftX + Bouncer-&gtWidth - 1; NewRightX = NewLeftX + Bouncer-&gt;Width - 1;
NewBottomY = NewTopY + Bouncer-&gtHeight - 1; NewBottomY = NewTopY + Bouncer-&gt;Height - 1;
/* Compare the new location to all bumpers, checking for bounce */ /* Compare the new location to all bumpers, checking for bounce */
for (i=0; i&ltNumBumpers; i++,BumperPtr++) { for (i=0; i&lt;NumBumpers; i++,BumperPtr++) {
/* If moving puts the bouncer inside this bumper, bounce */ /* If moving puts the bouncer inside this bumper, bounce */
if ( (NewLeftX &lt= BumperPtr-&gtRightX) &amp&amp if ( (NewLeftX &lt;= BumperPtr-&gt;RightX) &amp;&amp;
(NewRightX &gt= BumperPtr-&gtLeftX) &amp&amp (NewRightX &gt;= BumperPtr-&gt;LeftX) &amp;&amp;
(NewTopY &lt= BumperPtr-&gtBottomY) &amp&amp (NewTopY &lt;= BumperPtr-&gt;BottomY) &amp;&amp;
(NewBottomY &gt= BumperPtr-&gtTopY) ) { (NewBottomY &gt;= BumperPtr-&gt;TopY) ) {
/* The bouncer has tried to move into this bumper; figure /* The bouncer has tried to move into this bumper; figure
out which edge(s) it crossed, and bounce accordingly */ out which edge(s) it crossed, and bounce accordingly */
if (((Bouncer-&gtLeftX &gt BumperPtr-&gtRightX) &amp&amp if (((Bouncer-&gt;LeftX &gt; BumperPtr-&gt;RightX) &amp;&amp;
(NewLeftX &lt= BumperPtr-&gtRightX)) || (NewLeftX &lt;= BumperPtr-&gt;RightX)) ||
(((Bouncer-&gtLeftX + Bouncer-&gtWidth - 1) &lt (((Bouncer-&gt;LeftX + Bouncer-&gt;Width - 1) &lt;
BumperPtr-&gtLeftX) &amp&amp BumperPtr-&gt;LeftX) &amp;&amp;
(NewRightX &gt= BumperPtr-&gtLeftX))) { (NewRightX &gt;= BumperPtr-&gt;LeftX))) {
Bouncer-&gtDirX = -Bouncer-&gtDirX; /* bounce horizontally */ Bouncer-&gt;DirX = -Bouncer-&gt;DirX; /* bounce horizontally */
NewLeftX = Bouncer-&gtLeftX + Bouncer-&gtDirX; NewLeftX = Bouncer-&gt;LeftX + Bouncer-&gt;DirX;
} }
if (((Bouncer-&gtTopY &gt BumperPtr-&gtBottomY) &amp&amp if (((Bouncer-&gt;TopY &gt; BumperPtr-&gt;BottomY) &amp;&amp;
(NewTopY &lt= BumperPtr-&gtBottomY)) || (NewTopY &lt;= BumperPtr-&gt;BottomY)) ||
(((Bouncer-&gtTopY + Bouncer-&gtHeight - 1) &lt (((Bouncer-&gt;TopY + Bouncer-&gt;Height - 1) &lt;
BumperPtr-&gtTopY) &amp&amp BumperPtr-&gt;TopY) &amp;&amp;
(NewBottomY &gt= BumperPtr-&gtTopY))) { (NewBottomY &gt;= BumperPtr-&gt;TopY))) {
Bouncer-&gtDirY = -Bouncer-&gtDirY; /* bounce vertically */ Bouncer-&gt;DirY = -Bouncer-&gt;DirY; /* bounce vertically */
NewTopY = Bouncer-&gtTopY + Bouncer-&gtDirY; NewTopY = Bouncer-&gt;TopY + Bouncer-&gt;DirY;
} }
/* Update the bounce count display; turn over at 10000 */ /* Update the bounce count display; turn over at 10000 */
if (++BounceCount &gt= 10000) { if (++BounceCount &gt;= 10000) {
TextUp(&ldquo;0 &rdquo;,344,64,SPLIT-START-OFFSET,SCREEN-SEG); TextUp(&ldquo;0 &rdquo;,344,64,SPLIT-START-OFFSET,SCREEN-SEG);
BounceCount = 0; BounceCount = 0;
} else { } else {
@ -323,8 +323,8 @@ void MoveBouncer(bouncer *Bouncer, bumper *BumperPtr, int NumBumpers) {
} }
} }
} }
Bouncer-&gtLeftX = NewLeftX; /* set the final new coordinates */ Bouncer-&gt;LeftX = NewLeftX; /* set the final new coordinates */
Bouncer-&gtTopY = NewTopY; Bouncer-&gt;TopY = NewTopY;
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -142,7 +142,7 @@ void main()
} }
/* Set 320x200 256-color graphics mode */ /* Set 320x200 256-color graphics mode */
regs.x.ax = 0x0013; regs.x.ax = 0x0013;
int86(0x10, &ampregs, &ampregs); int86(0x10, &amp;regs, &amp;regs);
/* Loop and draw until a key is pressed */ /* Loop and draw until a key is pressed */
do { do {
@ -181,7 +181,7 @@ void main()
getch(); /* clear the keypress */ getch(); /* clear the keypress */
/* Back to text mode */ /* Back to text mode */
regs.x.ax = 0x0003; regs.x.ax = 0x0003;
int86(0x10, &ampregs, &ampregs); int86(0x10, &amp;regs, &amp;regs);
} }
/* Draw entities at current locations, updating dirty rectangle list. */ /* Draw entities at current locations, updating dirty rectangle list. */
void DrawEntities() void DrawEntities()

View file

@ -62,12 +62,12 @@ void Set640x400()
/* First, set to standard 640x350 mode (mode 10h) */ /* First, set to standard 640x350 mode (mode 10h) */
regset.x.ax = 0x0010; regset.x.ax = 0x0010;
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
/* Modify the sync polarity bits (bits 7 &amp 6) of the /* Modify the sync polarity bits (bits 7 &amp; 6) of the
Miscellaneous Output register (readable at 0x3CC, writable at Miscellaneous Output register (readable at 0x3CC, writable at
0x3C2) to select the 400-scan-line vertical scanning rate */ 0x3C2) to select the 400-scan-line vertical scanning rate */
outp(0x3C2, ((inp(0x3CC) &amp 0x3F) | 0x40)); outp(0x3C2, ((inp(0x3CC) &amp; 0x3F) | 0x40));
/* Now, tweak the registers needed to convert the vertical /* Now, tweak the registers needed to convert the vertical
timings from 350 to 400 scan lines */ timings from 350 to 400 scan lines */

View file

@ -98,7 +98,7 @@ void main()
/* Return to text mode and exit */ /* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
void Wait30Frames() void Wait30Frames()
@ -107,9 +107,9 @@ void Wait30Frames()
for (i=0; i&lt;30; i++) { for (i=0; i&lt;30; i++) {
/* Wait until we&rsquo;re not in vertical sync, so we can catch leading edge */ /* Wait until we&rsquo;re not in vertical sync, so we can catch leading edge */
while ((inp(INPUT_STATUS_1) &amp 0x08) != 0) ; while ((inp(INPUT_STATUS_1) &amp; 0x08) != 0) ;
/* Wait until we are in vertical sync */ /* Wait until we are in vertical sync */
while ((inp(INPUT_STATUS_1) &amp 0x08) == 0) ; while ((inp(INPUT_STATUS_1) &amp; 0x08) == 0) ;
} }
} }
</PRE> </PRE>
@ -132,7 +132,7 @@ void Set640x400()
regs.h.ah = 0x11; /* character generator function */ regs.h.ah = 0x11; /* character generator function */
regs.h.al = 0x24; /* use ROM 8x6 character set for graphics */ regs.h.al = 0x24; /* use ROM 8x6 character set for graphics */
regs.h.bl = 2; /* 25 rows */ regs.h.bl = 2; /* 25 rows */
int86(0x10, &ampregs, &ampregs); /* invoke the BIOS video interrupt int86(0x10, &amp;regs, &amp;regs); /* invoke the BIOS video interrupt
to set up the text */ to set up the text */
} }
</PRE> </PRE>

View file

@ -43,11 +43,11 @@
featuring internal animation, masked images (sprites), and nonoverlapping dirty featuring internal animation, masked images (sprites), and nonoverlapping dirty
rectangle copying. Tested with Borland C++ in the small model. */ rectangle copying. Tested with Borland C++ in the small model. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltalloc.h&gt #include &lt;alloc.h&gt;
#include &ltmemory.h&gt #include &lt;memory.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
/* Comment out to disable overlap elimination in the dirty rectangle list. */ /* Comment out to disable overlap elimination in the dirty rectangle list. */
#define CHECK-OVERLAP 1 #define CHECK-OVERLAP 1
@ -176,25 +176,25 @@ void main()
ScreenPtr = MK-FP(SCREEN-SEGMENT, 0); ScreenPtr = MK-FP(SCREEN-SEGMENT, 0);
/* Set up the entities we&rsquo;ll animate, at random locations */ /* Set up the entities we&rsquo;ll animate, at random locations */
randomize(); randomize();
for (= 0; &lt NUM-ENTITIES; i++) { for (= 0; &lt; NUM-ENTITIES; i++) {
Entities[i].X = random(SCREEN-WIDTH - IMAGE-WIDTH); Entities[i].X = random(SCREEN-WIDTH - IMAGE-WIDTH);
Entities[i].Y = random(SCREEN-HEIGHT - IMAGE-HEIGHT); Entities[i].Y = random(SCREEN-HEIGHT - IMAGE-HEIGHT);
Entities[i].XDirection = 1; Entities[i].XDirection = 1;
Entities[i].YDirection = -1; Entities[i].YDirection = -1;
Entities[i].InternalAnimateCount = &amp 1; Entities[i].InternalAnimateCount = &amp; 1;
Entities[i].InternalAnimateMax = 2; Entities[i].InternalAnimateMax = 2;
} }
/* Set the dirty rectangle list to empty, and set up the head/tail node /* Set the dirty rectangle list to empty, and set up the head/tail node
as a sentinel */ as a sentinel */
NumDirtyRectangles = 0; NumDirtyRectangles = 0;
DirtyHead.Next = &ampDirtyHead; DirtyHead.Next = &amp;DirtyHead;
DirtyHead.Top = 0x7FFF; DirtyHead.Top = 0x7FFF;
DirtyHead.Left= 0x7FFF; DirtyHead.Left= 0x7FFF;
DirtyHead.Bottom = 0x7FFF; DirtyHead.Bottom = 0x7FFF;
DirtyHead.Right = 0x7FFF; DirtyHead.Right = 0x7FFF;
/* Set 320x200 256-color graphics mode */ /* Set 320x200 256-color graphics mode */
regs.x.ax = 0x0013; regs.x.ax = 0x0013;
int86(0x10, &ampregs, &ampregs); int86(0x10, &amp;regs, &amp;regs);
/* Loop and draw until a key is pressed */ /* Loop and draw until a key is pressed */
do { do {
/* Draw the entities to the system buffer at their current locations, /* Draw the entities to the system buffer at their current locations,
@ -205,19 +205,19 @@ void main()
CopyDirtyRectanglesToScreen(); CopyDirtyRectanglesToScreen();
/* Reset the dirty rectangle list to empty */ /* Reset the dirty rectangle list to empty */
NumDirtyRectangles = 0; NumDirtyRectangles = 0;
DirtyHead.Next = &ampDirtyHead; DirtyHead.Next = &amp;DirtyHead;
/* Erase the entities in the system buffer at their old locations, /* Erase the entities in the system buffer at their old locations,
updating the dirty rectangle list */ updating the dirty rectangle list */
EraseEntities(); EraseEntities();
/* Move the entities, bouncing off the edges of the screen */ /* Move the entities, bouncing off the edges of the screen */
for (= 0; &lt NUM-ENTITIES; i++) { for (= 0; &lt; NUM-ENTITIES; i++) {
XTemp = Entities[i].X + Entities[i].XDirection; XTemp = Entities[i].X + Entities[i].XDirection;
YTemp = Entities[i].Y + Entities[i].YDirection; YTemp = Entities[i].Y + Entities[i].YDirection;
if ((XTemp &lt 0) || ((XTemp + IMAGE-WIDTH) &gt SCREEN-WIDTH)) { if ((XTemp &lt; 0) || ((XTemp + IMAGE-WIDTH) &gt; SCREEN-WIDTH)) {
Entities[i].XDirection = -Entities[i].XDirection; Entities[i].XDirection = -Entities[i].XDirection;
XTemp = Entities[i].X + Entities[i].XDirection; XTemp = Entities[i].X + Entities[i].XDirection;
} }
if ((YTemp &lt 0) || ((YTemp + IMAGE-HEIGHT) &gt SCREEN-HEIGHT)) { if ((YTemp &lt; 0) || ((YTemp + IMAGE-HEIGHT) &gt; SCREEN-HEIGHT)) {
Entities[i].YDirection = -Entities[i].YDirection; Entities[i].YDirection = -Entities[i].YDirection;
YTemp = Entities[i].Y + Entities[i].YDirection; YTemp = Entities[i].Y + Entities[i].YDirection;
} }
@ -229,7 +229,7 @@ void main()
/* Return back to text mode */ /* Return back to text mode */
regs.x.ax = 0x0003; regs.x.ax = 0x0003;
int86(0x10, &ampregs, &ampregs); int86(0x10, &amp;regs, &amp;regs);
} }
/* Draw entities at their current locations, updating dirty rectangle list. */ /* Draw entities at their current locations, updating dirty rectangle list. */
void DrawEntities() void DrawEntities()
@ -240,20 +240,20 @@ void DrawEntities()
char *TempPtrMask; char *TempPtrMask;
Entity *EntityPtr; Entity *EntityPtr;
for (= 0, EntityPtr = Entities; &lt NUM-ENTITIES; i++, EntityPtr++) { for (= 0, EntityPtr = Entities; &lt; NUM-ENTITIES; i++, EntityPtr++) {
/* Remember the dirty rectangle info for this entity */ /* Remember the dirty rectangle info for this entity */
AddDirtyRect(EntityPtr, IMAGE-HEIGHT, IMAGE-WIDTH); AddDirtyRect(EntityPtr, IMAGE-HEIGHT, IMAGE-WIDTH);
/* Point to the destination in the system buffer */ /* Point to the destination in the system buffer */
RowPtrBuffer = SystemBufferPtr + (EntityPtr-&gtY * SCREEN-WIDTH) + RowPtrBuffer = SystemBufferPtr + (EntityPtr-&gt;Y * SCREEN-WIDTH) +
EntityPtr-&gtX; EntityPtr-&gt;X;
/* Advance the image animation pointer */ /* Advance the image animation pointer */
if (++EntityPtr-&gtInternalAnimateCount &gt= if (++EntityPtr-&gt;InternalAnimateCount &gt;=
EntityPtr-&gtInternalAnimateMax) { EntityPtr-&gt;InternalAnimateMax) {
EntityPtr-&gtInternalAnimateCount = 0; EntityPtr-&gt;InternalAnimateCount = 0;
} }
/* Point to the image and mask to draw */ /* Point to the image and mask to draw */
TempPtrImage = ImagePixelArray[EntityPtr-&gtInternalAnimateCount]; TempPtrImage = ImagePixelArray[EntityPtr-&gt;InternalAnimateCount];
TempPtrMask = ImageMaskArray[EntityPtr-&gtInternalAnimateCount]; TempPtrMask = ImageMaskArray[EntityPtr-&gt;InternalAnimateCount];
DrawMasked(RowPtrBuffer, TempPtrImage, TempPtrMask, IMAGE-HEIGHT, DrawMasked(RowPtrBuffer, TempPtrImage, TempPtrMask, IMAGE-HEIGHT,
IMAGE-WIDTH, SCREEN-WIDTH); IMAGE-WIDTH, SCREEN-WIDTH);
} }
@ -274,18 +274,18 @@ void CopyDirtyRectanglesToScreen()
/* Copy only the dirty rectangles, in the YX-sorted order in which /* Copy only the dirty rectangles, in the YX-sorted order in which
they&rsquo;re linked */ they&rsquo;re linked */
DirtyPtr = DirtyHead.Next; DirtyPtr = DirtyHead.Next;
for (= 0; &lt NumDirtyRectangles; i++) { for (= 0; &lt; NumDirtyRectangles; i++) {
/* Offset in both system buffer and screen of image */ /* Offset in both system buffer and screen of image */
Offset = (unsigned int) (DirtyPtr-&gtTop * SCREEN-WIDTH) + Offset = (unsigned int) (DirtyPtr-&gt;Top * SCREEN-WIDTH) +
DirtyPtr-&gtLeft; DirtyPtr-&gt;Left;
/* Dimensions of dirty rectangle */ /* Dimensions of dirty rectangle */
RectWidth = DirtyPtr-&gtRight - DirtyPtr-&gtLeft; RectWidth = DirtyPtr-&gt;Right - DirtyPtr-&gt;Left;
RectHeight = DirtyPtr-&gtBottom - DirtyPtr-&gtTop; RectHeight = DirtyPtr-&gt;Bottom - DirtyPtr-&gt;Top;
/* Copy a dirty rectangle */ /* Copy a dirty rectangle */
CopyRect(ScreenPtr + Offset, SystemBufferPtr + Offset, CopyRect(ScreenPtr + Offset, SystemBufferPtr + Offset,
RectHeight, RectWidth, SCREEN-WIDTH, SCREEN-WIDTH); RectHeight, RectWidth, SCREEN-WIDTH, SCREEN-WIDTH);
/* Point to the next dirty rectangle */ /* Point to the next dirty rectangle */
DirtyPtr = DirtyPtr-&gtNext; DirtyPtr = DirtyPtr-&gt;Next;
} }
} }
} }
@ -296,9 +296,9 @@ void EraseEntities()
int i; int i;
char far *RowPtr; char far *RowPtr;
for (= 0; &lt NUM-ENTITIES; i++) { for (= 0; &lt; NUM-ENTITIES; i++) {
/* Remember the dirty rectangle info for this entity */ /* Remember the dirty rectangle info for this entity */
AddDirtyRect(&ampEntities[i], IMAGE-HEIGHT, IMAGE-WIDTH); AddDirtyRect(&amp;Entities[i], IMAGE-HEIGHT, IMAGE-WIDTH);
/* Point to the destination in the system buffer */ /* Point to the destination in the system buffer */
RowPtr = SystemBufferPtr + (Entities[i].Y * SCREEN-WIDTH) + RowPtr = SystemBufferPtr + (Entities[i].Y * SCREEN-WIDTH) +
Entities[i].X; Entities[i].X;
@ -321,7 +321,7 @@ void EraseEntities()
DirtyRectangle * TempPtr; DirtyRectangle * TempPtr;
Entity TempEntity; Entity TempEntity;
int i; int i;
if (NumDirtyRectangles &gt= MAX-DIRTY-RECTANGLES) { if (NumDirtyRectangles &gt;= MAX-DIRTY-RECTANGLES) {
/* Too many dirty rectangles; just redraw the whole screen */ /* Too many dirty rectangles; just redraw the whole screen */
DrawWholeScreen = 1; DrawWholeScreen = 1;
return; return;
@ -332,53 +332,53 @@ void EraseEntities()
#ifdef CHECK-OVERLAP #ifdef CHECK-OVERLAP
/* Check for overlap with existing rectangles */ /* Check for overlap with existing rectangles */
TempPtr = DirtyHead.Next; TempPtr = DirtyHead.Next;
for (= 0; &lt NumDirtyRectangles; i++, TempPtr = TempPtr-&gtNext) { for (= 0; &lt; NumDirtyRectangles; i++, TempPtr = TempPtr-&gt;Next) {
if ((TempPtr-&gtLeft &lt (pEntity-&gtX + ImageWidth)) &amp&amp if ((TempPtr-&gt;Left &lt; (pEntity-&gt;X + ImageWidth)) &amp;&amp;
(TempPtr-&gtRight &gt pEntity-&gtX) &amp&amp (TempPtr-&gt;Right &gt; pEntity-&gt;X) &amp;&amp;
(TempPtr-&gtTop &lt (pEntity-&gtY + ImageHeight)) &amp&amp (TempPtr-&gt;Top &lt; (pEntity-&gt;Y + ImageHeight)) &amp;&amp;
(TempPtr-&gtBottom &gt pEntity-&gtY)) { (TempPtr-&gt;Bottom &gt; pEntity-&gt;Y)) {
/* We&rsquo;ve found an overlapping rectangle. Calculate the /* We&rsquo;ve found an overlapping rectangle. Calculate the
rectangles, if any, remaining after subtracting out the rectangles, if any, remaining after subtracting out the
overlapped areas, and add them to the dirty list */ overlapped areas, and add them to the dirty list */
/* Check for a nonoverlapped left portion */ /* Check for a nonoverlapped left portion */
if (TempPtr-&gtLeft &gt pEntity-&gtX) { if (TempPtr-&gt;Left &gt; pEntity-&gt;X) {
/* There&rsquo;s definitely a nonoverlapped portion at the left; add /* There&rsquo;s definitely a nonoverlapped portion at the left; add
it, but only to at most the top and bottom of the overlapping it, but only to at most the top and bottom of the overlapping
rect; top and bottom strips are taken care of below */ rect; top and bottom strips are taken care of below */
TempEntity.X = pEntity-&gtX; TempEntity.X = pEntity-&gt;X;
TempEntity.Y = max(pEntity-&gtY, TempPtr-&gtTop); TempEntity.Y = max(pEntity-&gt;Y, TempPtr-&gt;Top);
AddDirtyRect(&ampTempEntity, AddDirtyRect(&amp;TempEntity,
min(pEntity-&gtY + ImageHeight, TempPtr-&gtBottom) - min(pEntity-&gt;Y + ImageHeight, TempPtr-&gt;Bottom) -
TempEntity.Y, TempEntity.Y,
TempPtr-&gtLeft - pEntity-&gtX); TempPtr-&gt;Left - pEntity-&gt;X);
} }
/* Check for a nonoverlapped right portion */ /* Check for a nonoverlapped right portion */
if (TempPtr-&gtRight &lt (pEntity-&gtX + ImageWidth)) { if (TempPtr-&gt;Right &lt; (pEntity-&gt;X + ImageWidth)) {
/* There&rsquo;s definitely a nonoverlapped portion at the right; add /* There&rsquo;s definitely a nonoverlapped portion at the right; add
it, but only to at most the top and bottom of the overlapping it, but only to at most the top and bottom of the overlapping
rect; top and bottom strips are taken care of below */ rect; top and bottom strips are taken care of below */
TempEntity.X = TempPtr-&gtRight; TempEntity.X = TempPtr-&gt;Right;
TempEntity.Y = max(pEntity-&gtY, TempPtr-&gtTop); TempEntity.Y = max(pEntity-&gt;Y, TempPtr-&gt;Top);
AddDirtyRect(&ampTempEntity, AddDirtyRect(&amp;TempEntity,
min(pEntity-&gtY + ImageHeight, TempPtr-&gtBottom) - min(pEntity-&gt;Y + ImageHeight, TempPtr-&gt;Bottom) -
TempEntity.Y, TempEntity.Y,
(pEntity-&gtX + ImageWidth) - TempPtr-&gtRight); (pEntity-&gt;X + ImageWidth) - TempPtr-&gt;Right);
} }
/* Check for a nonoverlapped top portion */ /* Check for a nonoverlapped top portion */
if (TempPtr-&gtTop &gt pEntity-&gtY) { if (TempPtr-&gt;Top &gt; pEntity-&gt;Y) {
/* There&rsquo;s a top portion that&rsquo;s not overlapped */ /* There&rsquo;s a top portion that&rsquo;s not overlapped */
TempEntity.X = pEntity-&gtX; TempEntity.X = pEntity-&gt;X;
TempEntity.Y = pEntity-&gtY; TempEntity.Y = pEntity-&gt;Y;
AddDirtyRect(&ampTempEntity, TempPtr-&gtTop - pEntity-&gtY, ImageWidth); AddDirtyRect(&amp;TempEntity, TempPtr-&gt;Top - pEntity-&gt;Y, ImageWidth);
} }
/* Check for a nonoverlapped bottom portion */ /* Check for a nonoverlapped bottom portion */
if (TempPtr-&gtBottom &lt (pEntity-&gtY + ImageHeight)) { if (TempPtr-&gt;Bottom &lt; (pEntity-&gt;Y + ImageHeight)) {
/* There&rsquo;s a bottom portion that&rsquo;s not overlapped */ /* There&rsquo;s a bottom portion that&rsquo;s not overlapped */
TempEntity.X = pEntity-&gtX; TempEntity.X = pEntity-&gt;X;
TempEntity.Y = TempPtr-&gtBottom; TempEntity.Y = TempPtr-&gt;Bottom;
AddDirtyRect(&ampTempEntity, AddDirtyRect(&amp;TempEntity,
(pEntity-&gtY + ImageHeight) - TempPtr-&gtBottom, ImageWidth); (pEntity-&gt;Y + ImageHeight) - TempPtr-&gt;Bottom, ImageWidth);
} }
/* We&rsquo;ve added all non-overlapped portions to the dirty list */ /* We&rsquo;ve added all non-overlapped portions to the dirty list */
return; return;
@ -389,22 +389,22 @@ void EraseEntities()
add this rectangle as-is */ add this rectangle as-is */
/* Find the YX-sorted insertion point. Searches will always terminate, /* Find the YX-sorted insertion point. Searches will always terminate,
because the head/tail rectangle is set to the maximum values */ because the head/tail rectangle is set to the maximum values */
TempPtr = &ampDirtyHead; TempPtr = &amp;DirtyHead;
while (((DirtyRectangle *)TempPtr-&gtNext)-&gtTop &lt pEntity-&gtY) { while (((DirtyRectangle *)TempPtr-&gt;Next)-&gt;Top &lt; pEntity-&gt;Y) {
TempPtr = TempPtr-&gtNext; TempPtr = TempPtr-&gt;Next;
} }
while ((((DirtyRectangle *)TempPtr-&gtNext)-&gtTop == pEntity-&gtY) &amp&amp while ((((DirtyRectangle *)TempPtr-&gt;Next)-&gt;Top == pEntity-&gt;Y) &amp;&amp;
(((DirtyRectangle *)TempPtr-&gtNext)-&gtLeft &lt pEntity-&gtX)) { (((DirtyRectangle *)TempPtr-&gt;Next)-&gt;Left &lt; pEntity-&gt;X)) {
TempPtr = TempPtr-&gtNext; TempPtr = TempPtr-&gt;Next;
} }
/* Set the rectangle and actually add it to the dirty list */ /* Set the rectangle and actually add it to the dirty list */
DirtyPtr = &ampDirtyRectangles[NumDirtyRectangles++]; DirtyPtr = &amp;DirtyRectangles[NumDirtyRectangles++];
DirtyPtr-&gtLeft = pEntity-&gtX; DirtyPtr-&gt;Left = pEntity-&gt;X;
DirtyPtr-&gtTop = pEntity-&gtY; DirtyPtr-&gt;Top = pEntity-&gt;Y;
DirtyPtr-&gtRight = pEntity-&gtX + ImageWidth; DirtyPtr-&gt;Right = pEntity-&gt;X + ImageWidth;
DirtyPtr-&gtBottom = pEntity-&gtY + ImageHeight; DirtyPtr-&gt;Bottom = pEntity-&gt;Y + ImageHeight;
DirtyPtr-&gtNext = TempPtr-&gtNext; DirtyPtr-&gt;Next = TempPtr-&gt;Next;
TempPtr-&gtNext = DirtyPtr; TempPtr-&gt;Next = DirtyPtr;
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -182,7 +182,7 @@ void main() {
} }
getch(); getch();
regset.x.ax = 0x0003; /* switch back to text mode and done */ regset.x.ax = 0x0003; /* switch back to text mode and done */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -58,8 +58,8 @@
rectangle fills by filling the screen with adjacent 80x60 rectangle fills by filling the screen with adjacent 80x60
rectangles in a variety of patterns. Tested with Borland C++ rectangles in a variety of patterns. Tested with Borland C++
in C compilation mode and the small model */ in C compilation mode and the small model */
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
void Set320x240Mode(void); void Set320x240Mode(void);
void FillPatternX(int, int, int, int, unsigned int, char*); void FillPatternX(int, int, int, int, unsigned int, char*);
@ -89,14 +89,14 @@ void main() {
union REGS regset; union REGS regset;
Set320x240Mode(); Set320x240Mode();
for (j = 0; j &lt 4; j++) { for (j = 0; j &lt; 4; j++) {
for (i = 0; i &lt 4; i++) { for (i = 0; i &lt; 4; i++) {
FillPatternX(i*80,j*60,i*80+80,j*60+60,0,PattTable[j*4+i]); FillPatternX(i*80,j*60,i*80+80,j*60+60,0,PattTable[j*4+i]);
} }
} }
getch(); getch();
regset.x.ax = 0x0003; /* switch back to text mode and done */ regset.x.ax = 0x0003; /* switch back to text mode and done */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -196,7 +196,7 @@ DoRightEdge:
; latches) ; latches)
CopyLoopBottom: CopyLoopBottom:
add si,[bp+SourceNextScanOffset] ;point to the start of add si,[bp+SourceNextScanOffset] ;point to the start of
add di,[bp+DestNextScanOffset] ; next source &amp dest lines add di,[bp+DestNextScanOffset] ; next source &amp; dest lines
dec word ptr [bp+Height] ;count down scan lines dec word ptr [bp+Height] ;count down scan lines
jnz CopyRowsLoop jnz CopyRowsLoop
CopyDone: CopyDone:

View file

@ -134,26 +134,26 @@ typedef struct {
MaskedImage *Image; MaskedImage *Image;
} AnimatedObject; } AnimatedObject;
AnimatedObject AnimatedObjects[] = { AnimatedObject AnimatedObjects[] = {
{ 0, 0,KITE_WIDTH,KITE_HEIGHT, 1, 1, 0, 0,&ampKiteImage}, { 0, 0,KITE_WIDTH,KITE_HEIGHT, 1, 1, 0, 0,&amp;KiteImage},
{ 10, 10,KITE_WIDTH,KITE_HEIGHT, 0, 1, 10, 10,&ampKiteImage}, { 10, 10,KITE_WIDTH,KITE_HEIGHT, 0, 1, 10, 10,&amp;KiteImage},
{ 20, 20,KITE_WIDTH,KITE_HEIGHT,-1, 1, 20, 20,&ampKiteImage}, { 20, 20,KITE_WIDTH,KITE_HEIGHT,-1, 1, 20, 20,&amp;KiteImage},
{ 30, 30,KITE_WIDTH,KITE_HEIGHT,-1,-1, 30, 30,&ampKiteImage}, { 30, 30,KITE_WIDTH,KITE_HEIGHT,-1,-1, 30, 30,&amp;KiteImage},
{ 40, 40,KITE_WIDTH,KITE_HEIGHT, 1,-1, 40, 40,&ampKiteImage}, { 40, 40,KITE_WIDTH,KITE_HEIGHT, 1,-1, 40, 40,&amp;KiteImage},
{ 50, 50,KITE_WIDTH,KITE_HEIGHT, 0,-1, 50, 50,&ampKiteImage}, { 50, 50,KITE_WIDTH,KITE_HEIGHT, 0,-1, 50, 50,&amp;KiteImage},
{ 60, 60,KITE_WIDTH,KITE_HEIGHT, 1, 0, 60, 60,&ampKiteImage}, { 60, 60,KITE_WIDTH,KITE_HEIGHT, 1, 0, 60, 60,&amp;KiteImage},
{ 70, 70,KITE_WIDTH,KITE_HEIGHT,-1, 0, 70, 70,&ampKiteImage}, { 70, 70,KITE_WIDTH,KITE_HEIGHT,-1, 0, 70, 70,&amp;KiteImage},
{ 80, 80,KITE_WIDTH,KITE_HEIGHT, 1, 2, 80, 80,&ampKiteImage}, { 80, 80,KITE_WIDTH,KITE_HEIGHT, 1, 2, 80, 80,&amp;KiteImage},
{ 90, 90,KITE_WIDTH,KITE_HEIGHT, 0, 2, 90, 90,&ampKiteImage}, { 90, 90,KITE_WIDTH,KITE_HEIGHT, 0, 2, 90, 90,&amp;KiteImage},
{100,100,KITE_WIDTH,KITE_HEIGHT,-1, 2,100,100,&ampKiteImage}, {100,100,KITE_WIDTH,KITE_HEIGHT,-1, 2,100,100,&amp;KiteImage},
{110,110,KITE_WIDTH,KITE_HEIGHT,-1,-2,110,110,&ampKiteImage}, {110,110,KITE_WIDTH,KITE_HEIGHT,-1,-2,110,110,&amp;KiteImage},
{120,120,KITE_WIDTH,KITE_HEIGHT, 1,-2,120,120,&ampKiteImage}, {120,120,KITE_WIDTH,KITE_HEIGHT, 1,-2,120,120,&amp;KiteImage},
{130,130,KITE_WIDTH,KITE_HEIGHT, 0,-2,130,130,&ampKiteImage}, {130,130,KITE_WIDTH,KITE_HEIGHT, 0,-2,130,130,&amp;KiteImage},
{140,140,KITE_WIDTH,KITE_HEIGHT, 2, 0,140,140,&ampKiteImage}, {140,140,KITE_WIDTH,KITE_HEIGHT, 2, 0,140,140,&amp;KiteImage},
{150,150,KITE_WIDTH,KITE_HEIGHT,-2, 0,150,150,&ampKiteImage}, {150,150,KITE_WIDTH,KITE_HEIGHT,-2, 0,150,150,&amp;KiteImage},
{160,160,KITE_WIDTH,KITE_HEIGHT, 2, 2,160,160,&ampKiteImage}, {160,160,KITE_WIDTH,KITE_HEIGHT, 2, 2,160,160,&amp;KiteImage},
{170,170,KITE_WIDTH,KITE_HEIGHT,-2, 2,170,170,&ampKiteImage}, {170,170,KITE_WIDTH,KITE_HEIGHT,-2, 2,170,170,&amp;KiteImage},
{180,180,KITE_WIDTH,KITE_HEIGHT,-2,-2,180,180,&ampKiteImage}, {180,180,KITE_WIDTH,KITE_HEIGHT,-2,-2,180,180,&amp;KiteImage},
{190,190,KITE_WIDTH,KITE_HEIGHT, 2,-2,190,190,&ampKiteImage}, {190,190,KITE_WIDTH,KITE_HEIGHT, 2,-2,190,190,&amp;KiteImage},
}; };
void main(void); void main(void);
void DrawBackground(unsigned int); void DrawBackground(unsigned int);
@ -177,9 +177,9 @@ void main()
union REGS regset; union REGS regset;
Set320x240Mode(); Set320x240Mode();
/* Download the kite image for fast copying later. */ /* Download the kite image for fast copying later. */
if (CreateAlignedMaskedImage(&ampKiteImage, DOWNLOAD_START_OFFSET, if (CreateAlignedMaskedImage(&amp;KiteImage, DOWNLOAD_START_OFFSET,
KitePixels, KITE_WIDTH, KITE_HEIGHT, KiteMask) == 0) { KitePixels, KITE_WIDTH, KITE_HEIGHT, KiteMask) == 0) {
regset.x.ax = 0x0003; int86(0x10, &ampregset, &ampregset); regset.x.ax = 0x0003; int86(0x10, &amp;regset, &amp;regset);
printf(&ldquo;Couldn&rsquo;t get memory\n&rdquo;); exit(); printf(&ldquo;Couldn&rsquo;t get memory\n&rdquo;); exit();
} }
/* Draw the background to the background page. */ /* Draw the background to the background page. */
@ -209,7 +209,7 @@ void main()
} }
/* Move and draw each object in the nondisplayed page. */ /* Move and draw each object in the nondisplayed page. */
for (i=0; i&lt;NUM_OBJECTS; i++) { for (i=0; i&lt;NUM_OBJECTS; i++) {
MoveObject(&ampAnimatedObjects[i]); MoveObject(&amp;AnimatedObjects[i]);
/* Draw object into nondisplayed page at new location */ /* Draw object into nondisplayed page at new location */
CopyScreenToScreenMaskedX(0, 0, AnimatedObjects[i].Width, CopyScreenToScreenMaskedX(0, 0, AnimatedObjects[i].Width,
AnimatedObjects[i].Height, AnimatedObjects[i].X, AnimatedObjects[i].Height, AnimatedObjects[i].X,
@ -224,7 +224,7 @@ void main()
} }
} while (!Done); } while (!Done);
/* Restore text mode and done. */ /* Restore text mode and done. */
regset.x.ax = 0x0003; int86(0x10, &ampregset, &ampregset); regset.x.ax = 0x0003; int86(0x10, &amp;regset, &amp;regset);
} }
void DrawBackground(unsigned int PageStart) void DrawBackground(unsigned int PageStart)
{ {

View file

@ -67,7 +67,7 @@ HLinePtr dw ? ;pointer to list of horz lines
HLineList ends HLineList ends
Parms struc Parms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
HLineListPtr dw ? ;pointer to HLineList structure HLineListPtr dw ? ;pointer to HLineList structure
Color dw ? ;color with which to fill Color dw ? ;color with which to fill
Parms ends Parms ends
@ -149,10 +149,10 @@ MaxXNotClipped:
add di,dx ;offset of first rect pixel in display mem add di,dx ;offset of first rect pixel in display mem
mov dx,si ;XStart mov dx,si ;XStart
and si,0003h ;look up left-edge plane mask and si,0003h ;look up left-edge plane mask
mov bh,LeftClipPlaneMask[si] ; to clip &amp put in BH mov bh,LeftClipPlaneMask[si] ; to clip &amp; put in BH
mov si,cx mov si,cx
and si,0003h ;look up right-edge plane and si,0003h ;look up right-edge plane
mov bl,RightClipPlaneMask[si] ; mask to clip &amp put in BL mov bl,RightClipPlaneMask[si] ; mask to clip &amp; put in BL
and dx,not 011b ;calculate # of addresses across rect and dx,not 011b ;calculate # of addresses across rect
sub cx,dx sub cx,dx
shr cx,1 shr cx,1

View file

@ -59,9 +59,9 @@ void XformVec(double Xform[4][4], double * SourceVec,
{ {
int i,j; int i,j;
for (i=0; i&lt4; i++) { for (i=0; i&lt;4; i++) {
DestVec[i] = 0; DestVec[i] = 0;
for (j=0; j&lt4; j++) for (j=0; j&lt;4; j++)
DestVec[i] += Xform[i][j] * SourceVec[j]; DestVec[i] += Xform[i][j] * SourceVec[j];
} }
} }
@ -79,10 +79,10 @@ void ConcatXforms(double SourceXform1[4][4], double SourceXform2[4][4],
{ {
int i,j,k; int i,j,k;
for (i=0; i&lt4; i++) { for (i=0; i&lt;4; i++) {
for (j=0; j&lt4; j++) { for (j=0; j&lt;4; j++) {
DestXform[i][j] = 0; DestXform[i][j] = 0;
for (k=0; k&lt4; k++) for (k=0; k&lt;4; k++)
DestXform[i][j] += SourceXform1[i][k] * SourceXform2[k][j]; DestXform[i][j] += SourceXform1[i][k] * SourceXform2[k][j];
} }
} }
@ -110,10 +110,10 @@ void XformAndProjectPoly(double Xform[4][4], struct Point3 * Poly,
struct PointListHeader Polygon; struct PointListHeader Polygon;
/* Transform to view space, then project to the screen */ /* Transform to view space, then project to the screen */
for (i=0; i&ltPolyLength; i++) { for (i=0; i&lt;PolyLength; i++) {
/* Transform to view space */ /* Transform to view space */
XformVec(Xform, (double *)&ampPoly[i], (double *)&ampXformedPoly[i]); XformVec(Xform, (double *)&amp;Poly[i], (double *)&amp;XformedPoly[i]);
/* Project the X &amp Y coordinates to the screen, rounding to the /* Project the X &amp; Y coordinates to the screen, rounding to the
nearest integral coordinates. The Y coordinate is negated to nearest integral coordinates. The Y coordinate is negated to
flip from view space, where increasing Y is up, to screen flip from view space, where increasing Y is up, to screen
space, where increasing Y is down. Add in half the screen space, where increasing Y is down. Add in half the screen
@ -125,20 +125,20 @@ void XformAndProjectPoly(double Xform[4][4], struct Point3 * Poly,
SCREEN_HEIGHT/2; SCREEN_HEIGHT/2;
/* Appropriately adjust the extent of the rectangle used to /* Appropriately adjust the extent of the rectangle used to
erase this page later */ erase this page later */
if (ProjectedPoly[i].X &gt EraseRect[NonDisplayedPage].Right) if (ProjectedPoly[i].X &gt; EraseRect[NonDisplayedPage].Right)
if (ProjectedPoly[i].X &lt SCREEN_WIDTH) if (ProjectedPoly[i].X &lt; SCREEN_WIDTH)
EraseRect[NonDisplayedPage].Right = ProjectedPoly[i].X; EraseRect[NonDisplayedPage].Right = ProjectedPoly[i].X;
else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH; else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH;
if (ProjectedPoly[i].Y &gt EraseRect[NonDisplayedPage].Bottom) if (ProjectedPoly[i].Y &gt; EraseRect[NonDisplayedPage].Bottom)
if (ProjectedPoly[i].Y &lt SCREEN_HEIGHT) if (ProjectedPoly[i].Y &lt; SCREEN_HEIGHT)
EraseRect[NonDisplayedPage].Bottom = ProjectedPoly[i].Y; EraseRect[NonDisplayedPage].Bottom = ProjectedPoly[i].Y;
else EraseRect[NonDisplayedPage].Bottom = SCREEN_HEIGHT; else EraseRect[NonDisplayedPage].Bottom = SCREEN_HEIGHT;
if (ProjectedPoly[i].X &lt EraseRect[NonDisplayedPage].Left) if (ProjectedPoly[i].X &lt; EraseRect[NonDisplayedPage].Left)
if (ProjectedPoly[i].X &gt 0) if (ProjectedPoly[i].X &gt; 0)
EraseRect[NonDisplayedPage].Left = ProjectedPoly[i].X; EraseRect[NonDisplayedPage].Left = ProjectedPoly[i].X;
else EraseRect[NonDisplayedPage].Left = 0; else EraseRect[NonDisplayedPage].Left = 0;
if (ProjectedPoly[i].Y &lt EraseRect[NonDisplayedPage].Top) if (ProjectedPoly[i].Y &lt; EraseRect[NonDisplayedPage].Top)
if (ProjectedPoly[i].Y &gt 0) if (ProjectedPoly[i].Y &gt; 0)
EraseRect[NonDisplayedPage].Top = ProjectedPoly[i].Y; EraseRect[NonDisplayedPage].Top = ProjectedPoly[i].Y;
else EraseRect[NonDisplayedPage].Top = 0; else EraseRect[NonDisplayedPage].Top = 0;
} }

View file

@ -57,7 +57,7 @@
#define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \ #define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \
Polygon.Length = NumPoints; \ Polygon.Length = NumPoints; \
Polygon.PointPtr = PointList; \ Polygon.PointPtr = PointList; \
FillConvexPolygon(&ampPolygon, Color, X, Y); FillConvexPolygon(&amp;Polygon, Color, X, Y);
/* Describes a single 2-D point */ /* Describes a single 2-D point */
struct Point { struct Point {

View file

@ -45,10 +45,10 @@
the direction of increasingly negative Z. A right-handed the direction of increasingly negative Z. A right-handed
coordinate system is used throughout. coordinate system is used throughout.
Tested with Borland C++ in the small model. */ Tested with Borland C++ in the small model. */
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
void main(void); void main(void);
@ -125,7 +125,7 @@ void main() {
/* Flip to display the page into which we just drew */ /* Flip to display the page into which we just drew */
ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]); ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
/* Rotate 6 degrees farther around the Y axis */ /* Rotate 6 degrees farther around the Y axis */
if ((Rotation += (M_PI/30.0)) &gt= (M_PI*2)) Rotation -= M_PI*2; if ((Rotation += (M_PI/30.0)) &gt;= (M_PI*2)) Rotation -= M_PI*2;
if (kbhit()) { if (kbhit()) {
switch (getch()) { switch (getch()) {
case 0x1B: /* Esc to exit */ case 0x1B: /* Esc to exit */
@ -134,7 +134,7 @@ void main() {
PolyWorldXform[2][3] -= 3.0; break; PolyWorldXform[2][3] -= 3.0; break;
case &lsquo;T&rsquo;: /* towards (+Z). Don&rsquo;t allow to get too */ case &lsquo;T&rsquo;: /* towards (+Z). Don&rsquo;t allow to get too */
case &lsquo;t&rsquo;: /* close, so Z clipping isn&rsquo;t needed */ case &lsquo;t&rsquo;: /* close, so Z clipping isn&rsquo;t needed */
if (PolyWorldXform[2][3] &lt -40.0) if (PolyWorldXform[2][3] &lt; -40.0)
PolyWorldXform[2][3] += 3.0; break; PolyWorldXform[2][3] += 3.0; break;
case 0: /* extended code */ case 0: /* extended code */
switch (getch()) { switch (getch()) {
@ -157,7 +157,7 @@ void main() {
} while (!Done); } while (!Done);
/* Return to text mode and exit */ /* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -43,9 +43,9 @@
is fixed at the origin (0,0,0) of world space, looking in the direction of is fixed at the origin (0,0,0) of world space, looking in the direction of
increasingly negative Z. A right-handed coordinate system is used throughout. increasingly negative Z. A right-handed coordinate system is used throughout.
All C code tested with Borland C++ in C compilation mode. */ All C code tested with Borland C++ in C compilation mode. */
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
#define ROTATION (M_PI / 30.0) /* rotate by 6 degrees at a time */ #define ROTATION (M_PI / 30.0) /* rotate by 6 degrees at a time */
@ -121,12 +121,12 @@ void main() {
/* Keep transforming the cube, drawing it to the undisplayed page, /* Keep transforming the cube, drawing it to the undisplayed page,
and flipping the page to show it */ and flipping the page to show it */
do { do {
/* Regenerate the object-&gtview transformation and /* Regenerate the object-&gt;view transformation and
retransform/project if necessary */ retransform/project if necessary */
if (RecalcXform) { if (RecalcXform) {
ConcatXforms(WorldViewXform, CubeWorldXform, WorkingXform); ConcatXforms(WorldViewXform, CubeWorldXform, WorkingXform);
/* Transform and project all the vertices in the cube */ /* Transform and project all the vertices in the cube */
XformAndProjectPoints(WorkingXform, &ampCube); XformAndProjectPoints(WorkingXform, &amp;Cube);
RecalcXform = 0; RecalcXform = 0;
} }
CurrentPageBase = /* select other page for drawing to */ CurrentPageBase = /* select other page for drawing to */
@ -142,7 +142,7 @@ void main() {
EraseRect[NonDisplayedPage].Right = EraseRect[NonDisplayedPage].Right =
EraseRect[NonDisplayedPage].Bottom = 0; EraseRect[NonDisplayedPage].Bottom = 0;
/* Draw all visible faces of the cube */ /* Draw all visible faces of the cube */
DrawVisibleFaces(&ampCube); DrawVisibleFaces(&amp;Cube);
/* Flip to display the page into which we just drew */ /* Flip to display the page into which we just drew */
ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]); ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
while (kbhit()) { while (kbhit()) {
@ -153,7 +153,7 @@ void main() {
CubeWorldXform[2][3] -= 3.0; RecalcXform = 1; break; CubeWorldXform[2][3] -= 3.0; RecalcXform = 1; break;
case &lsquo;T&rsquo;: /* towards (+Z). Don&rsquo;t allow to get too */ case &lsquo;T&rsquo;: /* towards (+Z). Don&rsquo;t allow to get too */
case &lsquo;t&rsquo;: /* close, so Z clipping isn&rsquo;t needed */ case &lsquo;t&rsquo;: /* close, so Z clipping isn&rsquo;t needed */
if (CubeWorldXform[2][3] &lt -40.0) { if (CubeWorldXform[2][3] &lt; -40.0) {
CubeWorldXform[2][3] += 3.0; CubeWorldXform[2][3] += 3.0;
RecalcXform = 1; RecalcXform = 1;
} }
@ -197,7 +197,7 @@ void main() {
} while (!Done); } while (!Done);
/* Return to text mode and exit */ /* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -42,34 +42,34 @@
/* Transforms all vertices in the specified object into view spa ce, then /* Transforms all vertices in the specified object into view spa ce, then
perspective projects them to screen space and maps them to screen coordinates, perspective projects them to screen space and maps them to screen coordinates,
storing the results in the object. */ storing the results in the object. */
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo;/ #include &ldquo;polygon.h&rdquo;/
void XformAndProjectPoints(double Xform[4][4], void XformAndProjectPoints(double Xform[4][4],
struct Object * ObjectToXform) struct Object * ObjectToXform)
{ {
int i, NumPoints = ObjectToXform-&gtNumVerts; int i, NumPoints = ObjectToXform-&gt;NumVerts;
struct Point3 * Points = ObjectToXform-&gtVertexList; struct Point3 * Points = ObjectToXform-&gt;VertexList;
struct Point3 * XformedPoints = ObjectToXform-&gtXformedVertexList; struct Point3 * XformedPoints = ObjectToXform-&gt;XformedVertexList;
struct Point3 * ProjectedPoints = ObjectToXform-&gtProjectedVertexList; struct Point3 * ProjectedPoints = ObjectToXform-&gt;ProjectedVertexList;
struct Point * ScreenPoints = ObjectToXform-&gtScreenVertexList; struct Point * ScreenPoints = ObjectToXform-&gt;ScreenVertexList;
for (i=0; i&ltNumPoints; i++, Points++, XformedPoints++, for (i=0; i&lt;NumPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) { ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */ /* Transform to view space */
XformVec(Xform, (double *)Points, (double *)XformedPoints); XformVec(Xform, (double *)Points, (double *)XformedPoints);
/* Perspective-project to screen space */ /* Perspective-project to screen space */
ProjectedPoints-&gtX = XformedPoints-&gtX / XformedPoints-&gtZ * ProjectedPoints-&gt;X = XformedPoints-&gt;X / XformedPoints-&gt;Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0); PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
ProjectedPoints-&gtY = XformedPoints-&gtY / XformedPoints-&gtZ * ProjectedPoints-&gt;Y = XformedPoints-&gt;Y / XformedPoints-&gt;Z *
PROJECTION_RATIO * (SCREEN_WIDTH / 2.0); PROJECTION_RATIO * (SCREEN_WIDTH / 2.0);
ProjectedPoints-&gtZ = XformedPoints-&gtZ; ProjectedPoints-&gt;Z = XformedPoints-&gt;Z;
/* Convert to screen coordinates. The Y coord is negated to /* Convert to screen coordinates. The Y coord is negated to
flip from increasing Y being up to increasing Y being down, flip from increasing Y being up to increasing Y being down,
as expected by the polygon filler. Add in half the screen as expected by the polygon filler. Add in half the screen
width and height to center on the screen. */ width and height to center on the screen. */
ScreenPoints-&gtX = ((int) floor(ProjectedPoints-&gtX + 0.5)) + SCREEN_WIDTH/2; ScreenPoints-&gt;X = ((int) floor(ProjectedPoints-&gt;X + 0.5)) + SCREEN_WIDTH/2;
ScreenPoints-&gtY = (-((int) floor(ProjectedPoints-&gtY + 0.5))) + ScreenPoints-&gt;Y = (-((int) floor(ProjectedPoints-&gt;Y + 0.5))) +
SCREEN_HEIGHT/2; SCREEN_HEIGHT/2;
} }
} }
@ -85,19 +85,19 @@ void XformAndProjectPoints(double Xform[4][4],
void DrawVisibleFaces(struct Object * ObjectToXform) void DrawVisibleFaces(struct Object * ObjectToXform)
{ {
int i, j, NumFaces = ObjectToXform-&gtNumFaces, NumVertices; int i, j, NumFaces = ObjectToXform-&gt;NumFaces, NumVertices;
int * VertNumsPtr; int * VertNumsPtr;
struct Face * FacePtr = ObjectToXform-&gtFaceList; struct Face * FacePtr = ObjectToXform-&gt;FaceList;
struct Point * ScreenPoints = ObjectToXform-&gtScreenVertexList; struct Point * ScreenPoints = ObjectToXform-&gt;ScreenVertexList;
long v1,v2,w1,w2; long v1,v2,w1,w2;
struct Point Vertices[MAX_POLY_LENGTH]; struct Point Vertices[MAX_POLY_LENGTH];
struct PointListHeader Polygon; struct PointListHeader Polygon;
/* Draw each visible face (polygon) of the object in turn */ /* Draw each visible face (polygon) of the object in turn */
for (i=0; i&ltNumFaces; i++, FacePtr++) { for (i=0; i&lt;NumFaces; i++, FacePtr++) {
NumVertices = FacePtr-&gtNumVerts; NumVertices = FacePtr-&gt;NumVerts;
/* Copy over the face&rsquo;s vertices from the vertex list */ /* Copy over the face&rsquo;s vertices from the vertex list */
for (j=0, VertNumsPtr=FacePtr-&gtVertNums; j&ltNumVertices; j++) for (j=0, VertNumsPtr=FacePtr-&gt;VertNums; j&lt;NumVertices; j++)
Vertices[j] = ScreenPoints[*VertNumsPtr++]; Vertices[j] = ScreenPoints[*VertNumsPtr++];
/* Draw only if outside face showing (if the normal to the /* Draw only if outside face showing (if the normal to the
polygon points toward the viewer; that is, has a positive polygon points toward the viewer; that is, has a positive
@ -106,30 +106,30 @@ void DrawVisibleFaces(struct Object * ObjectToXform)
w1 = Vertices[NumVertices-1].X - Vertices[0].X; w1 = Vertices[NumVertices-1].X - Vertices[0].X;
v2 = Vertices[1].Y - Vertices[0].Y; v2 = Vertices[1].Y - Vertices[0].Y;
w2 = Vertices[NumVertices-1].Y - Vertices[0].Y; w2 = Vertices[NumVertices-1].Y - Vertices[0].Y;
if ((v1*w2 - v2*w1) &gt 0) { if ((v1*w2 - v2*w1) &gt; 0) {
/* It is facing the screen, so draw */ /* It is facing the screen, so draw */
/* Appropriately adjust the extent of the rectangle used to /* Appropriately adjust the extent of the rectangle used to
erase this page later */ erase this page later */
for (j=0; j&ltNumVertices; j++) { for (j=0; j&lt;NumVertices; j++) {
if (Vertices[j].X &gt EraseRect[NonDisplayedPage].Right) if (Vertices[j].X &gt; EraseRect[NonDisplayedPage].Right)
if (Vertices[j].X &lt SCREEN_WIDTH) if (Vertices[j].X &lt; SCREEN_WIDTH)
EraseRect[NonDisplayedPage].Right = Vertices[j].X; EraseRect[NonDisplayedPage].Right = Vertices[j].X;
else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH; else EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH;
if (Vertices[j].Y &gt EraseRect[NonDisplayedPage].Bottom) if (Vertices[j].Y &gt; EraseRect[NonDisplayedPage].Bottom)
if (Vertices[j].Y &lt SCREEN_HEIGHT) if (Vertices[j].Y &lt; SCREEN_HEIGHT)
EraseRect[NonDisplayedPage].Bottom = Vertices[j].Y; EraseRect[NonDisplayedPage].Bottom = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Bottom=SCREEN_HEIGHT; else EraseRect[NonDisplayedPage].Bottom=SCREEN_HEIGHT;
if (Vertices[j].X &lt EraseRect[NonDisplayedPage].Left) if (Vertices[j].X &lt; EraseRect[NonDisplayedPage].Left)
if (Vertices[j].X &gt 0) if (Vertices[j].X &gt; 0)
EraseRect[NonDisplayedPage].Left = Vertices[j].X; EraseRect[NonDisplayedPage].Left = Vertices[j].X;
else EraseRect[NonDisplayedPage].Left = 0; else EraseRect[NonDisplayedPage].Left = 0;
if (Vertices[j].Y &lt EraseRect[NonDisplayedPage].Top) if (Vertices[j].Y &lt; EraseRect[NonDisplayedPage].Top)
if (Vertices[j].Y &gt 0) if (Vertices[j].Y &gt; 0)
EraseRect[NonDisplayedPage].Top = Vertices[j].Y; EraseRect[NonDisplayedPage].Top = Vertices[j].Y;
else EraseRect[NonDisplayedPage].Top = 0; else EraseRect[NonDisplayedPage].Top = 0;
} }
/* Draw the polygon */ /* Draw the polygon */
DRAW_POLYGON(Vertices, NumVertices, FacePtr-&gtColor, 0, 0); DRAW_POLYGON(Vertices, NumVertices, FacePtr-&gt;Color, 0, 0);
} }
} }
} }

View file

@ -47,7 +47,7 @@
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* Routines to perform incremental rotations around the three axes */ /* Routines to perform incremental rotations around the three axes */
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
/* Concatenate a rotation by Angle around the X axis to the transformation in /* Concatenate a rotation by Angle around the X axis to the transformation in

View file

@ -54,7 +54,7 @@
all vertices offset by (X,Y) */ all vertices offset by (X,Y) */
#define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \ #define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \
Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \ Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \
FillConvexPolygon(&ampPolygon, Color, X, Y); FillConvexPolygon(&amp;Polygon, Color, X, Y);
/* Describes a single 2D point */ /* Describes a single 2D point */
struct Point { struct Point {
int X; /* X coordinate */ int X; /* X coordinate */

View file

@ -42,8 +42,8 @@
/* 3-D animation program to rotate 12 cubes. Uses fixed point. All C code /* 3-D animation program to rotate 12 cubes. Uses fixed point. All C code
tested with Borland C++ in C compilation mode and the small model. */ tested with Borland C++ in C compilation mode and the small model. */
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
/* base offset of page to which to draw */ /* base offset of page to which to draw */
@ -73,11 +73,11 @@ void main() {
and flipping the page to show it */ and flipping the page to show it */
do { do {
/* For each object, regenerate viewing info, if necessary */ /* For each object, regenerate viewing info, if necessary */
for (i=0; i&ltNumObjects; i++) { for (i=0; i&lt;NumObjects; i++) {
if ((ObjectPtr = ObjectList[i])-&gtRecalcXform || if ((ObjectPtr = ObjectList[i])-&gt;RecalcXform ||
RecalcAllXforms) { RecalcAllXforms) {
ObjectPtr-&gtRecalcFunc(ObjectPtr); ObjectPtr-&gt;RecalcFunc(ObjectPtr);
ObjectPtr-&gtRecalcXform = 0; ObjectPtr-&gt;RecalcXform = 0;
} }
} }
RecalcAllXforms = 0; RecalcAllXforms = 0;
@ -85,32 +85,32 @@ void main() {
PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1]; PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1];
/* For each object, clear the portion of the non-displayed page /* For each object, clear the portion of the non-displayed page
that was drawn to last time, then reset the erase extent */ that was drawn to last time, then reset the erase extent */
for (i=0; i&ltNumObjects; i++) { for (i=0; i&lt;NumObjects; i++) {
ObjectPtr = ObjectList[i]; ObjectPtr = ObjectList[i];
FillRectangleX(ObjectPtr-&gtEraseRect[NonDisplayedPage].Left, FillRectangleX(ObjectPtr-&gt;EraseRect[NonDisplayedPage].Left,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Top, ObjectPtr-&gt;EraseRect[NonDisplayedPage].Top,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Right, ObjectPtr-&gt;EraseRect[NonDisplayedPage].Right,
ObjectPtr-&gtEraseRect[NonDisplayedPage].Bottom, ObjectPtr-&gt;EraseRect[NonDisplayedPage].Bottom,
CurrentPageBase, 0); CurrentPageBase, 0);
ObjectPtr-&gtEraseRect[NonDisplayedPage].Left = ObjectPtr-&gt;EraseRect[NonDisplayedPage].Left =
ObjectPtr-&gtEraseRect[NonDisplayedPage].Top = 0x7FFF; ObjectPtr-&gt;EraseRect[NonDisplayedPage].Top = 0x7FFF;
ObjectPtr-&gtEraseRect[NonDisplayedPage].Right = ObjectPtr-&gt;EraseRect[NonDisplayedPage].Right =
ObjectPtr-&gtEraseRect[NonDisplayedPage].Bottom = 0; ObjectPtr-&gt;EraseRect[NonDisplayedPage].Bottom = 0;
} }
/* Draw all objects */ /* Draw all objects */
for (i=0; i&ltNumObjects; i++) for (i=0; i&lt;NumObjects; i++)
ObjectList[i]-&gtDrawFunc(ObjectList[i]); ObjectList[i]-&gt;DrawFunc(ObjectList[i]);
/* Flip to display the page into which we just drew */ /* Flip to display the page into which we just drew */
ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]); ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
/* Move and reorient each object */ /* Move and reorient each object */
for (i=0; i&ltNumObjects; i++) for (i=0; i&lt;NumObjects; i++)
ObjectList[i]-&gtMoveFunc(ObjectList[i]); ObjectList[i]-&gt;MoveFunc(ObjectList[i]);
if (kbhit()) if (kbhit())
if (getch() == 0x1B) Done = 1; /* Esc to exit */ if (getch() == 0x1B) Done = 1; /* Esc to exit */
} while (!Done); } while (!Done);
/* Return to text mode and exit */ /* Return to text mode and exit */
regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */
int86(0x10, &ampregset, &ampregset); int86(0x10, &amp;regset, &amp;regset);
exit(1); exit(1);
} }
</PRE> </PRE>
@ -120,45 +120,45 @@ void main() {
<PRE> <PRE>
/* Transforms all vertices in the specified polygon-based object into view /* Transforms all vertices in the specified polygon-based object into view
space, then perspective projects them to screen space and maps them to screen space, then perspective projects them to screen space and maps them to screen
coordinates, storing results in the object. Recalculates object-&gtview coordinates, storing results in the object. Recalculates object-&gt;view
transformation because only if transform changes would we bother transformation because only if transform changes would we bother
to retransform the vertices. */ to retransform the vertices. */
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
void XformAndProjectPObject(PObject * ObjectToXform) void XformAndProjectPObject(PObject * ObjectToXform)
{ {
int i, NumPoints = ObjectToXform-&gtNumVerts; int i, NumPoints = ObjectToXform-&gt;NumVerts;
Point3 * Points = ObjectToXform-&gtVertexList; Point3 * Points = ObjectToXform-&gt;VertexList;
Point3 * XformedPoints = ObjectToXform-&gtXformedVertexList; Point3 * XformedPoints = ObjectToXform-&gt;XformedVertexList;
Point3 * ProjectedPoints = ObjectToXform-&gtProjectedVertexList; Point3 * ProjectedPoints = ObjectToXform-&gt;ProjectedVertexList;
Point * ScreenPoints = ObjectToXform-&gtScreenVertexList; Point * ScreenPoints = ObjectToXform-&gt;ScreenVertexList;
/* Recalculate the object-&gtview transform */ /* Recalculate the object-&gt;view transform */
ConcatXforms(WorldViewXform, ObjectToXform-&gtXformToWorld, ConcatXforms(WorldViewXform, ObjectToXform-&gt;XformToWorld,
ObjectToXform-&gtXformToView); ObjectToXform-&gt;XformToView);
/* Apply that new transformation and project the points */ /* Apply that new transformation and project the points */
for (i=0; i&ltNumPoints; i++, Points++, XformedPoints++, for (i=0; i&lt;NumPoints; i++, Points++, XformedPoints++,
ProjectedPoints++, ScreenPoints++) { ProjectedPoints++, ScreenPoints++) {
/* Transform to view space */ /* Transform to view space */
XformVec(ObjectToXform-&gtXformToView, (Fixedpoint *) Points, XformVec(ObjectToXform-&gt;XformToView, (Fixedpoint *) Points,
(Fixedpoint *) XformedPoints); (Fixedpoint *) XformedPoints);
/* Perspective-project to screen space */ /* Perspective-project to screen space */
ProjectedPoints-&gtX = ProjectedPoints-&gt;X =
FixedMul(FixedDiv(XformedPoints-&gtX, XformedPoints-&gtZ), FixedMul(FixedDiv(XformedPoints-&gt;X, XformedPoints-&gt;Z),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2))); DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints-&gtY = ProjectedPoints-&gt;Y =
FixedMul(FixedDiv(XformedPoints-&gtY, XformedPoints-&gtZ), FixedMul(FixedDiv(XformedPoints-&gt;Y, XformedPoints-&gt;Z),
DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2))); DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
ProjectedPoints-&gtZ = XformedPoints-&gtZ; ProjectedPoints-&gt;Z = XformedPoints-&gt;Z;
/* Convert to screen coordinates. The Y coord is negated to flip from /* Convert to screen coordinates. The Y coord is negated to flip from
increasing Y being up to increasing Y being down, as expected by polygon increasing Y being up to increasing Y being down, as expected by polygon
filler. Add in half the screen width and height to center on screen. */ filler. Add in half the screen width and height to center on screen. */
ScreenPoints-&gtX = ((int) ((ProjectedPoints-&gtX + ScreenPoints-&gt;X = ((int) ((ProjectedPoints-&gt;X +
DOUBLE_TO_FIXED(0.5)) &gt&gt 16)) + SCREEN_WIDTH/2; DOUBLE_TO_FIXED(0.5)) &gt;&gt; 16)) + SCREEN_WIDTH/2;
ScreenPoints-&gtY = (-((int) ((ProjectedPoints-&gtY + ScreenPoints-&gt;Y = (-((int) ((ProjectedPoints-&gt;Y +
DOUBLE_TO_FIXED(0.5)) &gt&gt 16))) + SCREEN_HEIGHT/2; DOUBLE_TO_FIXED(0.5)) &gt;&gt; 16))) + SCREEN_HEIGHT/2;
} }
}<B></B> }<B></B>
</PRE> </PRE>

View file

@ -41,7 +41,7 @@
<PRE> <PRE>
/* Routines to perform incremental rotations around the three axes. */ /* Routines to perform incremental rotations around the three axes. */
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
/* Concatenate a rotation by Angle around the X axis to transformation in /* Concatenate a rotation by Angle around the X axis to transformation in
@ -141,7 +141,7 @@ void XformVec(Xform WorkingXform, Fixedpoint *SourceVec,
{ {
int i; int i;
for (i=0; i&lt3; i++) for (i=0; i&lt;3; i++)
DestVec[i] = FixedMul(WorkingXform[i][0], SourceVec[0]) + DestVec[i] = FixedMul(WorkingXform[i][0], SourceVec[0]) +
FixedMul(WorkingXform[i][1], SourceVec[1]) + FixedMul(WorkingXform[i][1], SourceVec[1]) +
FixedMul(WorkingXform[i][2], SourceVec[2]) + FixedMul(WorkingXform[i][2], SourceVec[2]) +
@ -157,8 +157,8 @@ void ConcatXforms(Xform SourceXform1, Xform SourceXform2,
{ {
int i, j; int i, j;
for (i=0; i&lt3; i++) { for (i=0; i&lt;3; i++) {
for (j=0; j&lt4; j++) for (j=0; j&lt;4; j++)
DestXform[i][j] = DestXform[i][j] =
FixedMul(SourceXform1[i][0], SourceXform2[0][j]) + FixedMul(SourceXform1[i][0], SourceXform2[0][j]) +
FixedMul(SourceXform1[i][1], SourceXform2[1][j]) + FixedMul(SourceXform1[i][1], SourceXform2[1][j]) +
@ -189,10 +189,10 @@ void InitializeFixedPoint()
{ {
int i, j; int i, j;
for (i=0; i&lt3; i++) for (i=0; i&lt;3; i++)
for (j=0; j&lt4; j++) for (j=0; j&lt;4; j++)
WorldViewXform[i][j] = INT_TO_FIXED(IntWorldViewXform[i][j]); WorldViewXform[i][j] = INT_TO_FIXED(IntWorldViewXform[i][j]);
for (i=0; i&ltNUM_CUBE_VERTS; i++) { for (i=0; i&lt;NUM_CUBE_VERTS; i++) {
CubeVerts[i].X = INT_TO_FIXED(IntCubeVerts[i].X); CubeVerts[i].X = INT_TO_FIXED(IntCubeVerts[i].X);
CubeVerts[i].Y = INT_TO_FIXED(IntCubeVerts[i].Y); CubeVerts[i].Y = INT_TO_FIXED(IntCubeVerts[i].Y);
CubeVerts[i].Z = INT_TO_FIXED(IntCubeVerts[i].Z); CubeVerts[i].Z = INT_TO_FIXED(IntCubeVerts[i].Z);

View file

@ -46,26 +46,26 @@
void RotateAndMovePObject(PObject * ObjectToMove) void RotateAndMovePObject(PObject * ObjectToMove)
{ {
if (--ObjectToMove-&gtRDelayCount == 0) { /* rotate */ if (--ObjectToMove-&gt;RDelayCount == 0) { /* rotate */
ObjectToMove-&gtRDelayCount = ObjectToMove-&gtRDelayCountBase; ObjectToMove-&gt;RDelayCount = ObjectToMove-&gt;RDelayCountBase;
if (ObjectToMove-&gtRotate.RotateX != 0.0) if (ObjectToMove-&gt;Rotate.RotateX != 0.0)
AppendRotationX(ObjectToMove-&gtXformToWorld, AppendRotationX(ObjectToMove-&gt;XformToWorld,
ObjectToMove-&gtRotate.RotateX); ObjectToMove-&gt;Rotate.RotateX);
if (ObjectToMove-&gtRotate.RotateY != 0.0) if (ObjectToMove-&gt;Rotate.RotateY != 0.0)
AppendRotationY(ObjectToMove-&gtXformToWorld, AppendRotationY(ObjectToMove-&gt;XformToWorld,
ObjectToMove-&gtRotate.RotateY); ObjectToMove-&gt;Rotate.RotateY);
if (ObjectToMove-&gtRotate.RotateZ != 0.0) if (ObjectToMove-&gt;Rotate.RotateZ != 0.0)
AppendRotationZ(ObjectToMove-&gtXformToWorld, AppendRotationZ(ObjectToMove-&gt;XformToWorld,
ObjectToMove-&gtRotate.RotateZ); ObjectToMove-&gt;Rotate.RotateZ);
ObjectToMove-&gtRecalcXform = 1; ObjectToMove-&gt;RecalcXform = 1;
} }
/* Move in Z, checking for bouncing and stopping */ /* Move in Z, checking for bouncing and stopping */
if (--ObjectToMove-&gtMDelayCount == 0) { if (--ObjectToMove-&gt;MDelayCount == 0) {
ObjectToMove-&gtMDelayCount = ObjectToMove-&gtMDelayCountBase; ObjectToMove-&gt;MDelayCount = ObjectToMove-&gt;MDelayCountBase;
ObjectToMove-&gtXformToWorld[2][3] += ObjectToMove-&gtMove.MoveZ; ObjectToMove-&gt;XformToWorld[2][3] += ObjectToMove-&gt;Move.MoveZ;
if (ObjectToMove-&gtXformToWorld[2][3]&gtObjectToMove-&gtMove.MaxZ) if (ObjectToMove-&gt;XformToWorld[2][3]&gt;ObjectToMove-&gt;Move.MaxZ)
ObjectToMove-&gtMove.MoveZ = 0; /* stop if close enough */ ObjectToMove-&gt;Move.MoveZ = 0; /* stop if close enough */
ObjectToMove-&gtRecalcXform = 1; ObjectToMove-&gt;RecalcXform = 1;
} }
} }
</PRE> </PRE>
@ -81,19 +81,19 @@ void RotateAndMovePObject(PObject * ObjectToMove)
void DrawPObject(PObject * ObjectToXform) void DrawPObject(PObject * ObjectToXform)
{ {
int i, j, NumFaces = ObjectToXform-&gtNumFaces, NumVertices; int i, j, NumFaces = ObjectToXform-&gt;NumFaces, NumVertices;
int * VertNumsPtr; int * VertNumsPtr;
Face * FacePtr = ObjectToXform-&gtFaceList; Face * FacePtr = ObjectToXform-&gt;FaceList;
Point * ScreenPoints = ObjectToXform-&gtScreenVertexList; Point * ScreenPoints = ObjectToXform-&gt;ScreenVertexList;
long v1, v2, w1, w2; long v1, v2, w1, w2;
Point Vertices[MAX_POLY_LENGTH]; Point Vertices[MAX_POLY_LENGTH];
PointListHeader Polygon; PointListHeader Polygon;
/* Draw each visible face (polygon) of the object in turn */ /* Draw each visible face (polygon) of the object in turn */
for (i=0; i&ltNumFaces; i++, FacePtr++) { for (i=0; i&lt;NumFaces; i++, FacePtr++) {
NumVertices = FacePtr-&gtNumVerts; NumVertices = FacePtr-&gt;NumVerts;
/* Copy over the face's vertices from the vertex list */ /* Copy over the face's vertices from the vertex list */
for (j=0, VertNumsPtr=FacePtr-&gtVertNums; j&ltNumVertices; j++) for (j=0, VertNumsPtr=FacePtr-&gt;VertNums; j&lt;NumVertices; j++)
Vertices[j] = ScreenPoints[*VertNumsPtr++]; Vertices[j] = ScreenPoints[*VertNumsPtr++];
/* Draw only if outside face showing (if the normal to the /* Draw only if outside face showing (if the normal to the
polygon points toward viewer; that is, has a positive Z component) */ polygon points toward viewer; that is, has a positive Z component) */
@ -101,40 +101,40 @@ void DrawPObject(PObject * ObjectToXform)
w1 = Vertices[NumVertices-1].X - Vertices[0].X; w1 = Vertices[NumVertices-1].X - Vertices[0].X;
v2 = Vertices[1].Y - Vertices[0].Y; v2 = Vertices[1].Y - Vertices[0].Y;
w2 = Vertices[NumVertices-1].Y - Vertices[0].Y; w2 = Vertices[NumVertices-1].Y - Vertices[0].Y;
if ((v1*w2 - v2*w1) &gt 0) { if ((v1*w2 - v2*w1) &gt; 0) {
/* It is facing the screen, so draw */ /* It is facing the screen, so draw */
/* Appropriately adjust the extent of the rectangle used to /* Appropriately adjust the extent of the rectangle used to
erase this object later */ erase this object later */
for (j=0; j&ltNumVertices; j++) { for (j=0; j&lt;NumVertices; j++) {
if (Vertices[j].X &gt if (Vertices[j].X &gt;
ObjectToXform-&gtEraseRect[NonDisplayedPage].Right) ObjectToXform-&gt;EraseRect[NonDisplayedPage].Right)
if (Vertices[j].X &lt SCREEN_WIDTH) if (Vertices[j].X &lt; SCREEN_WIDTH)
ObjectToXform-&gtEraseRect[NonDisplayedPage].Right = ObjectToXform-&gt;EraseRect[NonDisplayedPage].Right =
Vertices[j].X; Vertices[j].X;
else ObjectToXform-&gtEraseRect[NonDisplayedPage].Right = else ObjectToXform-&gt;EraseRect[NonDisplayedPage].Right =
SCREEN_WIDTH; SCREEN_WIDTH;
if (Vertices[j].Y &gt if (Vertices[j].Y &gt;
ObjectToXform-&gtEraseRect[NonDisplayedPage].Bottom) ObjectToXform-&gt;EraseRect[NonDisplayedPage].Bottom)
if (Vertices[j].Y &lt SCREEN_HEIGHT) if (Vertices[j].Y &lt; SCREEN_HEIGHT)
ObjectToXform-&gtEraseRect[NonDisplayedPage].Bottom = ObjectToXform-&gt;EraseRect[NonDisplayedPage].Bottom =
Vertices[j].Y; Vertices[j].Y;
else ObjectToXform-&gtEraseRect[NonDisplayedPage].Bottom= else ObjectToXform-&gt;EraseRect[NonDisplayedPage].Bottom=
SCREEN_HEIGHT; SCREEN_HEIGHT;
if (Vertices[j].X &lt if (Vertices[j].X &lt;
ObjectToXform-&gtEraseRect[NonDisplayedPage].Left) ObjectToXform-&gt;EraseRect[NonDisplayedPage].Left)
if (Vertices[j].X &gt 0) if (Vertices[j].X &gt; 0)
ObjectToXform-&gtEraseRect[NonDisplayedPage].Left = ObjectToXform-&gt;EraseRect[NonDisplayedPage].Left =
Vertices[j].X; Vertices[j].X;
else ObjectToXform-&gtEraseRect[NonDisplayedPage].Left=0; else ObjectToXform-&gt;EraseRect[NonDisplayedPage].Left=0;
if (Vertices[j].Y &lt if (Vertices[j].Y &lt;
ObjectToXform-&gtEraseRect[NonDisplayedPage].Top) ObjectToXform-&gt;EraseRect[NonDisplayedPage].Top)
if (Vertices[j].Y &gt 0) if (Vertices[j].Y &gt; 0)
ObjectToXform-&gtEraseRect[NonDisplayedPage].Top = ObjectToXform-&gt;EraseRect[NonDisplayedPage].Top =
Vertices[j].Y; Vertices[j].Y;
else ObjectToXform-&gtEraseRect[NonDisplayedPage].Top=0; else ObjectToXform-&gt;EraseRect[NonDisplayedPage].Top=0;
} }
/* Draw the polygon */ /* Draw the polygon */
DRAW_POLYGON(Vertices, NumVertices, FacePtr-&gtColor, 0, 0); DRAW_POLYGON(Vertices, NumVertices, FacePtr-&gt;Color, 0, 0);
} }
} }
} }

View file

@ -41,8 +41,8 @@
<PRE> <PRE>
/* Initializes the cubes and adds them to the object list. */ /* Initializes the cubes and adds them to the object list. */
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
#define ROT_6 (M_PI / 30.0) /* rotate 6 degrees at a time */ #define ROT_6 (M_PI / 30.0) /* rotate 6 degrees at a time */
@ -99,64 +99,64 @@ void InitializeCubes()
int i, j, k; int i, j, k;
PObject *WorkingCube; PObject *WorkingCube;
for (i=0; i&ltNUM_CUBES; i++) { for (i=0; i&lt;NUM_CUBES; i++) {
if ((WorkingCube = malloc(sizeof(PObject))) == NULL) { if ((WorkingCube = malloc(sizeof(PObject))) == NULL) {
printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); } printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); }
WorkingCube-&gtDrawFunc = DrawPObject; WorkingCube-&gt;DrawFunc = DrawPObject;
WorkingCube-&gtRecalcFunc = XformAndProjectPObject; WorkingCube-&gt;RecalcFunc = XformAndProjectPObject;
WorkingCube-&gtMoveFunc = RotateAndMovePObject; WorkingCube-&gt;MoveFunc = RotateAndMovePObject;
WorkingCube-&gtRecalcXform = 1; WorkingCube-&gt;RecalcXform = 1;
for (k=0; k&lt2; k++) { for (k=0; k&lt;2; k++) {
WorkingCube-&gtEraseRect[k].Left = WorkingCube-&gt;EraseRect[k].Left =
WorkingCube-&gtEraseRect[k].Top = 0x7FFF; WorkingCube-&gt;EraseRect[k].Top = 0x7FFF;
WorkingCube-&gtEraseRect[k].Right = 0; WorkingCube-&gt;EraseRect[k].Right = 0;
WorkingCube-&gtEraseRect[k].Bottom = 0; WorkingCube-&gt;EraseRect[k].Bottom = 0;
} }
WorkingCube-&gtRDelayCount = InitRDelayCounts[i]; WorkingCube-&gt;RDelayCount = InitRDelayCounts[i];
WorkingCube-&gtRDelayCountBase = BaseRDelayCounts[i]; WorkingCube-&gt;RDelayCountBase = BaseRDelayCounts[i];
WorkingCube-&gtMDelayCount = InitMDelayCounts[i]; WorkingCube-&gt;MDelayCount = InitMDelayCounts[i];
WorkingCube-&gtMDelayCountBase = BaseMDelayCounts[i]; WorkingCube-&gt;MDelayCountBase = BaseMDelayCounts[i];
/* Set the object-&gtworld xform to none */ /* Set the object-&gt;world xform to none */
for (j=0; j&lt3; j++) for (j=0; j&lt;3; j++)
for (k=0; k&lt4; k++) for (k=0; k&lt;4; k++)
WorkingCube-&gtXformToWorld[j][k] = INT_TO_FIXED(0); WorkingCube-&gt;XformToWorld[j][k] = INT_TO_FIXED(0);
WorkingCube-&gtXformToWorld[0][0] = WorkingCube-&gt;XformToWorld[0][0] =
WorkingCube-&gtXformToWorld[1][1] = WorkingCube-&gt;XformToWorld[1][1] =
WorkingCube-&gtXformToWorld[2][2] = WorkingCube-&gt;XformToWorld[2][2] =
WorkingCube-&gtXformToWorld[3][3] = INT_TO_FIXED(1); WorkingCube-&gt;XformToWorld[3][3] = INT_TO_FIXED(1);
/* Set the initial location */ /* Set the initial location */
for (j=0; j&lt3; j++) WorkingCube-&gtXformToWorld[j][3] = for (j=0; j&lt;3; j++) WorkingCube-&gt;XformToWorld[j][3] =
INT_TO_FIXED(CubeStartCoords[i][j]); INT_TO_FIXED(CubeStartCoords[i][j]);
WorkingCube-&gtNumVerts = NUM_CUBE_VERTS; WorkingCube-&gt;NumVerts = NUM_CUBE_VERTS;
WorkingCube-&gtVertexList = CubeVerts; WorkingCube-&gt;VertexList = CubeVerts;
WorkingCube-&gtNumFaces = NUM_CUBE_FACES; WorkingCube-&gt;NumFaces = NUM_CUBE_FACES;
WorkingCube-&gtRotate = InitialRotate[i]; WorkingCube-&gt;Rotate = InitialRotate[i];
WorkingCube-&gtMove.MoveX = INT_TO_FIXED(InitialMove[i].MoveX); WorkingCube-&gt;Move.MoveX = INT_TO_FIXED(InitialMove[i].MoveX);
WorkingCube-&gtMove.MoveY = INT_TO_FIXED(InitialMove[i].MoveY); WorkingCube-&gt;Move.MoveY = INT_TO_FIXED(InitialMove[i].MoveY);
WorkingCube-&gtMove.MoveZ = INT_TO_FIXED(InitialMove[i].MoveZ); WorkingCube-&gt;Move.MoveZ = INT_TO_FIXED(InitialMove[i].MoveZ);
WorkingCube-&gtMove.MinX = INT_TO_FIXED(InitialMove[i].MinX); WorkingCube-&gt;Move.MinX = INT_TO_FIXED(InitialMove[i].MinX);
WorkingCube-&gtMove.MinY = INT_TO_FIXED(InitialMove[i].MinY); WorkingCube-&gt;Move.MinY = INT_TO_FIXED(InitialMove[i].MinY);
WorkingCube-&gtMove.MinZ = INT_TO_FIXED(InitialMove[i].MinZ); WorkingCube-&gt;Move.MinZ = INT_TO_FIXED(InitialMove[i].MinZ);
WorkingCube-&gtMove.MaxX = INT_TO_FIXED(InitialMove[i].MaxX); WorkingCube-&gt;Move.MaxX = INT_TO_FIXED(InitialMove[i].MaxX);
WorkingCube-&gtMove.MaxY = INT_TO_FIXED(InitialMove[i].MaxY); WorkingCube-&gt;Move.MaxY = INT_TO_FIXED(InitialMove[i].MaxY);
WorkingCube-&gtMove.MaxZ = INT_TO_FIXED(InitialMove[i].MaxZ); WorkingCube-&gt;Move.MaxZ = INT_TO_FIXED(InitialMove[i].MaxZ);
if ((WorkingCube-&gtXformedVertexList = if ((WorkingCube-&gt;XformedVertexList =
malloc(NUM_CUBE_VERTS*sizeof(Point3))) == NULL) { malloc(NUM_CUBE_VERTS*sizeof(Point3))) == NULL) {
printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); } printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); }
if ((WorkingCube-&gtProjectedVertexList = if ((WorkingCube-&gt;ProjectedVertexList =
malloc(NUM_CUBE_VERTS*sizeof(Point3))) == NULL) { malloc(NUM_CUBE_VERTS*sizeof(Point3))) == NULL) {
printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); } printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); }
if ((WorkingCube-&gtScreenVertexList = if ((WorkingCube-&gt;ScreenVertexList =
malloc(NUM_CUBE_VERTS*sizeof(Point))) == NULL) { malloc(NUM_CUBE_VERTS*sizeof(Point))) == NULL) {
printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); } printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); }
if ((WorkingCube-&gtFaceList = if ((WorkingCube-&gt;FaceList =
malloc(NUM_CUBE_FACES*sizeof(Face))) == NULL) { malloc(NUM_CUBE_FACES*sizeof(Face))) == NULL) {
printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); } printf(&ldquo;Couldn't get memory\n&rdquo;); exit(1); }
/* Initialize the faces */ /* Initialize the faces */
for (j=0; j&ltNUM_CUBE_FACES; j++) { for (j=0; j&lt;NUM_CUBE_FACES; j++) {
WorkingCube-&gtFaceList[j].VertNums = VertNumList[j]; WorkingCube-&gt;FaceList[j].VertNums = VertNumList[j];
WorkingCube-&gtFaceList[j].NumVerts = VertsInFace[j]; WorkingCube-&gt;FaceList[j].NumVerts = VertsInFace[j];
WorkingCube-&gtFaceList[j].Color = Colors[i][j]; WorkingCube-&gt;FaceList[j].Color = Colors[i][j];
} }
ObjectList[NumObjects++] = (Object *)WorkingCube; ObjectList[NumObjects++] = (Object *)WorkingCube;
} }

View file

@ -52,7 +52,7 @@
public _FixedMul,_FixedDiv public _FixedMul,_FixedDiv
; Multiplies two fixed-point values together. ; Multiplies two fixed-point values together.
FMparms struc FMparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
M1 dd ? M1 dd ?
M2 dd ? M2 dd ?
FMparms ends FMparms ends
@ -70,7 +70,7 @@ _FixedMul proc near
_FixedMul endp _FixedMul endp
; Divides one fixed-point value by another. ; Divides one fixed-point value by another.
FDparms struc FDparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
Dividend dd ? Dividend dd ?
Divisor dd ? Divisor dd ?
FDparms ends FDparms ends
@ -137,8 +137,8 @@ _FixedDiv endp
Color with all vertices offset by (X,Y) */ Color with all vertices offset by (X,Y) */
#define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \ #define DRAW_POLYGON(PointList,NumPoints,Color,X,Y) \
Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \ Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \
FillConvexPolygon(&ampPolygon, Color, X, Y); FillConvexPolygon(&amp;Polygon, Color, X, Y);
#define INT_TO_FIXED(x) (((long)(int)x) &lt&lt 16) #define INT_TO_FIXED(x) (((long)(int)x) &lt;&lt; 16)
#define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5)) #define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5))
typedef long Fixedpoint; typedef long Fixedpoint;
@ -181,8 +181,8 @@ typedef struct {
BASE_OBJECT BASE_OBJECT
int RDelayCount, RDelayCountBase; /* controls rotation speed */ int RDelayCount, RDelayCountBase; /* controls rotation speed */
int MDelayCount, MDelayCountBase; /* controls movement speed */ int MDelayCount, MDelayCountBase; /* controls movement speed */
Xform XformToWorld; /* transform from object-&gtworld space */ Xform XformToWorld; /* transform from object-&gt;world space */
Xform XformToView; /* transform from object-&gtview space */ Xform XformToView; /* transform from object-&gt;view space */
RotateControl Rotate; /* controls rotation change over time */ RotateControl Rotate; /* controls rotation change over time */
MoveControl Move; /* controls object movement over time */ MoveControl Move; /* controls object movement over time */
int NumVerts; /* # vertices in VertexList */ int NumVerts; /* # vertices in VertexList */

View file

@ -54,7 +54,7 @@ ALIGNMENT equ 2
; Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2); ; Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2);
; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor); ; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
FMparms struc FMparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
M1 dd ? M1 dd ?
M2 dd ? M2 dd ?
FMparms ends FMparms ends
@ -78,7 +78,7 @@ endif ;ROUNDING-ON
; C near-callable as: ; C near-callable as:
; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor); ; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
FDparms struc FDparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
Dividend dd ? Dividend dd ?
Divisor dd ? Divisor dd ?
FDparms ends FDparms ends
@ -140,8 +140,8 @@ CosTable label dword
include costable.inc include costable.inc
SCparms struc SCparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
Angle dw ? ;angle to calculate sine &amp cosine for Angle dw ? ;angle to calculate sine &amp; cosine for
Cos dw ? ;pointer to cos destination Cos dw ? ;pointer to cos destination
Sin dw ? ;pointer to sin destination Sin dw ? ;pointer to sin destination
SCparms ends SCparms ends
@ -242,7 +242,7 @@ ret
; WorkingXform[i][3]; /* no need to multiply by W = 1 */ ; WorkingXform[i][3]; /* no need to multiply by W = 1 */
XVparms struc XVparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
WorkingXform dw ? ;pointer to transform matrix WorkingXform dw ? ;pointer to transform matrix
SourceVec dw ? ;pointer to source vector SourceVec dw ? ;pointer to source vector
DestVec dw ? ;pointer to destination vector DestVec dw ? ;pointer to destination vector
@ -328,7 +328,7 @@ ret
; } ; }
CXparms struc CXparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
SourceXform1 dw ? ;pointer to first source xform matrix SourceXform1 dw ? ;pointer to first source xform matrix
SourceXform2 dw ? ;pointer to second source xform matrix SourceXform2 dw ? ;pointer to second source xform matrix
DestXform dw ? ;pointer to destination xform matrix DestXform dw ? ;pointer to destination xform matrix
@ -380,7 +380,7 @@ endif ;ROUNDING-ON
add ecx,eax ;running total add ecx,eax ;running total
mov[di+coff+roff],ecx ;save the result in dest matrix mov[di+coff+roff],ecx ;save the result in dest matrix
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
ENDM ENDM
;now do the fourth column, assuming ;now do the fourth column, assuming
; 1 as the bottom entry, causing ; 1 as the bottom entry, causing
@ -415,9 +415,9 @@ addecx,eax;running total
addecx,[si+roff+12];add in translation addecx,[si+roff+12];add in translation
mov[di+coff+roff],ecx;save the result in dest matrix mov[di+coff+roff],ecx;save the result in dest matrix
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
roff=roff+16 ;point to next col in xform2 &amp dest roff=roff+16 ;point to next col in xform2 &amp; dest
ENDM ENDM
popdi;restore register variables popdi;restore register variables

View file

@ -48,11 +48,11 @@
terminate searches */ terminate searches */
void InitializeObjectList() void InitializeObjectList()
{ {
ObjectListStart.NextObject = &ampObjectListEnd; ObjectListStart.NextObject = &amp;ObjectListEnd;
ObjectListStart.PreviousObject = NULL; ObjectListStart.PreviousObject = NULL;
ObjectListStart.CenterInView.Z = INT-TO-FIXED(-32768); ObjectListStart.CenterInView.Z = INT-TO-FIXED(-32768);
ObjectListEnd.NextObject = NULL; ObjectListEnd.NextObject = NULL;
ObjectListEnd.PreviousObject = &ampObjectListStart; ObjectListEnd.PreviousObject = &amp;ObjectListStart;
ObjectListEnd.CenterInView.Z = 0x7FFFFFFFL; ObjectListEnd.CenterInView.Z = 0x7FFFFFFFL;
NumObjects = 0; NumObjects = 0;
} }

View file

@ -65,7 +65,7 @@ ALIGNMENT equ 2
; C near-callable as: ; C near-callable as:
; Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2); ; Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2);
FMparms struc FMparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
M1 dd ? M1 dd ?
M2 dd ? M2 dd ?
FMparms ends FMparms ends
@ -161,7 +161,7 @@ _FixedMul endp
; C near-callable as: ; C near-callable as:
; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor); ; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
FDparms struc FDparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
Dividend dd? Dividend dd?
Divisor dd? Divisor dd?
FDparms ends FDparms ends
@ -290,8 +290,8 @@ CosTable label dword
include costable.inc include costable.inc
SCparms struc SCparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
Angle dw ? ;angle to calculate sine &amp cosine for Angle dw ? ;angle to calculate sine &amp; cosine for
Cos dw ? ;pointer to cos destination Cos dw ? ;pointer to cos destination
Sin dw ? ;pointer to sin destination Sin dw ? ;pointer to sin destination
SCparms ends SCparms ends
@ -486,7 +486,7 @@ _CosSin endp
; WorkingXform[i][3]; /* no need to multiply by W = 1 */ ; WorkingXform[i][3]; /* no need to multiply by W = 1 */
XVparms struc XVparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
WorkingXform dw ? ;pointer to transform matrix WorkingXform dw ? ;pointer to transform matrix
SourceVec dw ? ;pointer to source vector SourceVec dw ? ;pointer to source vector
DestVec dw ? ;pointer to destination vector DestVec dw ? ;pointer to destination vector
@ -502,40 +502,40 @@ FIXED-MUL MACRO M1,M2
;figure out signs, so we can use ;figure out signs, so we can use
; unsigned multiplies ; unsigned multiplies
sub cx,cx ;assume both operands positive sub cx,cx ;assume both operands positive
mov bx,word ptr [&ampM1&amp+2] mov bx,word ptr [&amp;M1&amp;+2]
and bx,bx ;first operand negative? and bx,bx ;first operand negative?
jns CheckSecondOperand ;no jns CheckSecondOperand ;no
neg bx ;yes, so negate first operand neg bx ;yes, so negate first operand
neg word ptr [&ampM1&amp] neg word ptr [&amp;M1&amp;]
sbb bx,0 sbb bx,0
mov word ptr [&ampM1&amp+2],bx mov word ptr [&amp;M1&amp;+2],bx
inc cx ;mark that first operand is negative inc cx ;mark that first operand is negative
CheckSecondOperand: CheckSecondOperand:
mov bx,word ptr [&ampM2&amp+2] mov bx,word ptr [&amp;M2&amp;+2]
and bx,bx ;second operand negative? and bx,bx ;second operand negative?
jns SaveSignStatus ;no jns SaveSignStatus ;no
neg bx ;yes, so negate second operand neg bx ;yes, so negate second operand
neg word ptr [&ampM2&amp] neg word ptr [&amp;M2&amp;]
sbb bx,0 sbb bx,0
mov word ptr [&ampM2&amp+2],bx mov word ptr [&amp;M2&amp;+2],bx
xor cx,1 ;mark that second operand is negative xor cx,1 ;mark that second operand is negative
SaveSignStatus: SaveSignStatus:
push cx ;remember sign of result; 1 if result push cx ;remember sign of result; 1 if result
; negative, 0 if result nonnegative ; negative, 0 if result nonnegative
mov ax,word ptr [&ampM1&amp+2] ;high word times high word mov ax,word ptr [&amp;M1&amp;+2] ;high word times high word
mul word ptr [&ampM2&amp+2] mul word ptr [&amp;M2&amp;+2]
mov cx,ax ; mov cx,ax ;
;assume no overflow into DX ;assume no overflow into DX
mov ax,word ptr [&ampM1&amp+2] ;high word times low word mov ax,word ptr [&amp;M1&amp;+2] ;high word times low word
mul word ptr [&ampM2&amp] mul word ptr [&amp;M2&amp;]
mov bx,ax mov bx,ax
add cx,dx add cx,dx
mov ax,word ptr [&ampM1&amp] ;low word times high word mov ax,word ptr [&amp;M1&amp;] ;low word times high word
mul word ptr [&ampM2&amp+2] mul word ptr [&amp;M2&amp;+2]
add bx,ax add bx,ax
adc cx,dx adc cx,dx
mov ax,word ptr [&ampM1&amp] ;low word times low word mov ax,word ptr [&amp;M1&amp;] ;low word times low word
mul word ptr [&ampM2&amp] mul word ptr [&amp;M2&amp;]
if MUL-ROUNDING-ON if MUL-ROUNDING-ON
add ax,8000h ;round by adding 2^(-17) add ax,8000h ;round by adding 2^(-17)
adc bx,dx adc bx,dx
@ -692,7 +692,7 @@ _XformVecendp
; } ; }
CXparms struc CXparms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
SourceXform1 dw ? ;pointer to first source xform matrix SourceXform1 dw ? ;pointer to first source xform matrix
SourceXform2 dw ? ;pointer to second source xform matrix SourceXform2 dw ? ;pointer to second source xform matrix
DestXform dw ? ;pointer to destination xform matrix DestXform dw ? ;pointer to destination xform matrix
@ -746,7 +746,7 @@ endif ;MUL-ROUNDING-ON
add ecx,eax ;running total add ecx,eax ;running total
mov [di+coff+roff],ecx ;save the result in dest matrix mov [di+coff+roff],ecx ;save the result in dest matrix
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
ENDM ENDM
;now do the fourth column, assuming ;now do the fourth column, assuming
; 1 as the bottom entry, causing ; 1 as the bottom entry, causing
@ -781,9 +781,9 @@ endif ;MUL-ROUNDING-ON
add ecx,[si+roff+12] ;add in translation add ecx,[si+roff+12] ;add in translation
mov [di+coff+roff],ecx ;save the result in dest matrix mov [di+coff+roff],ecx ;save the result in dest matrix
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
roff=roff+16 ;point to next col in xform2 &amp dest roff=roff+16 ;point to next col in xform2 &amp; dest
ENDM ENDM
else ;!USE386 else ;!USE386
@ -837,7 +837,7 @@ addsp,8;clear parameters from stack
pop bx ;restore DestXForm pointer pop bx ;restore DestXForm pointer
mov [bx+coff+roff],cx ;save the result in dest matrix mov [bx+coff+roff],cx ;save the result in dest matrix
mov [bx+coff+roff+2],bp mov [bx+coff+roff+2],bp
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
ENDM ENDM
;now do the fourth column, assuming ;now do the fourth column, assuming
; 1 as the bottom entry, causing ; 1 as the bottom entry, causing
@ -883,9 +883,9 @@ coff=coff+4 ;point to next col in xform2 &amp dest
pop bx ;restore DestXForm pointer pop bx ;restore DestXForm pointer
mov [bx+coff+roff],cx ;save the result in dest matrix mov [bx+coff+roff],cx ;save the result in dest matrix
mov [bx+coff+roff+2],bp mov [bx+coff+roff+2],bp
coff=coff+4 ;point to next col in xform2 &amp dest coff=coff+4 ;point to next col in xform2 &amp; dest
roff=roff+16 ;point to next col in xform2 &amp dest roff=roff+16 ;point to next col in xform2 &amp; dest
ENDM ENDM
pop bp ;restore stack frame pointer pop bp ;restore stack frame pointer

View file

@ -66,8 +66,8 @@ void DrawPObject(PObject * ObjectToXform)
must be the first and second entries in the polgyon's vertex list. must be the first and second entries in the polgyon's vertex list.
Note that the second point is also an active polygon vertex */ Note that the second point is also an active polygon vertex */
VertNumsPtr = FacePtr-&gt;VertNums; VertNumsPtr = FacePtr-&gt;VertNums;
NormalEndpoint = &ampObjectToXform-&gt;XformedVertexList[*VertNumsPtr++]; NormalEndpoint = &amp;ObjectToXform-&gt;XformedVertexList[*VertNumsPtr++];
NormalStartpoint = &ampObjectToXform-&gt;XformedVertexList[*VertNumsPtr]; NormalStartpoint = &amp;ObjectToXform-&gt;XformedVertexList[*VertNumsPtr];
/* Copy over the face's vertices from the vertex list */ /* Copy over the face's vertices from the vertex list */
NumVertices = FacePtr-&gt;NumVerts; NumVertices = FacePtr-&gt;NumVerts;
for (j=0; j&lt;NumVertices; j++) for (j=0; j&lt;NumVertices; j++)
@ -118,14 +118,14 @@ void DrawPObject(PObject * ObjectToXform)
} else { } else {
/* Handle shading */ /* Handle shading */
/* Do ambient shading, if enabled */ /* Do ambient shading, if enabled */
if (AmbientOn &amp&amp (FacePtr-&gt;ShadingType &amp AMBIENT-SHADING)) { if (AmbientOn &amp;&amp; (FacePtr-&gt;ShadingType &amp; AMBIENT-SHADING)) {
/* Use the ambient shading component */ /* Use the ambient shading component */
IntensityTemp = AmbientIntensity; IntensityTemp = AmbientIntensity;
} else { } else {
SET-INTENSITY(IntensityTemp, 0, 0, 0); SET-INTENSITY(IntensityTemp, 0, 0, 0);
} }
/* Do diffuse shading, if enabled */ /* Do diffuse shading, if enabled */
if (FacePtr-&gt;ShadingType &amp DIFFUSE-SHADING) { if (FacePtr-&gt;ShadingType &amp; DIFFUSE-SHADING) {
/* Calculate the unit normal for this polygon, for use in dot /* Calculate the unit normal for this polygon, for use in dot
products */ products */
UnitNormal.X = NormalEndpoint-&gt;X - NormalStartpoint-&gt;X; UnitNormal.X = NormalEndpoint-&gt;X - NormalStartpoint-&gt;X;
@ -155,12 +155,12 @@ void DrawPObject(PObject * ObjectToXform)
} }
/* Convert the drawing color to the desired fraction of the /* Convert the drawing color to the desired fraction of the
brightest possible color */ brightest possible color */
IntensityAdjustColor(&ampColorTemp, &ampFacePtr-&gt;FullColor, IntensityAdjustColor(&amp;ColorTemp, &amp;FacePtr-&gt;FullColor,
&ampIntensityTemp); &amp;IntensityTemp);
/* Draw with the cumulative shading, converting from the general /* Draw with the cumulative shading, converting from the general
color representation to the best-match color index */ color representation to the best-match color index */
DRAW-POLYGON(Vertices, NumVertices, DRAW-POLYGON(Vertices, NumVertices,
ModelColorToColorIndex(&ampColorTemp), 0, 0); ModelColorToColorIndex(&amp;ColorTemp), 0, 0);
} }
} }
} }

View file

@ -70,7 +70,7 @@
even intensity steps on the screen. even intensity steps on the screen.
*/ */
#include &ltdos.h&gt #include &lt;dos.h&gt;
#include "polygon.h" #include "polygon.h"
static unsigned char Gamma4Levels[] = { 0, 39, 53, 63 }; static unsigned char Gamma4Levels[] = { 0, 39, 53, 63 };
@ -89,10 +89,10 @@
union REGS regset; union REGS regset;
struct SREGS sregset; struct SREGS sregset;
for (Red=0; Red&lt4; Red++) { for (Red=0; Red&lt;4; Red++) {
for (Green=0; Green&lt4; Green++) { for (Green=0; Green&lt;4; Green++) {
for (Blue=0; Blue&lt4; Blue++) { for (Blue=0; Blue&lt;4; Blue++) {
Index = (Red&lt&lt4)+(Green&lt&lt2)+Blue; Index = (Red&lt;&lt;4)+(Green&lt;&lt;2)+Blue;
PaletteBlock[Index][0] = Gamma4Levels[Red]; PaletteBlock[Index][0] = Gamma4Levels[Red];
PaletteBlock[Index][1] = Gamma4Levels[Green]; PaletteBlock[Index][1] = Gamma4Levels[Green];
PaletteBlock[Index][2] = Gamma4Levels[Blue]; PaletteBlock[Index][2] = Gamma4Levels[Blue];
@ -100,19 +100,19 @@
} }
} }
for (Red=0; Red&lt64; Red++) { for (Red=0; Red&lt;64; Red++) {
PaletteBlock[64+Red][0] = Gamma64Levels[Red]; PaletteBlock[64+Red][0] = Gamma64Levels[Red];
PaletteBlock[64+Red][1] = 0; PaletteBlock[64+Red][1] = 0;
PaletteBlock[64+Red][2] = 0; PaletteBlock[64+Red][2] = 0;
} }
for (Green=0; Green&lt64; Green++) { for (Green=0; Green&lt;64; Green++) {
PaletteBlock[128+Green][0] = 0; PaletteBlock[128+Green][0] = 0;
PaletteBlock[128+Green][1] = Gamma64Levels[Green]; PaletteBlock[128+Green][1] = Gamma64Levels[Green];
PaletteBlock[128+Green][2] = 0; PaletteBlock[128+Green][2] = 0;
} }
for (Blue=0; Blue&lt64; Blue++) { for (Blue=0; Blue&lt;64; Blue++) {
PaletteBlock[192+Blue][0] = 0; PaletteBlock[192+Blue][0] = 0;
PaletteBlock[192+Blue][1] = 0; PaletteBlock[192+Blue][1] = 0;
PaletteBlock[192+Blue][2] = Gamma64Levels[Blue]; PaletteBlock[192+Blue][2] = Gamma64Levels[Blue];
@ -125,7 +125,7 @@
regset.x.dx = (unsigned int)PaletteBlock; /* offset of array from which regset.x.dx = (unsigned int)PaletteBlock; /* offset of array from which
to load RGB settings */ to load RGB settings */
sregset.es = DS; /* segment of array from which to load settings */ sregset.es = DS; /* segment of array from which to load settings */
int86x(0x10, &ampregset, &ampregset, &ampsregset); /* load the palette block */ int86x(0x10, &amp;regset, &amp;regset, &amp;sregset); /* load the palette block */
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

View file

@ -44,22 +44,22 @@
special-cased, and everything else is handled by a 2-2-2 model. */ special-cased, and everything else is handled by a 2-2-2 model. */
int ModelColorToColorIndex(ModelColor * Color) int ModelColorToColorIndex(ModelColor * Color)
{ {
if (Color-&gtRed == 0) { if (Color-&gt;Red == 0) {
if (Color-&gtGreen == 0) { if (Color-&gt;Green == 0) {
/* Pure blue */ /* Pure blue */
return(192+(Color-&gtBlue &gt&gt 2)); return(192+(Color-&gt;Blue &gt;&gt; 2));
} else if (Color-&gtBlue == 0) { } else if (Color-&gt;Blue == 0) {
/* Pure green */ /* Pure green */
return(128+(Color-&gtGreen &gt&gt 2)); return(128+(Color-&gt;Green &gt;&gt; 2));
} }
} else if ((Color-&gtGreen == 0) &amp&amp (Color-&gtBlue == 0)) { } else if ((Color-&gt;Green == 0) &amp;&amp; (Color-&gt;Blue == 0)) {
/* Pure red */ /* Pure red */
return(64+(Color-&gtRed &gt&gt 2)); return(64+(Color-&gt;Red &gt;&gt; 2));
} }
/* Multi-color mix; look up the index with the two most significant bits /* Multi-color mix; look up the index with the two most significant bits
of each color component */ of each color component */
return(((Color-&gtRed &amp 0xC0) &gt&gt 2) | ((Color-&gtGreen &amp 0xC0) &gt&gt 4) | return(((Color-&gt;Red &amp; 0xC0) &gt;&gt; 2) | ((Color-&gt;Green &amp; 0xC0) &gt;&gt; 4) |
((Color-&gtBlue &amp 0xC0) &gt&gt 6)); ((Color-&gt;Blue &amp; 0xC0) &gt;&gt; 6));
} }
</PRE> </PRE>

View file

@ -50,7 +50,7 @@
; Demonstrates drawing solid text on the VGA, using the BitMan&rsquo;s write mode ; Demonstrates drawing solid text on the VGA, using the BitMan&rsquo;s write mode
; 3-based, one-pass technique. ; 3-based, one-pass technique.
CHAR_HEIGHT equ 8 ;# of scan lines per character (must be &lt256) CHAR_HEIGHT equ 8 ;# of scan lines per character (must be &lt;256)
SCREEN_HEIGHT equ 480 ;# of scan lines per screen SCREEN_HEIGHT equ 480 ;# of scan lines per screen
SCREEN_SEGMENT equ 0a000h ;where screen memory is SCREEN_SEGMENT equ 0a000h ;where screen memory is
FG_COLOR equ 14 ;text color FG_COLOR equ 14 ;text color
@ -64,14 +64,14 @@
.stack 200h .stack 200h
.data .data
Line dw ? ;current line # Line dw ? ;current line #
CharHeight dw ? ;# of scan lines in each character (must be &lt256) CharHeight dw ? ;# of scan lines in each character (must be &lt;256)
MaxLines dw ? ;max # of scan lines of text that will fit on screen MaxLines dw ? ;max # of scan lines of text that will fit on screen
LineWidthBytes dw ? ;offset from one scan line to the next LineWidthBytes dw ? ;offset from one scan line to the next
FontPtr dd ? ;pointer to font with which to draw FontPtr dd ? ;pointer to font with which to draw
SampleString label byte SampleString label byte
db &lsquo;ABCDEFGHIJKLMNOPQRSTUVWXYZ&rsquo; db &lsquo;ABCDEFGHIJKLMNOPQRSTUVWXYZ&rsquo;
db &lsquo;abcdefghijklmnopqrstuvwxyz&rsquo; db &lsquo;abcdefghijklmnopqrstuvwxyz&rsquo;
db &lsquo;0123456789!@#$%^&amp*(),&lt.&gt/?;:&rsquo;,0 db &lsquo;0123456789!@#$%^&amp;*(),&lt;.&gt;/?;:&rsquo;,0
.code .code
start: start:

View file

@ -50,10 +50,10 @@
texture mapped onto it */ texture mapped onto it */
#define DRAW_TEXTURED_POLYGON(PointList,NumPoints,TexVerts,TexMap) \ #define DRAW_TEXTURED_POLYGON(PointList,NumPoints,TexVerts,TexMap) \
Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \ Polygon.Length = NumPoints; Polygon.PointPtr = PointList; \
DrawTexturedPolygon(&ampPolygon, TexVerts, TexMap); DrawTexturedPolygon(&amp;Polygon, TexVerts, TexMap);
#define FIXED_TO_INT(FixedVal) ((int) (FixedVal &gt&gt 16)) #define FIXED_TO_INT(FixedVal) ((int) (FixedVal &gt;&gt; 16))
#define ROUND_FIXED_TO_INT(FixedVal) \ #define ROUND_FIXED_TO_INT(FixedVal) \
((int) ((FixedVal + DOUBLE_TO_FIXED(0.5)) &gt&gt 16)) ((int) ((FixedVal + DOUBLE_TO_FIXED(0.5)) &gt;&gt; 16))
/* Retrieves specified pixel from specified image bitmap of specified width. */ /* Retrieves specified pixel from specified image bitmap of specified width. */
#define GET_IMAGE_PIXEL(TexMapBits, TexMapWidth, X, Y) \ #define GET_IMAGE_PIXEL(TexMapBits, TexMapWidth, X, Y) \
TexMapBits[(Y * TexMapWidth) + X] TexMapBits[(Y * TexMapWidth) + X]
@ -97,10 +97,10 @@ extern void DrawTexturedPolygon(PointListHeader *, Point *, TextureMap *);
&ldquo;Convex&rdquo; means that every horizontal line drawn through the polygon at any &ldquo;Convex&rdquo; means that every horizontal line drawn through the polygon at any
point would cross exactly two active edges (neither horizontal lines nor point would cross exactly two active edges (neither horizontal lines nor
zero-length edges count as active edges; both are acceptable anywhere in zero-length edges count as active edges; both are acceptable anywhere in
the polygon), and that the right &amp left edges never cross. Nonconvex the polygon), and that the right &amp; left edges never cross. Nonconvex
polygons won&rsquo;t be drawn properly. Can&rsquo;t fail. */ polygons won&rsquo;t be drawn properly. Can&rsquo;t fail. */
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltmath.h&gt #include &lt;math.h&gt;
#include &ldquo;polygon.h&rdquo; #include &ldquo;polygon.h&rdquo;
/* Describes the current location and stepping, in both the source and /* Describes the current location and stepping, in both the source and
the destination, of an edge */ the destination, of an edge */
@ -143,13 +143,13 @@ void DrawTexturedPolygon(PointListHeader * Polygon, Point * TexVerts,
{ {
int MinY, MaxY, MinVert, i; int MinY, MaxY, MinVert, i;
EdgeScan LeftEdge, RightEdge; EdgeScan LeftEdge, RightEdge;
NumVerts = Polygon-&gtLength; NumVerts = Polygon-&gt;Length;
VertexPtr = Polygon-&gtPointPtr; VertexPtr = Polygon-&gt;PointPtr;
TexVertsPtr = TexVerts; TexVertsPtr = TexVerts;
TexMapBits = TexMap-&gtTexMapBits; TexMapBits = TexMap-&gt;TexMapBits;
TexMapWidth = TexMap-&gtTexMapWidth; TexMapWidth = TexMap-&gt;TexMapWidth;
/* Nothing to draw if less than 3 vertices */ /* Nothing to draw if less than 3 vertices */
if (NumVerts &lt 3) { if (NumVerts &lt; 3) {
return; return;
} }
/* Scan through the destination polygon vertices and find the top of the /* Scan through the destination polygon vertices and find the top of the
@ -158,18 +158,18 @@ void DrawTexturedPolygon(PointListHeader * Polygon, Point * TexVerts,
backface removal) */ backface removal) */
MinY = 32767; MinY = 32767;
MaxY = -32768; MaxY = -32768;
for (i=0; i&ltNumVerts; i++) { for (i=0; i&lt;NumVerts; i++) {
if (VertexPtr[i].Y &lt MinY) { if (VertexPtr[i].Y &lt; MinY) {
MinY = VertexPtr[i].Y; MinY = VertexPtr[i].Y;
MinVert = i; MinVert = i;
} }
if (VertexPtr[i].Y &gt MaxY) { if (VertexPtr[i].Y &gt; MaxY) {
MaxY = VertexPtr[i].Y; MaxY = VertexPtr[i].Y;
MaxVert = i; MaxVert = i;
} }
} }
/* Reject flat (0-pixel-high) polygons */ /* Reject flat (0-pixel-high) polygons */
if (MinY &gt= MaxY) { if (MinY &gt;= MaxY) {
return; return;
} }
/* The destination Y coordinate is not edge specific; it applies to /* The destination Y coordinate is not edge specific; it applies to
@ -180,9 +180,9 @@ void DrawTexturedPolygon(PointListHeader * Polygon, Point * TexVerts,
by one in Y, so calculate the corresponding destination X step for by one in Y, so calculate the corresponding destination X step for
each edge, and then the corresponding source image X and Y steps */ each edge, and then the corresponding source image X and Y steps */
LeftEdge.Direction = -1; /* set up left edge first */ LeftEdge.Direction = -1; /* set up left edge first */
SetUpEdge(&ampLeftEdge, MinVert); SetUpEdge(&amp;LeftEdge, MinVert);
RightEdge.Direction = 1; /* set up right edge */ RightEdge.Direction = 1; /* set up right edge */
SetUpEdge(&ampRightEdge, MinVert); SetUpEdge(&amp;RightEdge, MinVert);
/* Step down destination edges one scan line at a time. At each scan /* Step down destination edges one scan line at a time. At each scan
line, find the corresponding edge points in the source image. Scan line, find the corresponding edge points in the source image. Scan
between the edge points in the source, drawing the corresponding between the edge points in the source, drawing the corresponding
@ -192,20 +192,20 @@ void DrawTexturedPolygon(PointListHeader * Polygon, Point * TexVerts,
in clockwise order as seen from the viewpoint) */ in clockwise order as seen from the viewpoint) */
for (;;) { for (;;) {
/* Done if off bottom of clip rectangle */ /* Done if off bottom of clip rectangle */
if (DestY &gt= ClipMaxY) { if (DestY &gt;= ClipMaxY) {
return; return;
} }
/* Draw only if inside Y bounds of clip rectangle */ /* Draw only if inside Y bounds of clip rectangle */
if (DestY &gt= ClipMinY) { if (DestY &gt;= ClipMinY) {
/* Draw the scan line between the two current edges */ /* Draw the scan line between the two current edges */
ScanOutLine(&ampLeftEdge, &ampRightEdge); ScanOutLine(&amp;LeftEdge, &amp;RightEdge);
} }
/* Advance the source and destination polygon edges, ending if we&rsquo;ve /* Advance the source and destination polygon edges, ending if we&rsquo;ve
scanned all the way to the bottom of the polygon */ scanned all the way to the bottom of the polygon */
if (!StepEdge(&ampLeftEdge)) { if (!StepEdge(&amp;LeftEdge)) {
break; break;
} }
if (!StepEdge(&ampRightEdge)) { if (!StepEdge(&amp;RightEdge)) {
break; break;
} }
DestY++; DestY++;
@ -218,28 +218,28 @@ int StepEdge(EdgeScan * Edge)
{ {
/* Count off the scan line we stepped last time; if this edge is /* Count off the scan line we stepped last time; if this edge is
finished, try to start another one */ finished, try to start another one */
if (--Edge-&gtRemainingScans == 0) { if (--Edge-&gt;RemainingScans == 0) {
/* Set up the next edge; done if there is no next edge */ /* Set up the next edge; done if there is no next edge */
if (SetUpEdge(Edge, Edge-&gtCurrentEnd) == 0) { if (SetUpEdge(Edge, Edge-&gt;CurrentEnd) == 0) {
return(0); /* no more edges; done drawing polygon */ return(0); /* no more edges; done drawing polygon */
} }
return(1); /* all set to draw the new edge */ return(1); /* all set to draw the new edge */
} }
/* Step the current source edge */ /* Step the current source edge */
Edge-&gtSourceX += Edge-&gtSourceStepX; Edge-&gt;SourceX += Edge-&gt;SourceStepX;
Edge-&gtSourceY += Edge-&gtSourceStepY; Edge-&gt;SourceY += Edge-&gt;SourceStepY;
/* Step dest X with Bresenham-style variables, to get precise dest pixel /* Step dest X with Bresenham-style variables, to get precise dest pixel
placement and avoid gaps */ placement and avoid gaps */
Edge-&gtDestX += Edge-&gtDestXIntStep; /* whole pixel step */ Edge-&gt;DestX += Edge-&gt;DestXIntStep; /* whole pixel step */
/* Do error term stuff for fractional pixel X step handling */ /* Do error term stuff for fractional pixel X step handling */
if ((Edge-&gtDestXErrTerm += Edge-&gtDestXAdjUp) &gt 0) { if ((Edge-&gt;DestXErrTerm += Edge-&gt;DestXAdjUp) &gt; 0) {
Edge-&gtDestX += Edge-&gtDestXDirection; Edge-&gt;DestX += Edge-&gt;DestXDirection;
Edge-&gtDestXErrTerm -= Edge-&gtDestXAdjDown; Edge-&gt;DestXErrTerm -= Edge-&gt;DestXAdjDown;
} }
return(1); return(1);
} }
/* Sets up an edge to be scanned; the edge starts at StartVert and proceeds /* Sets up an edge to be scanned; the edge starts at StartVert and proceeds
in direction Edge-&gtDirection through the vertex list. Edge-&gtDirection must in direction Edge-&gt;Direction through the vertex list. Edge-&gt;Direction must
be set prior to call; -1 to scan a left edge (backward through the vertex be set prior to call; -1 to scan a left edge (backward through the vertex
list), 1 to scan a right edge (forward through the vertex list). list), 1 to scan a right edge (forward through the vertex list).
Automatically skips over 0-height edges. Returns 1 for success, or 0 if Automatically skips over 0-height edges. Returns 1 for success, or 0 if
@ -255,41 +255,41 @@ int SetUpEdge(EdgeScan * Edge, int StartVert)
} }
/* Advance to the next vertex, wrapping if we run off the start or end /* Advance to the next vertex, wrapping if we run off the start or end
of the vertex list */ of the vertex list */
NextVert = StartVert + Edge-&gtDirection; NextVert = StartVert + Edge-&gt;Direction;
if (NextVert &gt= NumVerts) { if (NextVert &gt;= NumVerts) {
NextVert = 0; NextVert = 0;
} else if (NextVert &lt 0) { } else if (NextVert &lt; 0) {
NextVert = NumVerts - 1; NextVert = NumVerts - 1;
} }
/* Calculate the variables for this edge and done if this is not a /* Calculate the variables for this edge and done if this is not a
zero-height edge */ zero-height edge */
if ((Edge-&gtRemainingScans = if ((Edge-&gt;RemainingScans =
VertexPtr[NextVert].Y - VertexPtr[StartVert].Y) != 0) { VertexPtr[NextVert].Y - VertexPtr[StartVert].Y) != 0) {
DestYHeight = INT_TO_FIXED(Edge-&gtRemainingScans); DestYHeight = INT_TO_FIXED(Edge-&gt;RemainingScans);
Edge-&gtCurrentEnd = NextVert; Edge-&gt;CurrentEnd = NextVert;
Edge-&gtSourceX = INT_TO_FIXED(TexVertsPtr[StartVert].X); Edge-&gt;SourceX = INT_TO_FIXED(TexVertsPtr[StartVert].X);
Edge-&gtSourceY = INT_TO_FIXED(TexVertsPtr[StartVert].Y); Edge-&gt;SourceY = INT_TO_FIXED(TexVertsPtr[StartVert].Y);
Edge-&gtSourceStepX = FixedDiv(INT_TO_FIXED(TexVertsPtr[NextVert].X) - Edge-&gt;SourceStepX = FixedDiv(INT_TO_FIXED(TexVertsPtr[NextVert].X) -
Edge-&gtSourceX, DestYHeight); Edge-&gt;SourceX, DestYHeight);
Edge-&gtSourceStepY = FixedDiv(INT_TO_FIXED(TexVertsPtr[NextVert].Y) - Edge-&gt;SourceStepY = FixedDiv(INT_TO_FIXED(TexVertsPtr[NextVert].Y) -
Edge-&gtSourceY, DestYHeight); Edge-&gt;SourceY, DestYHeight);
/* Set up Bresenham-style variables for dest X stepping */ /* Set up Bresenham-style variables for dest X stepping */
Edge-&gtDestX = VertexPtr[StartVert].X; Edge-&gt;DestX = VertexPtr[StartVert].X;
if ((DestXWidth = if ((DestXWidth =
(VertexPtr[NextVert].X - VertexPtr[StartVert].X)) &lt 0) { (VertexPtr[NextVert].X - VertexPtr[StartVert].X)) &lt; 0) {
/* Set up for drawing right to left */ /* Set up for drawing right to left */
Edge-&gtDestXDirection = -1; Edge-&gt;DestXDirection = -1;
DestXWidth = -DestXWidth; DestXWidth = -DestXWidth;
Edge-&gtDestXErrTerm = 1 - Edge-&gtRemainingScans; Edge-&gt;DestXErrTerm = 1 - Edge-&gt;RemainingScans;
Edge-&gtDestXIntStep = -(DestXWidth / Edge-&gtRemainingScans); Edge-&gt;DestXIntStep = -(DestXWidth / Edge-&gt;RemainingScans);
} else { } else {
/* Set up for drawing left to right */ /* Set up for drawing left to right */
Edge-&gtDestXDirection = 1; Edge-&gt;DestXDirection = 1;
Edge-&gtDestXErrTerm = 0; Edge-&gt;DestXErrTerm = 0;
Edge-&gtDestXIntStep = DestXWidth / Edge-&gtRemainingScans; Edge-&gt;DestXIntStep = DestXWidth / Edge-&gt;RemainingScans;
} }
Edge-&gtDestXAdjUp = DestXWidth % Edge-&gtRemainingScans; Edge-&gt;DestXAdjUp = DestXWidth % Edge-&gt;RemainingScans;
Edge-&gtDestXAdjDown = Edge-&gtRemainingScans; Edge-&gt;DestXAdjDown = Edge-&gt;RemainingScans;
return(1); /* success */ return(1); /* success */
} }
StartVert = NextVert; /* keep looking for a non-0-height edge */ StartVert = NextVert; /* keep looking for a non-0-height edge */
@ -298,17 +298,17 @@ int SetUpEdge(EdgeScan * Edge, int StartVert)
/* Texture-map-draw the scan line between two edges. */ /* Texture-map-draw the scan line between two edges. */
void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge) void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge)
{ {
Fixedpoint SourceX = LeftEdge-&gtSourceX; Fixedpoint SourceX = LeftEdge-&gt;SourceX;
Fixedpoint SourceY = LeftEdge-&gtSourceY; Fixedpoint SourceY = LeftEdge-&gt;SourceY;
int DestX = LeftEdge-&gtDestX; int DestX = LeftEdge-&gt;DestX;
int DestXMax = RightEdge-&gtDestX; int DestXMax = RightEdge-&gt;DestX;
Fixedpoint DestWidth; Fixedpoint DestWidth;
Fixedpoint SourceXStep, SourceYStep; Fixedpoint SourceXStep, SourceYStep;
/* Nothing to do if fully X clipped */ /* Nothing to do if fully X clipped */
if ((DestXMax &lt= ClipMinX) || (DestX &gt= ClipMaxX)) { if ((DestXMax &lt;= ClipMinX) || (DestX &gt;= ClipMaxX)) {
return; return;
} }
if ((DestXMax - DestX) &lt= 0) { if ((DestXMax - DestX) &lt;= 0) {
return; /* nothing to draw */ return; /* nothing to draw */
} }
/* Width of destination scan line, for scaling. Note: because this is an /* Width of destination scan line, for scaling. Note: because this is an
@ -321,21 +321,21 @@ void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge)
DestWidth = INT_TO_FIXED(DestXMax - DestX); DestWidth = INT_TO_FIXED(DestXMax - DestX);
/* Calculate source steps that correspond to each dest X step (across /* Calculate source steps that correspond to each dest X step (across
the scan line) */ the scan line) */
SourceXStep = FixedDiv(RightEdge-&gtSourceX - SourceX, DestWidth); SourceXStep = FixedDiv(RightEdge-&gt;SourceX - SourceX, DestWidth);
SourceYStep = FixedDiv(RightEdge-&gtSourceY - SourceY, DestWidth); SourceYStep = FixedDiv(RightEdge-&gt;SourceY - SourceY, DestWidth);
/* Clip right edge if necessary */ /* Clip right edge if necessary */
if (DestXMax &gt ClipMaxX) { if (DestXMax &gt; ClipMaxX) {
DestXMax = ClipMaxX; DestXMax = ClipMaxX;
} }
/* Clip left edge if necssary */ /* Clip left edge if necssary */
if (DestX &lt ClipMinX) { if (DestX &lt; ClipMinX) {
SourceX += SourceXStep * (ClipMinX - DestX); SourceX += SourceXStep * (ClipMinX - DestX);
SourceY += SourceYStep * (ClipMinX - DestX); SourceY += SourceYStep * (ClipMinX - DestX);
DestX = ClipMinX; DestX = ClipMinX;
} }
/* Scan across the destination scan line, updating the source image /* Scan across the destination scan line, updating the source image
position accordingly */ position accordingly */
for (; DestX&ltDestXMax; DestX++) { for (; DestX&lt;DestXMax; DestX++) {
/* Get currently mapped pixel out of image and draw it to screen */ /* Get currently mapped pixel out of image and draw it to screen */
WritePixelX(DestX, DestY, WritePixelX(DestX, DestY,
GET_IMAGE_PIXEL(TexMapBits, TexMapWidth, GET_IMAGE_PIXEL(TexMapBits, TexMapWidth,

View file

@ -57,21 +57,21 @@ void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge)
{ {
Fixedpoint SourceX; Fixedpoint SourceX;
Fixedpoint SourceY; Fixedpoint SourceY;
int DestX = LeftEdge-&gtDestX; int DestX = LeftEdge-&gt;DestX;
int DestXMax = RightEdge-&gtDestX; int DestXMax = RightEdge-&gt;DestX;
Fixedpoint DestWidth; Fixedpoint DestWidth;
Fixedpoint SourceStepX, SourceStepY; Fixedpoint SourceStepX, SourceStepY;
/* Nothing to do if fully X clipped */ /* Nothing to do if fully X clipped */
if ((DestXMax &lt= ClipMinX) || (DestX &gt= ClipMaxX)) { if ((DestXMax &lt;= ClipMinX) || (DestX &gt;= ClipMaxX)) {
return; return;
} }
if ((DestXMax - DestX) &lt= 0) { if ((DestXMax - DestX) &lt;= 0) {
return; /* nothing to draw */ return; /* nothing to draw */
} }
SourceX = LeftEdge-&gtSourceX; SourceX = LeftEdge-&gt;SourceX;
SourceY = LeftEdge-&gtSourceY; SourceY = LeftEdge-&gt;SourceY;
/* Width of destination scan line, for scaling. Note: because this is an /* Width of destination scan line, for scaling. Note: because this is an
integer-based scaling, it can have a total error of as much as nearly integer-based scaling, it can have a total error of as much as nearly
@ -84,30 +84,30 @@ void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge)
/* Calculate source steps that correspond to each dest X step (across /* Calculate source steps that correspond to each dest X step (across
the scan line) */ the scan line) */
SourceStepX = FixedDiv(RightEdge-&gtSourceX - SourceX, DestWidth); SourceStepX = FixedDiv(RightEdge-&gt;SourceX - SourceX, DestWidth);
SourceStepY = FixedDiv(RightEdge-&gtSourceY - SourceY, DestWidth); SourceStepY = FixedDiv(RightEdge-&gt;SourceY - SourceY, DestWidth);
/* Advance 1/2 step in the stepping direction, to space scanned pixels /* Advance 1/2 step in the stepping direction, to space scanned pixels
evenly between the left and right edges. (There&rsquo;s a slight inaccuracy evenly between the left and right edges. (There&rsquo;s a slight inaccuracy
in dividing negative numbers by 2 by shifting rather than dividing, in dividing negative numbers by 2 by shifting rather than dividing,
but the inaccuracy is in the least significant bit, and we&rsquo;ll just but the inaccuracy is in the least significant bit, and we&rsquo;ll just
live with it.) */ live with it.) */
SourceX += SourceStepX &gt&gt 1; SourceX += SourceStepX &gt;&gt; 1;
SourceY += SourceStepY &gt&gt 1; SourceY += SourceStepY &gt;&gt; 1;
/* Clip right edge if necssary */ /* Clip right edge if necssary */
if (DestXMax &gt ClipMaxX) if (DestXMax &gt; ClipMaxX)
DestXMax = ClipMaxX; DestXMax = ClipMaxX;
/* Clip left edge if necssary */ /* Clip left edge if necssary */
if (DestX &lt ClipMinX) { if (DestX &lt; ClipMinX) {
SourceX += FixedMul(SourceStepX, INT-TO-FIXED(ClipMinX - DestX)); SourceX += FixedMul(SourceStepX, INT-TO-FIXED(ClipMinX - DestX));
SourceY += FixedMul(SourceStepY, INT-TO-FIXED(ClipMinX - DestX)); SourceY += FixedMul(SourceStepY, INT-TO-FIXED(ClipMinX - DestX));
DestX = ClipMinX; DestX = ClipMinX;
} }
/* Scan across the destination scan line, updating the source image /* Scan across the destination scan line, updating the source image
position accordingly */ position accordingly */
for (; DestX&ltDestXMax; DestX++) { for (; DestX&lt;DestXMax; DestX++) {
/* Get the currently mapped pixel out of the image and draw it to /* Get the currently mapped pixel out of the image and draw it to
the screen */ the screen */
WritePixelX(DestX, DestY, WritePixelX(DestX, DestY,

View file

@ -87,7 +87,7 @@ DestXAdjDown dw ? ;amount to subtract from error term when the
EdgeScan ends EdgeScan ends
Parms struc Parms struc
dw 2 dup(?) ;return address &amp pushed BP dw 2 dup(?) ;return address &amp; pushed BP
LeftEdge dw ? ;pointer to EdgeScan structure for left edge LeftEdge dw ? ;pointer to EdgeScan structure for left edge
RightEdge dw ? ;pointer to EdgeScan structure for right edge RightEdge dw ? ;pointer to EdgeScan structure for right edge
Parms ends Parms ends

View file

@ -59,7 +59,7 @@
; EDX = fractional source texture Y coordinate in lower ; EDX = fractional source texture Y coordinate in lower
; 15 bits of CX, fractional source texture X coord ; 15 bits of CX, fractional source texture X coord
; in high word of ECX, bit 15 set to 0 ; in high word of ECX, bit 15 set to 0
; SI = sum of integral X &amp Y source pointer advances ; SI = sum of integral X &amp; Y source pointer advances
; DS:DI = initial destination pointer ; DS:DI = initial destination pointer
; SS:BP = initial source texture pointer ; SS:BP = initial source texture pointer
@ -73,7 +73,7 @@ SCANOFFSET=0
add edx,ecx ;advance frac Y in DX, add edx,ecx ;advance frac Y in DX,
; frac X in high word of EDX ; frac X in high word of EDX
adc bp,si ;advance source pointer by integral adc bp,si ;advance source pointer by integral
; X &amp Y amount, also accounting for ; X &amp; Y amount, also accounting for
; carry from X fractional addition ; carry from X fractional addition
test dh,80h ;carry from Y fractional addition? test dh,80h ;carry from Y fractional addition?
jz @F ;no jz @F ;no

View file

@ -43,7 +43,7 @@
; rather than a horizontal scanline. Maxed-out 32-bit version. ; rather than a horizontal scanline. Maxed-out 32-bit version.
; ;
; At this point: ; At this point:
; EAX = sum of integral X &amp Y source pointer advances ; EAX = sum of integral X &amp; Y source pointer advances
; ECX = source pointer increment to advance one in Y ; ECX = source pointer increment to advance one in Y
; EDX = fractional source texture Y coordinate in lower ; EDX = fractional source texture Y coordinate in lower
; 15 bits of DX, fractional source texture X coord ; 15 bits of DX, fractional source texture X coord
@ -62,7 +62,7 @@ SCANOFFSET=0
add edx,ebp ;advance frac Y in DX, add edx,ebp ;advance frac Y in DX,
; frac X in high word of EDX ; frac X in high word of EDX
adc esi,eax ;advance source pointer by integral adc esi,eax ;advance source pointer by integral
; X &amp Y amount, also accounting for ; X &amp; Y amount, also accounting for
; carry from X fractional addition ; carry from X fractional addition
mov [edi+SCANOFFSET],bl ;set screen pixel mov [edi+SCANOFFSET],bl ;set screen pixel
; (located here to avoid 486 ; (located here to avoid 486

View file

@ -76,20 +76,20 @@
void WalkBSPTree(NODE *pNode) void WalkBSPTree(NODE *pNode)
{ {
if (WallFacingForward(pNode) { if (WallFacingForward(pNode) {
if (pNode-&gtBackChild) { if (pNode-&gt;BackChild) {
WalkBSPTree(pNode-&gtBackChild); WalkBSPTree(pNode-&gt;BackChild);
} }
Draw(pNode); Draw(pNode);
if (pNode-&gtFrontChild) { if (pNode-&gt;FrontChild) {
WalkBSPTree(pNode-&gtFrontChild); WalkBSPTree(pNode-&gt;FrontChild);
} }
} else { } else {
if (pNode-&gtFrontChild) { if (pNode-&gt;FrontChild) {
WalkBSPTree(pNode-&gtFrontChild); WalkBSPTree(pNode-&gt;FrontChild);
} }
Draw(pNode); Draw(pNode);
if (pNode-&gtBackChild) { if (pNode-&gt;BackChild) {
WalkBSPTree(pNode-&gtBackChild); WalkBSPTree(pNode-&gt;BackChild);
} }
} }
} }

View file

@ -49,7 +49,7 @@
<PRE> <PRE>
// Function to inorder walk a tree, using code recursion. // Function to inorder walk a tree, using code recursion.
// Tested with 32-bit Visual C++ 1.10. // Tested with 32-bit Visual C++ 1.10.
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ldquo;tree.h&rdquo; #include &ldquo;tree.h&rdquo;
extern void Visit(NODE *pNode); extern void Visit(NODE *pNode);
void WalkTree(NODE *pNode) void WalkTree(NODE *pNode)
@ -58,16 +58,16 @@ void WalkTree(NODE *pNode)
if (pNode != NULL) if (pNode != NULL)
{ {
// Traverse the left subtree, if there is one // Traverse the left subtree, if there is one
if (pNode-&gtpLeftChild != NULL) if (pNode-&gt;pLeftChild != NULL)
{ {
WalkTree(pNode-&gtpLeftChild); WalkTree(pNode-&gt;pLeftChild);
} }
// Visit this node // Visit this node
Visit(pNode); Visit(pNode);
// Traverse the right subtree, if there is one // Traverse the right subtree, if there is one
if (pNode-&gtpRightChild != NULL) if (pNode-&gt;pRightChild != NULL)
{ {
WalkTree(pNode-&gtpRightChild); WalkTree(pNode-&gt;pRightChild);
} }
} }
} }
@ -97,7 +97,7 @@ struct _NODE *pRightChild;
// Function to inorder walk a tree, using data recursion. // Function to inorder walk a tree, using data recursion.
// No stack overflow testing is performed. // No stack overflow testing is performed.
// Tested with 32-bit Visual C++ 1.10. // Tested with 32-bit Visual C++ 1.10.
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &ldquo;tree.h&rdquo; #include &ldquo;tree.h&rdquo;
#define MAX_PUSHED_NODES 100 #define MAX_PUSHED_NODES 100
extern void Visit(NODE *pNode); extern void Visit(NODE *pNode);
@ -118,10 +118,10 @@ void WalkTree(NODE *pNode)
// Keep doing this until we come to a node // Keep doing this until we come to a node
// with no left child; that&rsquo;s the next node to // with no left child; that&rsquo;s the next node to
// visit in inorder sequence // visit in inorder sequence
while (pNode-&gtpLeftChild != NULL) while (pNode-&gt;pLeftChild != NULL)
{ {
*pNodeStack++ = pNode; *pNodeStack++ = pNode;
pNode = pNode-&gtpLeftChild; pNode = pNode-&gt;pLeftChild;
} }
// We&rsquo;re at a node that has no left child, so // We&rsquo;re at a node that has no left child, so
// visit the node, then visit the right // visit the node, then visit the right
@ -143,11 +143,11 @@ void WalkTree(NODE *pNode)
// passed on the way down, until we find a // passed on the way down, until we find a
// node with a right subtree to traverse // node with a right subtree to traverse
// or run out of pushed nodes and are done // or run out of pushed nodes and are done
if (pNode-&gtpRightChild != NULL) if (pNode-&gt;pRightChild != NULL)
{ {
// Current node has a right child; // Current node has a right child;
// traverse the right subtree // traverse the right subtree
pNode = pNode-&gtpRightChild; pNode = pNode-&gt;pRightChild;
break; break;
} }
// Pop the next node from the stack so // Pop the next node from the stack so

View file

@ -53,10 +53,10 @@
// Sample program to exercise and time the performance of // Sample program to exercise and time the performance of
// implementations of WalkTree(). // implementations of WalkTree().
// Tested with 32-bit Visual C++ 1.10 under Windows NT. // Tested with 32-bit Visual C++ 1.10 under Windows NT.
#include &ltstdio.h&gt #include &lt;stdio.h&gt;
#include &ltconio.h&gt #include &lt;conio.h&gt;
#include &ltstdlib.h&gt #include &lt;stdlib.h&gt;
#include &lttime.h&gt #include &lt;time.h&gt;
#include &ldquo;tree.h&rdquo; #include &ldquo;tree.h&rdquo;
long VisitCount = 0; long VisitCount = 0;
void main(void); void main(void);
@ -68,12 +68,12 @@ void main()
int i; int i;
long StartTime; long StartTime;
// Build a sample tree // Build a sample tree
BuildTree(&ampRootNode, 14); BuildTree(&amp;RootNode, 14);
// Walk the tree 1000 times and see how long it takes // Walk the tree 1000 times and see how long it takes
StartTime = time(NULL); StartTime = time(NULL);
for (i=0; i&lt1000; i++) for (i=0; i&lt;1000; i++)
{ {
WalkTree(&ampRootNode); WalkTree(&amp;RootNode);
} }
printf(&ldquo;Seconds elapsed: %ld\n&rdquo;, printf(&ldquo;Seconds elapsed: %ld\n&rdquo;,
time(NULL) - StartTime); time(NULL) - StartTime);
@ -87,25 +87,25 @@ void BuildTree(NODE *pNode, int RemainingDepth)
{ {
if (RemainingDepth == 0) if (RemainingDepth == 0)
{ {
pNode-&gtpLeftChild = NULL; pNode-&gt;pLeftChild = NULL;
pNode-&gtpRightChild = NULL; pNode-&gt;pRightChild = NULL;
} }
else else
{ {
pNode-&gtpLeftChild = malloc(sizeof(NODE)); pNode-&gt;pLeftChild = malloc(sizeof(NODE));
if (pNode-&gtpLeftChild == NULL) if (pNode-&gt;pLeftChild == NULL)
{ {
printf(&ldquo;Out of memory\n&rdquo;); printf(&ldquo;Out of memory\n&rdquo;);
exit(1); exit(1);
} }
pNode-&gtpRightChild = malloc(sizeof(NODE)); pNode-&gt;pRightChild = malloc(sizeof(NODE));
if (pNode-&gtpRightChild == NULL) if (pNode-&gt;pRightChild == NULL)
{ {
printf(&ldquo;Out of memory\n&rdquo;); printf(&ldquo;Out of memory\n&rdquo;);
exit(1); exit(1);
} }
BuildTree(pNode-&gtpLeftChild, RemainingDepth - 1); BuildTree(pNode-&gt;pLeftChild, RemainingDepth - 1);
BuildTree(pNode-&gtpRightChild, RemainingDepth - 1); BuildTree(pNode-&gt;pRightChild, RemainingDepth - 1);
} }
} }
// //

View file

@ -40,7 +40,7 @@
</P> </P>
<P>For our purposes, <I>projection</I> is the process of mapping coordinates onto a line or surface. <I>Perspective projection</I> projects 3-D coordinates onto a viewplane, scaling coordinates according to their z distance from the viewpoint in order to provide proper perspective. <I>Objectspace</I> is the coordinate space in which an object is defined, independent of other objects and the world itself. <I>Worldspace</I> is the absolute frame of reference for a 3-D world; all objects&rsquo; locations and orientations are with respect to worldspace, and this is the frame of reference around which the viewpoint and view direction move. <I>Viewspace</I> is worldspace as seen from the viewpoint, looking in the view direction. <I>Screenspace</I> is viewspace after perspective projection and scaling to the screen.</P> <P>For our purposes, <I>projection</I> is the process of mapping coordinates onto a line or surface. <I>Perspective projection</I> projects 3-D coordinates onto a viewplane, scaling coordinates according to their z distance from the viewpoint in order to provide proper perspective. <I>Objectspace</I> is the coordinate space in which an object is defined, independent of other objects and the world itself. <I>Worldspace</I> is the absolute frame of reference for a 3-D world; all objects&rsquo; locations and orientations are with respect to worldspace, and this is the frame of reference around which the viewpoint and view direction move. <I>Viewspace</I> is worldspace as seen from the viewpoint, looking in the view direction. <I>Screenspace</I> is viewspace after perspective projection and scaling to the screen.</P>
<P>Finally, <I>transformation</I> is the process of converting points from one coordinate space into another; in our case, that&rsquo;ll mean rotating and translating (moving) points from objectspace or worldspace to viewspace.</P> <P>Finally, <I>transformation</I> is the process of converting points from one coordinate space into another; in our case, that&rsquo;ll mean rotating and translating (moving) points from objectspace or worldspace to viewspace.</P>
<P>For additional information, you might want to check out Foley &amp van Dam&rsquo;s <I>Computer Graphics</I> (ISBN 0-201-12110-7), or the chapters in this book dealing with my X-Sharp 3-D graphics library.</P> <P>For additional information, you might want to check out Foley &amp; van Dam&rsquo;s <I>Computer Graphics</I> (ISBN 0-201-12110-7), or the chapters in this book dealing with my X-Sharp 3-D graphics library.</P>
<H3><A NAME="Heading5"></A>The Dot Product</H3> <H3><A NAME="Heading5"></A>The Dot Product</H3>
<P>Now we&rsquo;re ready to move on to the dot product. Given two vectors <B>U</B> = [u<SUB>1</SUB> u<SUB>2</SUB> u<SUB>3</SUB>] and <B>V</B> = [v<SUB>1</SUB> v<SUB>2</SUB> v<SUB>3</SUB>], their dot product, denoted by the symbol &bull;, is calculated as:</P> <P>Now we&rsquo;re ready to move on to the dot product. Given two vectors <B>U</B> = [u<SUB>1</SUB> u<SUB>2</SUB> u<SUB>3</SUB>] and <B>V</B> = [v<SUB>1</SUB> v<SUB>2</SUB> v<SUB>3</SUB>], their dot product, denoted by the symbol &bull;, is calculated as:</P>
<P ALIGN="LEFT"><P ALIGN="CENTER"><IMG SRC="images/61-02d.jpg"></P> <P ALIGN="LEFT"><P ALIGN="CENTER"><IMG SRC="images/61-02d.jpg"></P>

View file

@ -262,8 +262,8 @@ void ClipWalls()
// perform a quick test for trivial rejection by seeing if // perform a quick test for trivial rejection by seeing if
// the end point is outside the view triangle on the same // the end point is outside the view triangle on the same
// side as the start point // side as the start point
if (((tempstartx&gt;tempstartz) &amp&amp (tempendx&gt;tempendz)) || if (((tempstartx&gt;tempstartz) &amp;&amp; (tempendx&gt;tempendz)) ||
((tempstartx&lt;-tempstartz) &amp&amp (tempendx&lt;-tempendz))) ((tempstartx&lt;-tempstartz) &amp;&amp; (tempendx&lt;-tempendz)))
// Fully clipped&mdash;trivially reject // Fully clipped&mdash;trivially reject
goto NextWall; goto NextWall;
// Clip the start point // Clip the start point
@ -327,9 +327,9 @@ void ClipWalls()
(tempendwalltop &gt; tempendz) || (tempendwalltop &gt; tempendz) ||
(tempendwallbottom &lt; -tempendz)) { (tempendwallbottom &lt; -tempendz)) {
// Not trivially unclipped; check for fully clipped // Not trivially unclipped; check for fully clipped
if ((tempstartwallbottom &gt; tempstartz) &amp&amp if ((tempstartwallbottom &gt; tempstartz) &amp;&amp;
(tempstartwalltop &lt; -tempstartz) &amp&amp (tempstartwalltop &lt; -tempstartz) &amp;&amp;
(tempendwallbottom &gt; tempendz) &amp&amp (tempendwallbottom &gt; tempendz) &amp;&amp;
(tempendwalltop &lt; -tempendz)) { (tempendwalltop &lt; -tempendz)) {
// Outside view triangle, trivially clipped // Outside view triangle, trivially clipped
goto NextWall; goto NextWall;

View file

@ -108,11 +108,11 @@ FSUB ST(0),ST(1)
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
; use of fxch to allow addition of first two; products to start while third : multiplication finishes ; use of fxch to allow addition of first two; products to start while third : multiplication finishes
fld [vec0+0] ;starts &amp ends on cycle 0 fld [vec0+0] ;starts &amp; ends on cycle 0
fmul [vec1+0] ;starts on cycle 1 fmul [vec1+0] ;starts on cycle 1
fld [vec0+4] ;starts &amp ends on cycle 2 fld [vec0+4] ;starts &amp; ends on cycle 2
fmul [vec1+4] ;starts on cycle 3 fmul [vec1+4] ;starts on cycle 3
fld [vec0+8] ;starts &amp ends on cycle 4 fld [vec0+8] ;starts &amp; ends on cycle 4
fmul [vec1+8] ;starts on cycle 5 fmul [vec1+8] ;starts on cycle 5
fxch st(1) ;no cost fxch st(1) ;no cost
faddp st(2),st(0) ;starts on cycle 6 faddp st(2),st(0) ;starts on cycle 6

Some files were not shown because too many files have changed in this diff Show more