**Part 3: Multi-Colored Graphics In Mode 8**

Phil Dunn

*Into the world of Graphics mode 8, with multi-colored displays. This tutorial and commentary covers both the CTIA and the GTIA chips. You'll find the explanations and utility programs invaluable. 32 K RAM memory is recommended, but, with judicious cutting, you can run this with 24K.*

Graphics Mode 8 provides the highest resolution images that we can generate with the Atari system, with a horizontal grid of 320 and a vertical grid of 192 (or 160 with a split screen). Therefore, a mastery of the mysteries of Mode 8 will enable us to develop some of the highest quality images that the Atari system can provide. This article offers you that ability, with some user-friendly programs that make it as easy as apple pie. If you want to, you can generate your own version of the Atari Video Easel, or you can use the programs to make really fine pictures.

These routines will require 32K of memory to work in Mode 8 graphics. With all REM statements removed, and a reduction in some nonessential functions, these routines should work with only 24K of memory.

There is a rumor that Mode 8 graphics allows only one color. This rumor states that the SETCOLOR 2 command determines the hue and luminance of the background, and the SETCOLOR 1 command determines just the luminance of a point or line drawn with the PLOT-DRAWTO commands. The only other SETCOLOR command that has any effect in Mode 8 is SETCOLOR 4, which only controls the hue and luminance of the border.

This rumor has an impeccable source: the Atari BASIC Reference Manual. Let's check it out. We go over to our favorite machine and flip on the power switches for our computer and TV monitor, and see our friendly 'READY' message pop up at the top of the screen.

From past encounters of this kind we know that we are in Mode 0. So, we type in the direct command, GRAPHICS 8. The screen flips and now we see the READY at the bottom of the screen. "Aha!" we think, "Mode 8 with our split-screen text window at the bottom."

Let's draw a line. We type in the command, COLOR 1 : PLOT 5, 80 : DRAWTO 315, 80 and a horizontal line appears. Now we can play with SETCOLOR commands to our heart's content, and we will only conclude that the manual is telling the truth, the whole truth, and nothing but the truth, so help them Atari!

Now let's run a different experiment. As in any good experiment, we must carefully set the conditions. With SETCOLOR 2, 0, 0 we set a black background, and with SETCOLOR 1, 0, 12 we get set for high-contrast lines. Now, with the command PLOT 160, 150 : DRAWTO 160, 5 we see a brown line if we have the CTIA chip, or we see a blue line if we have the GTIA chip.

But you may not see brown or blue. The color you see, and all the colors that are mentioned in the remainder of this article, are dependent upon the condition and alignment of your system. While the colors you see may be different than the ones described here, the principles and techniques for obtaining the variety of colors remain the same.

Now let's enter the command PLOT 101, 150 : DRAWTO 101, 5, and we will see a blue vertical line if we have the CTIA chip, or a brown line with the GTIA. Why are the two lines different colors? It's just dependent upon whether the vertical line has an even or an odd value for its X coordinate. All vertical lines with an even X value will be one color, and all with an odd X value will be the other. This is true for all PLOT points also. If we wish to draw a line at any angle by PLOTting only those line points at the odd or even X coordinate values, then we will obtain a blue or brown line.

Notice that I am saying that the color we obtain (as a function of whether the X coordinate parity is odd or even) is reversed between the CTIA and the GTIA chips. Both chips give us exactly the same variety of colors and textures in Mode 8. It is just the effect of the X coordinate parity that is reversed. As far as I know, this type of color difference between the two chips does not exist in any mode other than Graphics 8.

In the remainder of this article, when I refer to colors, I will first indicate the color we obtain with the CTIA chip, and then, alongside it and in parentheses, the color obtained with the GTIA chip.

If we draw another line with the command PLOT 160, 80 : DRAWTO 240, 120 we see a green (red) line. Typing PLOT 101, 80 : DRAWTO 181, 120 gives a red (green) line. The rule here is that all sloping lines with an X/Y ratio slope of 2/1 will be either green or red, depending upon the X coordinate of the start point.

The command PLOT 10, 10 : DRAWTO 150, 150 gives us a grey line. All lines drawn with an X/Y ratio slope of 1/1 will be grey.

These are what we will call the six primary colors of Mode 8 graphics. White (horizontal lines, or several lines adjacent to each other), brown and blue (vertical lines), green and red (2/1 slope lines), and grey (1/1) slope lines. All other sloping lines tend to give peppermint-stripe mixtures of these primary colors.

Now, next to the blue (brown) vertical line at 101, 150-101, 5 let's PLOT-DRAWTO another line at 102, 80-102, 60. This gives us a green (red) line, but one with a different texture than we saw in the 2/1 ratio version. If we PLOT-DRAWTO another line at 100, 60-100, 40 we get a red (green) line, again with a different texture than we saw previously.

If we enter the PLOT-DRAWTO Command 159, 80-199, 100, it merges with our green (red) sloping line to give a warm grey. The command 201, 100-241, 120 converts our green (red) line to a cool grey.

The colors and textures that we obtain by drawing multiple lines that interact with one another we can call the secondary colors and textures of Mode 8 graphics. How many are there? I don't know. Later on in this article you will see over 60 that I have found. I only stopped at that point to write this up so others could explore this also.

Well, what is going on here with that Atari Manual? Is Atari trying to hide something from us about Mode 8? What's the story?

The Atari Manual is not lying. It is hiding something, though. It is hiding something that might only be confusing to the programming novice who is still struggling to grasp the implications of the various commands in BASIC and the Atari graphics modes. Also, what value is a color you can only get by drawing a line at some specific angle? (Plenty of value! More about this later.)

The answer to what this is all about lies in the structure of our video tubes and the way they generate colors. The face of these tubes is covered with a series of horizontal "scan lines" that consist of a repeating series of blue, green and red phosphor dots. These phosphor dots only glow their color if the electron beam gun in the neck of the tube shoots them. These dots are so small that we don't see them as dots, but only as the composite color of many dots. The variety of colors that we see on TV, and with which Atari provides us in its hueluminance SETCOLOR command, is obtained by controlling the electron beam intensity to each dot. It is the balancing of the brightness between the blue, green, and red dots that provides us with the full spectrum of colors.

This feature of Mode 8 graphics occurs because when we draw a vertical line, that line is so thin that it cannot cover all three colors of the screen. When the X coordinate of the vertical line is odd (even), it hits mostly the blue dots, and we get a blue line. When the X coordinate is even (odd), it hits both red and green dots, giving us a brown line. The resolution of Atari Mode 8 graphics is almost as fine as the resolution of the TV screen dot pattern! Since our lines may not touch all three color dots, the line color cannot be adjusted effectively by balancing the color-dot intensities as is done in the lower resolution graphics modes. (Horizontal lines always cover all three dot colors.)

Now we understand Mode 8, and we recognize that it has colors, but how can we use them? Well, we can always draw blue and brown lines, but that is not where the action is. The action is where the possibility exists for a multitude of colors, patterns, and textures. The action lies not in drawing lines, but in coloring areas. And what is our simplest, most useful method for coloring areas? If you have read the previous articles you know the answer. It is the polygon fill technique.

If we want to think of the PLOT-DRAW commands as being our Atari colored pencils, then the polygon fill technique is our Atari paintbrush.

At this point it is most appropriate to scan the programs presented here. Program 1, the POLY8 subroutine, is the essential tool that we will use to harness the graphics power of Mode 8. The POLY8 subroutine is supported by a secondary subroutine called LINEP, given here as Program 2. LINEP is based upon a machine code program. For those interested, the machine code assembly listing is presented as Program 3. My appreciation to Bill Wilkinson for that fantastically useful article on Atari I/O Graphics (**COMPUTE!**, February 1982, #21), and to Judy Bogart of Atari for her advice and direction regarding the CIO method.

Program 4 is the PALETT8 program, which allows us to investigate and discover the colors, patterns, and textures inherent in Mode 8. Although it has been set up to work in Modes 6 and 7 also, it was primarily designed to study Mode 8 graphics. Naturally, it essentially depends upon the POLY8 subroutine which must be appended to it.

Program 5 is the PICTUR8 program. This program allows us to define a complete picture just by entering values in data statements. This, too, is essentially dependent upon the POLY8 subroutine.

These programs have been written with an abundance of REM statements. Even with all the REM statements removed, they will require more than 16K of memory to run in Graphics Mode 8. With the REM statements removed they should run with 24K, or they can be left in if you have more.

The Atari BASIC Reference Manual tells us that we can reduce the memory requirements of our programs by defining constant numeric values in variables, when the constants are used in more than two or three places in our program. I have decided as a regular practice to set up the beginning of all my programs and general purpose subroutines with variables with names beginning with the letter "C" to represent the most commonly used numeric constants. This procedure has been implemented in these programs.

The key to the use of these programs is in the POLY8 subroutine, so let's take a look at Program 1. The initial REM statements summarize its capabilities, so we'll review them. The first variable this subroutine uses is TYPE, which can vary from 1 to 7, depending upon how this routine will be used. For TYPE values of 1 to 6 this routine also requires a value for the variable NP, and values for the DIMensioned array variables X(i), Y(i), where i varies from 1 to NP.

When TYPE = 1, for "Bar Painting," a defined polygon area will be filled with lines (or "bars") in a way which we can specify. The polygon is defined by its perimeter points, the X, Y values stored in the X(), Y() DIMensioned array variables. NP specifies the number of perimeter points around the polygon.

When TYPE = 2, for "Pixel Painting," the defined polygon will be filled on a pixel-by-pixel basis, according to our specified instructions. When TYPE = 3 the defined polygon area will only be outlined, by drawing a series of lines around its perimeter.

For values of TYPE that are greater than 3, we are no longer dealing with a defined polygon area. Later on I will show how these options enable us to specify a huge amount of picture detail with a minimum amount of program coding.

When TYPE = 4 we simply color in the pixels, connected or disconnected, that are specified in the X(i), Y(i) array variables, where i varies from 1 to NP.

When TYPE = 5 we PLOT-DRAWTO a series of lines specified in the array variables X(i), Y(i) and X(i + 1), Y(i + 1) where i varies from 1 to NP. Note that NP always refers to the number of X, Y pairs to be used. Therefore, for one line set NP = 2, for two lines set NP = 4, for three line set NP = 6, etc.

When TYPE = 6 we DRAWTO from one point to another, starting at the initial cursor position to X(1), Y(2), then to X(2), Y(2), then to X(NP), Y(NP).

When TYPE = 7 a color register is assigned by the COLOR command using the value stored in the RA variable.

For cases where TYPE = 1 or TYPE = 2, additional information is required. The slope at which the bars are to be drawn, or the pixels are to be swept, is specified in the RA variable in terms of the X/Y ratio. RA = 0 for vertical lines, + 1 or -1 for lines at + 45 degrees or 45 degrees, and RA = 100 for horizontal lines.

As we have previously seen, the factors that determine the line colors in Mode 8 are the line slope and the X-axis odd/even parity. The zero element of the P() array is used to specify the parity option. If P(0) = 0 then the parity option is bypassed. If P(0) = 1 then odd parity is selected, and if P(0) = 2 then the even parity option is chosen.

The remaining elements in the P(i) array, for values of i greater than zero, are used to specify the line spacing sequence, and determine whether or not the parity option is to be applied to that line. The parity option, if selected, always is applied to the first line drawn. All succeeding lines can have the parity option applied or not, at our specification. If the corresponding value of P(i) is negative, then the parity option will be applied to that line. If P(i) has a positive value, then the parity option will be bypassed for that line.

The magnitude of P(i) determines the increment to move to draw the next line. If the magnitude of P(i) is equal to 1, then the next line will be drawn immediately adjacent to the previous one. If the magnitude is 2, then there will be one space between; if 3, then two spaces between, etc. Therefore, a value of zero would mean that the next line should be drawn directly over the previous one. Since this would make no sense at all, the value of zero is used to indicate the end of the P(i) sequence.

Now here comes the neat part: If the polygon was not completely filled and a value of P(i) = 0 is obtained (signifying the end of the line spacing sequence), then the line spacing sequence is set back to the first element in the sequence, P(1), and the procedure continues until the polygon is filled up.

Therefore, one of the simplest sequences for this array is P(0) = 1, P(1) = -2, P(2) = 0. For this example sequence P(0) specifies odd parity, P(1) specifies the application of the odd parity to that line and to increment the line position by 2 (i.e., to skip one space), and P(2) ends the sequence. This command sequence will fill the polygon with a series of lines separated by one space, with each line drawn from an odd X coordinate.

When TYPE = 2 for Pixel Painting, additional information must be specified. The variable PB specifies the random probability blend of plotted and unchanged pixels. The plotted pixels are colored as per the previously specified COLOR command. The unchanged pixels may be spoken of as being plotted with the "transparent" color. This gives us the possibility of doing a multiplicity of "overlay" effects on the same area. If PB is less than 1, then PB specifies the probability or proportion of plotted pixels. When PB = .1 then ten percent of the pixels will be plotted. When PB = .5 then 50 percent will be plotted, etc.

If PB = 1 then another form of blending will be used, and another variable, *PC*, must be used to control this technique. When PC › 0 then the first line drawn will be entirely unchanged pixels and the last line drawn to fill the polygon will be entirely plotted pixels. The lines in between will have a higher proportion of plotted pixels as they are drawn closer to the end of the polygon. When PC ‹ 0 then the unchanged-plotted pixel effect is reversed: the first line will be entirely plotted and the last line will be entirely unchanged.

The magnitude of *PC* determines the rate at which the proportion of pixels plotted changes from the start of the polygon to the end. If ABS(PC) = 1, then the proportion ratio changes evenly from one end of the polygon to the other. The line drawn at the halfway point will have half of its pixels plotted and the other half unchanged. When ABS(PC) › 1, say 2 or 4, the start condition phases out more slowly to the end condition, and the start condition will be seen to have more influence over the entire polygon. When ABS(PC) ‹ 1, say 0.5 or 0.25, then the start condition phases out more rapidly and the end condition is seen to dominate the polygon area.

If you have read the previous article, you may have noted that the "checkerboard" option that was available in the previous version is not specified here. This routine can be used to provide that effect if 45 degree lines are drawn every other space over a previously colored polygon.

This concludes a functional description of the POLY8 subroutine. We will take a brief tour of its structure before continuing on to the more practical aspects of how to use it. Overall, a great similarity will be found with respect to the polygon fill subroutines that were previously documented. Since these have been explained in previous sections, we will just focus on the differences here.

The additional and new TYPE options, implemented in lines 18405 to 18425, are fairly obvious. A big functional difference between this routine and the previous one is that this one lets us fill the polygon with lines of any specified slope. In order to implement this feature in the simplest way, a U, V axis system is defined as being rotated with respect to the screen X, Y axis system by the angle whose Sine and Cosine values are stored in the variables SA and CA, respectively. SA and CA are calculated in terms of the slope ratio RA in lines 18445 and 18450. RA is also the Tangent of the angle. Then, each X(), Y() array element that defines the polygon perimeter is rotated into a corresponding U(), V() array element in lines 18460 to 18475. Using the same method described in the previous article, vertical line segments are calculated to fill the polygon in the U, V plane, in lines 18550 to 18565. These line segments are then rotated back into the X, Y plane in lines 18575 to 18610. The previously described parity logic is implemented in the middle of this, in lines 18580 to 1859.

For the case of "bar painting," the line segments can be simply drawn with the PLOT-DRAWTO command in line 18620. In the case of "pixel painting," where each pixel must be tested to be plotted or passed over, I finally broke down and did some assembly programming. In Mode 8 graphics there are too many pixels and the coding in BASIC is too slow. The pixel-painting probability factor is calculated in lines 18643 and 18645, and the LINEP subroutine that does the job starts at line 18790.

Note that the machine code component of this routine must first be initialized by GOSUBing to line 18900.

Before we leave these dungeons of program structure, I have a confession to make. With all this geometry-math-programming, I couldn't escape the need for a cut-and-try Finagle correction factor. That's the Z5 round-up factor in lines 18575, 18595 and 18600. It is defined in lines 18430 and 18435. These values generally work well. But if you strike out on your own in the uncharted land of Mode 8 patterns and textures, and you find that for some reason the pattern suddenly shifts in the middle of the polygon, you might want to try modifying that factor for your case.

So much for the POLY8 structure. (Do I hear a sigh of relief somewhere?) The easiest way I know to become familiar with this subroutine is to use it to explore Mode 8 graphics, which is what this is all about anyway! And the easiest way I know to do this is by using Program 4, the PALETT8 program.

Studying the listing of the PALETT8 program, lines 270 and 275 define the constants for often used numeric values to reduce program memory requirements. (Naturally, if the REM statements are eliminated, memory requirements will be reduced much further.) The required DIMensioned arrays are defined in line 280, and the machine code routine is initialized in line 285.

Lines 295 to 320 initialize the E, F scale factors for the desired graphics mode. While these programs were developed specifically for Mode 8, they can be used in any mode. This version of the PALETT8 program can immediately run in Modes 6, 7, and 8. You can modify it to run in the other modes by inserting additional logic in this area.

Lines 370 to 490 set the initial hue-luminance values in the four registers of interest.

It might be useful to pause and study lines 570 to 780, because they represent an interesting programming technique. Instead of cluttering up our program with a group of PLOT-DRAWTO commands, the equivalent coding is set into DATA statements. Then, in lines 750 to 780 the information is used to either PLOT or DRAWTO, depending upon whether the code number is -1 or -2. The negative values for the code make it easy to differentiate the code from the X, Y coordinates in the DATA statements.

We will be studying Mode 8 colors and textures by placing them in one of 15 available screen areas. These square areas are defined in lines 810 to 950 in terms of four numbers that represent the lower left and upper right corners of the squares in the variables XL, YL, XU, YU. In line 1050 the program asks us which AREA we wish to use. If we return a value of from 1 to 15, then line 1090 points to the appropriate DATA location. Line 1100 reads the data, and lines 1110 to 1140 dump the appropriate values in the X(), Y() arrays (scaled appropriately for the specified graphics mode) that the POLY8 routine needs to define its polygon perimeter.

Note that if we return a zero value to the AREA question, then we are shunted to line 1660 where we can change our SETCOLOR assignment values by using the joystick. It works the same as the option in the previous article, as per the REM statements in lines 1840 to 1870.

Note also, as per REM lines 980 to 1030, that RETURNing the value 99 to any question will always reset the input sequence back to the AREA request on line 1050. We can also do the same thing by pressing the BREAK key and RETURNing the command GOTO 1050.

Now suppose we LOAD the program and RUN it. We specify Mode 8 graphics and, in response to the AREA question, we answer 1. We are then asked to choose between the CREATE and PRESET options by RETURNing 1 or 2. Let me defer an explanation of the PRESET option for the time being, and go straight to the CREATE option by RETURNing a 1.

We are then asked which TYPE of painting we desire, Bar, Pixel, or COLOR. Strictly speaking, the COLOR option is not a painting method at all, just the option to redefine the color register selection for the next PLOT-DRAWTO commands. This option is important, and it was a convenient place to stick it in the question sequence. If we do select the COLOR option, we are asked what COLOR number we desire (line 1600) and are reminded that in Mode 8 only 1 and 0 are functional COLOR numbers. However, we are not restricted from RETURNing any value to obtain the flexibility of being able to use this program in the other graphics modes.

Suppose we select Bar Painting. We are then asked for the angle ratio. We will select 0 for vertical lines. We are then asked for the value of the parity variable, P(0). We will select 1 for odd parity. Then we are asked for a value to P(1). Note that the program will refuse the value 0 for this variable. We will return with the value -2, which specifies the use of the parity check because it is negative, and will move two spaces (i.e., skip one space). We are then asked for the value of P(1). We return a value of 0 to end the sequence, and watch while it fills AREA 1 with Mode 8 primary blue (brown).

We are asked again "which AREA?" If we answer with a 2 and then repeat the exact same answers we gave previously (except for the parity variable P(0), for which we will return a value of 2 for even parity), we will see the machine fill area 2 with Mode 8 primary brown (blue).

With the next two areas we can repeat what we have just done. But by returning a value of 2 for the angle ratio we will obtain the Mode 8 primary colors, red and green. By returning a value of 1 for the angle ratio, zero for P(0) (no parity check), 2 for P(1), and 1 for P(2) we obtain Mode 8 primary grey.

Now let's go back to our blue area. In response to the AREA request we return a value of 1. This time, on top of the primary blue that is already there, we will overwrite the Mode 8 primary grey pattern and see how it interacts to form blue-grey diagonal bars. If we repeat this over the primary brown, we will see green-grey diagonal bars.

Remember the beginning of this article, where we changed the color of the blue vertical line by drawing another line immediately adjacent to it? Well, let's repeat that here.

We can return an AREA number 10, specify the CREATE mode, Bar Painting, an angle ratio of 0, and parity P(0) of 1. Then, for P(1) we can specify a -1 to move one space with parity check. For P(2) we can specify 3, to move three spaces without parity check. Since we are moving an odd number of spaces from our last parity check, the parity here must be the opposite and should not be checked against the reference P(0) specification. We can end this sequence by returning a value for P(3) of 0, and then watch green (red) vertical bars being drawn.

As we can see, this activity of generating Mode 8 textures and colors can go on indefinitely. Now let's take a look at that PRESET option in the program. However, if you have only 24K of memory, you may have to delete this PRESET coding, or at least some of the PRESET DATA lines, in order to RUN this program.

From line 1160, in response to returning a value of 2 for the PRESET option, we are shunted to line 1900 and asked "Which PRESET Number?" In this program version, starting at line 2070, we have stored only 67 "PRESET" colors and textures. Line 1930 prohibits a return value of less than 0 or more than 66.

Suppose we return a value of 2 for the PRESET Number. The DATA pointer on line 1950 will then point to DATA line 2090. The READ statement on line 1960 will then pick up the value of 1 on line 2090 and assign it to the TYPE variable. It then proceeds to read three more DATA values in line 1990 and assigns them to the variables RA = 0, P(0) = 1, and P(1) = -2. It then reads P(2) = 0 in line 2010 and, because of its zero value, it ends the READ sequence in line 2020 by GOSUBing to the POLY8 subroutine where it will proceed to fill the AREA specified with Mode 8 primary blue (brown).

When it returns from the POLY8 subroutine, it jumps to line 2040 and reads the next numeric DATA on line 2090. In this case the value is zero so the program loops back to the AREA question. However, if the value was 99 the program would have looped back to read the next value for TYPE, plus the rest of the information that would have laid another pattern over the previous one.

PRESET number 0, DATA line 2070, is important because it can be used as an eraser to wipe out previous patterns. It consists of a TYPE 7 COLOR command, a COLOR value of 0 (blank out), 99 to loop around for another READ, a new TYPE = 1 (Bar Painting). RATIO = 0 (vertical), P(0) = 0 (no parity), P(1) = 1 (no spaces between lines), P(2) = 0 to end the sequence and plot the off pixels, 99 to loop around again, 7 for the COLOR command, 1 to turn the COLOR back on, and 0 to end the DATA sequence and jump to the AREA request.

At this point you are on your own. You can call up the various 66 PRESET patterns stored here and study them. You can create new patterns and, when you find something you want to file, add it to this PRESET sequence. (Be sure to update the input limit test in line 1930.)

If you want to just continue drawing patterns over patterns, as per the Video Easel game, you can modify this program to automate that kind of operation. However, the COLOR should be alternated between 1 and 0, else very quickly it will just be drawing white on white.

At this point I imagine somebody is muttering that all this is nice, but what can we do with it besides play Video Easel type games?

Ah hah! Glad you asked. That PRESET data we assembled was not just an academic study. This is our color-texture PALETTE from which we shall judiciously extract what we need to create scenes with a quality that is unique to the graphics of Mode 8.

The time has now come to take a look at Program 5, the PICTUR8 program. This program is specifically designed for drawing a picture in Mode 8 graphics, although it would be a simple task to modify it for any other graphics mode. The specific example picture in this version of the program is defined entirely within the PRINT and DATA statements starting at line 1000. The program statements before line 1000 are fairly general, with the exception of the Graphics mode and SETCOLOR assignment values. If another Graphics mode is used, where the COLOR register values could be more than just 0 or 1, then the error detection statements in lines 390 and 590 must be changed.

Since some have the CTIA chip and others have the GTIA chip, this program has been designed to display the proper colors in either case. To do this, the program asks which chip is being used at line 330.

A great simplification technique is used here, where the picture DATA is separated into two major functions: AREA and FILL. The AREA DATA starts at line 3000 and defines the geometry in terms of X, Y coordinates. The FILL DATA starts at line 2000 and determines the type of painting technique, and the color-texture pattern that we will use to fill the polygon AREA.

At line 360 in the program the first numeric value is read from a line of AREA DATA and is assigned to the variable FILL. If FILL = 999 then the picture is complete and the program stops reading data and jumps to line 1000.

If the variable FILL is a positive number, then the program will eventually use it to read the appropriate fill data using the program logic at lines 550 and 560. For most cases this will probably be the condition. However, there are certain cases where this AREA-FILL split-up becomes excessively cumbersome and artificial. Therefore, a provision has been made to allow one to bypass the reading of separate fill data for these cases. This bypass option is enacted when the numeric value read for the FILL variable is negative.

For example, line 380 allows the program to fall through if FILL = 7 and to read the next data value as the variable RA. It then assigns the positive value of FILL to the variable type and lets the POLY8 subroutine handle it directly in line 405.

Another special provision has been implemented, allowing the use of multiple data sequences on the same line. After it returns from the POLY8 routine, the program reads the next data value at line 410. If it reads a value of 99, then that tells it to go back and read another set of data without incrementing the AREA DATA pointer. Otherwise, it will increment the AREA DATA pointer in lines 340 and 350 before reading the next data set.

If the variable FILL is not -7 then it reads the next data value and assigns it to the variable NP, at line 470. The program then proceeds to read in the next NP amount of number pairs which it promptly stores in the X(), Y() arrays, at line 496.

On line 510 FILL is checked one more time and, if it is a negative number, TYPE is set equal to that positive value of FILL and the program GOSUBs directly to the POLY8 subroutine. Otherwise, the program reads the value for the type variable from the fill DATA statement, as per line 550 and 560. If TYPE = 7 then it simply reads the next data value and sets the color in line 600. It then jumps to line 700 where it reads the next data value. Here, too, a value of 99 will enable it to keep reading fill data without jumping back to the AREA DATA and incrementing the AREA pointer.

If TYPE is not equal to 7, then it checks whether TYPE = 2, at line 620. If it is, then the next two data values are assigned to the variables PB and PC, for the POLY8 routine. If TYPE is not equal to 2, then the program directly reads the values for the variables RA, P(0), P(1), P(2) etc., and then GOSUBs to the POLY8 routine.

Suppose we take a look at some of the data and see how the program uses it. The AREA DATA starts at line 3000. Originally there were two items to be painted by the data that was in lines 3010 and 3020. Then I decided to move these items down in the sequence. Instead of changing all the line numbers of the data statements, I just inserted two "dummy" statements that don't really change anything. They both just specify a -7 code for the FILL variable, which tells the program to change the COLOR assignment. The next number is 1, so the program just implements the command COLOR 1, which was previously done anyway. The final zero in the data statement terminates the sequence. The remaining alphanumeric string is stored as if it were string data, but it is never read and has been inserted only for REMark type information.

The first real area painting is done in line 3030. The end string tells us that this is AREA 3 DATA, and that it is supposed to represent city walls. The first number, 8, is the value for the variable FILL. This will cause the program to read the fill data set at line 2080, which is "Bar Red," according to its alphanumeric label. The first number in line 2080 sets TYPE = 1 for Bar Painting. The second number sets RA = 0 for vertical lines. The third number sets P(0) = 2 for even parity check. The next two numbers set P(1) = -1 to move one space with parity check, and P(2) = 3 to then move 3 spaces without parity check. The next number sets P(3) = 0 to end the move command sequence. The final number of zero ends the DATA sequence for that line.

Going back to line 3030, the second number sets NP = 4, and the next eight numbers set the four pair of X, Y values into the X(), Y() arrays. The final zero ends the DATA sequence for that line.

The next area data on line 3040 has a similar format, but it draws us a blue ocean with the fill data at line 2020. The area data at line 3050 is interesting. We can see that it has exactly the same numbers as the ocean area data, except for its first FILL number of 9. It is covering exactly the same screen area as the "ocean" data, but this data will provide a watery looking reflection effect. FILL DATA number 9 is called "receding bars." It has TYPE = 2 for Pixel Painting. Thus, the next two numbers must define PB = 1 and PC = -1. The value of PB = 1 specifies that there will be an uneven pixel-on probability across the polygon, and that PC must be used to specify it. The value of PC = -1 specifies that the initial line will be drawn with all pixels on, the final line will be drawn with all pixels off, and that the pixel proportion will vary evenly in between. An RA = 100 specifies horizontal lines, a P(0) = 0 specifies no parity check, and the remaining lines specify the number of spaces.

This example is interesting for a number of reasons. First, unlike the other cases, the line spacing sequence is non-repetitive. Second, the optical effect of distance is achieved in two ways: the changing line spacing, and the changing pixel-on proportions.

The next three area data statements are interesting because they all work the same screen area, but with a different FILL specification. First, line 3060 calls for FILL = 0, which is the fill data at line 2000. This data is called the "horizontal eraser." The first value at line 2000 specifies TYPE = 7, RA = 0, which turns COLOR off. Then a 99 continue leads to TYPE = 1 Bar Painting, RA = 100 horizontal lines, P(0) = 0, P(1) = 1, P(2) = 0 for no parity check, lines drawn immediately adjacent with no spaces in between. Another 99 to continue, and then TYPE = 7, RA = 1 to reset the COLOR register for further painting.

Unlike the lower resolution modes where we can simply over-plot previously-colored pixels with new pixels colored differently, in Mode 8 graphics all the previously colored pixels must be turned off if we want to insert a specific color pattern.

Line 3070 then inserts the primary color-texture pattern for this area, and line 3080 then adds, on top of it, some additional random texturizing effect to eliminate a flat repetitiveness.

The full power of Mode 8 hi-resolution graphics is called for in lines 3180 to 3220. Lines 3180 and 3190 draw the small sailboat, where the Mode 8 pixel size is needed to provide the proper proportions for this small image.

Then line 3200 turns the color register off with a -7, 0 command. The 99 continue then leads to a value of -4, which specifies a direct TYPE = 4 command to just PLOT individual X, Y pixel coordinates. An NP = 10 specifies the 10 X, Y coordinate pairs to be PLOTted in the boat, to represent the two individuals. Then on line 3210 the COLOR register is turned back on.

The boat wake is drawn with line 3220 data which again turns the COLOR off with the -7, 0 data values. The 99 continue leads to a -5 for a direct TYPE = 5 command to just PLOT-DRAWTO lines, and the NP = 8 value specifies the eight X, Y pairs to draw the four lines.

Of course, the mountain itself is the biggest surprise. But I won't spoil it for you by describing it here. Run it and see for yourself. With the previously analyzed sections as background, you should be able to decipher the DATA code for these last elements with little difficulty.

There are quite a few game programs for sale that advertise the use of high resolution graphics with much enthusiasm. These include adventure programs, space programs, and utility programs. Often these are advertised in the magazines, with multi-colored dramatic pictures. However, when we actually see how they use Mode 8 to illustrate their programs, it usually doesn't even come close to the dramatic pictures in the advertisements. If you have run this program and seen this sample picture, then you know the programs presented here can be used to close that gap between the drama of the advertising illustrations and the drama of the program illustrations.

It may be of interest to note that Paul Twitchell's book, *The Tiger's Fang*, was a most appropriate source of inspiration to demonstrate these dramatic graphic techniques. This book is the story of one of the greatest adventures of all time.

One very useful TYPE option which was not demonstrated in this example picture is the case where TYPE = 3, to just draw the boundary of an area. This option can be used in the initial picture development phase to outline the area boundaries.

Naturally, we will start creating our overall picture on a grid paper, with the screen coordinates marked off on the horizontal and vertical edges. We sketch out our picture and then outline our major areas with a straightedge and note the X, Y vertex coordinates of the perimeters. High-resolution details must be "blown up" on another sheet of grid paper so we can see each individual pixel of their form.

Once we have a good layout for our picture geometry, then we can start constructing our AREA DATA statements after line 3000, in line increments of 10. If we specify the first numeric value to be -3, then we will see what our geometric outlines look like on the screen without using any fill DATA statements.

You can see what this looks like by changing the first numeric value to -3 in all the DATA statements from line 3030 to 3190 in the PICTUR8 program.

You are now on your own to use these programs or modify them as you see fit.

**PROGRAM 1. Multi-Colored Graphics In Mode 8.**

```
18000 REM ===========================
```

18005 REM = {4 SPACES} POLY8 Subroutine {5 SPACES} =

18010 REM = Polygon Painting For {3 SPACES} =

18015 REM = BASIC Graphics Mode 8 =

18020 REM ===========================

18023 REM = {10 SPACES} by; {12 SPACES} =

18024 REM = {7 SPACES} Phil Dunn {9 SPACES} =

18025 REM = {5 SPACES} 12 Monroe Ave. {6 SPACES} =

18026 REM = Hicksville, NY 11801 {3 SPACES} =

18030 REM ===========================

18035 REM Enter with the value for

18040 REM TYPE = Type of Painting

18045 REM " {3 SPACES} = 1 for Bar Painting

18050 REM " {3 SPACES} = 2 for Pixel Painting

18053 REM " {3 SPACES} = 3 for a Line Boundary

18055 REM " {3 SPACES} = 4 to PLOT X(i), Y(i)

18057 REM " {3 SPACES} = 5 TO PLOT X(i), Y(i),

18058 REM . and DRAWTO X(i + 1), Y(i + 1)

18060 REM " {3 SPACES} = 6 to DRAWTO X(i), Y(i)

18065 REM " {3 SPACES} = 7 to COLOR RA

18070 REM ...........................

18075 REM For TYPE = 1 to 6,

18080 REM enter with the values . . .

18085 REM NP = No. of Vertex Points.

18087 REM . for i = 1 to NP :

18090 REM X(i) = DIM Vertex X values

18095 REM Y(i) = DIM Vertex Y values

18100 REM ...........................

18105 REM For TYPE 1 and 2 Painting

18110 REM also enter values for . . .

18115 REM RA = Angle X/Y Ratio

18120 REM " = 0 for Vertical

18125 REM " = + -1 for + -45 degrees

18130 REM " = 100 for Horizontal

18135 REM P() = DIM array for spacing

18140 REM .Parity Color-Lock Option:

18145 REM .P(0) = 0 for no parity

18150 REM .P(0) = 1 for odd parity

18155 REM .P(0) = 2 for even parity

18160 REM .for i = 1 to something:

18165 REM .ABS(P(i)) = Spaces to move

18170 REM .SGN(P(i)) = +1, no parity

18175 REM .SGN(P(i)) = -1, parity lock

18180 REM .{4 SPACES}P(i) = 0 to end data

18185 REM ............................

18190 REM For TYPE 2 Pixel Painting

18195 REM also enter values for . . .

18200 REM PB & PC For Pixel Blending

18205 REM * Set PB < 1 for an even

18210 REM . blend of active and

18215 REM . inactive pixels.

18220 REM . PB = the proportion of

18225 REM . active pixels. PB > 0

18230 REM * Set PB >= 1 for an uneven

18235 REM . blend across the area.

18240 REM . area. Then . . .

18245 REM . If PC > 0 then the start

18250 REM . {4 SPACES} color is inactive and

18255 REM . {4 SPACES} the end is active.

18260 REM . If PC < 0 then the start

18265 REM . {4 SPACES} color is active and

18270 REM . {4 SPACES} the end is inactive.

18275 REM . When ABS(PC) = 1 then the

18280 REM . {4 SPACES} start color phases out

18285 REM . {4 SPACES} evenly to the end.

18290 REM . When ABS(PC) > 1 then the

18295 REM . {4 SPACES} start color phases out

18300 REM . {4 SPACES} more slowly.

18305 REM . When ABS(PC) < 1 then the

18310 REM . {4 SPACES} start color phases out

18315 REM . {4 SPACES} more rapidly.

18320 REM ...........................

18325 REM For TYPE = 7, to COLOR RA,

18330 REM enter with RA = 0 or 1

18335 REM ...........................

18340 REM S() = DIM array used here

18345 REM T() = DIM array used here

18350 REM U() = DIM array used here

18355 REM V() = DIM array used here

18360 REM Variable names used . . .

18365 REM C0, C1, C2, Z3, Z4, Z5, Z9,

18370 REM X1, Y1, X2, Y2, CA, SA

18375 REM K, L, M, N, IM, IP, MAX, MIN, NOW

18380 REM ===========================

18400 C0 = 0 : C1 = 1 : C2 = 2 : Z9 = 999

18405 IF TYPE = 3 THEN PLOT X(C1), Y(C1) : FOR N = C2 TO NP : DRAWTO X(N), Y(N) : NEXT N : DRAWTO X(C1), Y(C1) : RETURN

18410 IF TYPE = 4 THEN FOR N = C1 TO NP : PLOT X(N), Y(N) : NEXT N : RETURN

18415 IF TYPE = 5 THEN FOR N = C1 TO NP STEP C2 : PLOT X(N), Y(N) : DRAWTO X(N + C1), Y(N + C1) : NEXT N : RETURN

18420 IF TYPE = 6 THEN FOR N = C1 TO NP : DRAWTO X(N), Y(N) : NEXT N : RETURN

18425 IF TYPE = 7 THEN COLOR RA : RETURN

18430 Z5 = 0.5 : IF RA = C2 THEN Z5 = 0.55

18435 IF RA = -C2 THEN Z5 = 0.18

18440 Z3 = -C1 : IF RA< >C0 THEN Z3 = SGN(RA)

18445 SA = SQR(1/(1 + RA^C2)) * Z3 : IF ABS(SA) < 0.2 THEN SA = C0

18450 CA = SQR(1 - SA^C2)

18455 REM Rotate X(), Y() to U(), V() :

18460 FOR M = C1 TO NP

18465 U(M) = X(M) * CA + Y(M) * SA

18470 V(M) = -X(M) * SA + Y(M) * CA : NEXT M

18480 FOR M = C1 TO NP : N = M + C1 : IF N > NP THEN N = C1

18485 REM Calculate slopes S() and Y axis intercepts T()

18490 IF U(M) = U(N) THEN S(M) = Z9 : GOTO 18510

18495 S(M) = (V(N) - V(M))/(U(N) - U(M)) : T(M) = V(M) - S(M) * U(M)

18500 IF ABS(S(M)) > Z9 THEN S(M) = Z9

18505 IF ABS(S(M)) < C1/Z9 THEN S(M) = C0

18510 NEXT M : MAX = -Z9 : MIN = Z9 : FOR M = C1 TO NP : Z3 = V(M)

18515 IF MAX < Z3' THEN MAX = Z3

18520 IF MIN > Z3 THEN MIN = Z3 : N = M

18525 NEXT M : MXMN = MAX - MIN : NOW = MIN : IM = N - C1 : IF IM < C1 THEN IM = NP

18527 IP = N + C1 : IF IP > NP THEN IP = C1

18530 IF P(C1) = C0 THEN P(C1) = C1 : P(C2) = C0

18535 M = C1 : IF P(M) < C0 THEN M = C1

18540 GOTO 18675

18545 REM Calculate intercepts . . .

18550 IF S(N) = Z9 OR S(N) = C0 THEN Z3 = U(N) : GOTO 18560

18555 Z3 = (NOW - T(N))/S(N)

18560 IF S(IM) = Z9 OR S(IM) = C0 THEM Z4 = U(IM) : GOTO 18575

18565 Z4 = (NOW - T(IM))/S(IM)

18570 REM Rotate U(), V() to X(), Y() :

18575 X1 = INT(Z3 * CA - NOW * SA + Z5)

18580 IF NOW< >MIN AND P(M) >= C0 THEN 18595

18585 IF P(C0) = C1 THEN IF X1 = C2 * INT(X1/C2) THEN X1 = X1 + C1

18590 IF P(C0) = C2 THEN IF X1< >C2 * INT(X1/C2) THEN X1 = X1 + C1

18595 Y1 = INT(Z3 * SA + NOW * CA + Z5)

18600 Y2 = INT(Z4 * SA + NOW * CA + Z5)

18605 IF SA = C0 THEN X2 = Z4 * CA

18610 IF SA< >C0 THEN X2 = X1 + (Y2 - Y1) * RA

18615 REM Bar Painting ...............

18620 IF TYPE = 1 THEN PLOT X1, Y1 : DRAWTO X2, Y2 : GOTO 18660

18635 REM Pixel Painting............

18643 IF PB < C1 THEN PR = PB : GOTO 18650

18645 PR = ((NOW - MIN)/MXMN)^ABS(PC) : IF PC < C0 THEN PR = C1 - PR

18650 GOSUB LINEP

18655 REM ...........................

18660 NOW = Y1 * CA - X1 * SA

18665 REM Increment NOW for next bar

18670 NOW = NOW + ABS(P(M)) : M = M + C1 : IF P(M) = C0 THEN M = C1

18675 IF NOW < V(IP) THEN 18690

18680 IF V(IP) = MAX THEN RETURN

18685 N = IP : IP = IP + C1 : IF IP > NP THEN IP = C1

18690 IF NOW < V(IM) THEN GOTO 18550

18695 IF V(IM) = MAX THEN RETURN

18700 IM = IM - C1 : IF IM < C1 THEN IM = NP

18705 GOTO 18550

18710 REM ===========================

**PROGRAM 2. Multi-Colored Graphics In Mode 8.**

```
18750 REM LINEP Subroutine
```

18751 REM by. . . Phil Dunn

18755 REM Draws a line pixel by pixel

18760 REM With a probability to plot

18765 REM or skip each pixel.

18770 REM X1, Y1 = start point

18775 REM X2, Y2 = end point

18780 REM PR = probability to PLOT

18785 REM " >= 0 and <= 1

18790 C0 = 0 : C1 = 1 : C255 = 255 : C230 = 230 : C198 = 198

18795 C92 = 92 : C97 = 97 : C103 = 103 : C106 = 106 : C120 = 120

18800 K = X2 - X1 : L = Y2 - Y1 : Z3 = ABS(K) : Z4 = ABS(L) : BI = PR * C255

18805 IF K = C0 AND L = C0 THEN RETURN

18810 IF K < C0 THEN 18840

18815 LINE$(C92, C92) = CHR$(C230) : REM INC

18820 LINE$(C97, C97) = CHR$(C0)

18825 LINE$(C103, C103) = CHR$(C1)

18830 LINE$(C106, C106) = CHR$(C230)

18835 GOTO 18860

18840 LINE$(C92, C92) = CHR$(C198) : REM DEC

18845 LINE$(C97, C97) = CHR$(C255)

18850 LINE$(C103, C103) = CHR$(C0)

18855 LINE$(C106, C106) = CHR$(C198)

18860 LINE$(C120, C120) = CHR$(C230) : IF L < C0 THEN LINE$(C120, C120) = CHR$(C198)

18865 IF Z3 = C0 THEN Z3 = C1/C255

18870 IF Z4 = C0 THEN Z4 = C1/C255

18875 IF Z3 > Z4 THEN K = Z3 : Y2 = Z3/Z4 : X2 = 1 : IF Y2 > C255 THEN Y2 = C255

18880 IF Z3 < Z4 THEN K = Z4 : X2 = Z4/Z3 : Y2 = 1 : IF X2 > C255 THEN X2 = C255

18883 IF K < 1 THEN RETURN

18884 POKE 752, C1

18885 L = USR(ADR(LINE$), K, X1, Y1, X2, Y2, BI)

18890 RETURN

18895 REM ...........................

18900 DIM LINE$(136) : RESTORE 18910 : LINEP = 18790

18905 FOR K = 1 TO 136 : READ L : LINE$(K, K) = CHR$(L) : NEXT K : RETURN

18910 DATA 104, 104, 133, 211, 104, 133, 210, 104, 133, 86

18915 DATA 104, 133, 85, 104, 104, 133, 84, 104, 104, 133

18920 DATA 209, 170, 104, 104, 133, 208, 168, 104, 104, 133

18925 DATA 207, 173, 10, 210, 24, 101, 207, 144, 46, 138

18930 DATA 72, 152, 72, 165, 86, 72, 165, 85, 72, 165

18935 DATA 84, 72, 162, 96, 169, 11, 157, 66, 3, 169

18940 DATA 0, 157, 72, 3, 157, 73, 3, 169, 1, 32

18945 DATA 86, 228, 104, 133, 84, 104, 133, 85, 104, 133

18950 DATA 86, 104, 168, 104, 170, 202, 208, 19, 165, 209

18955 DATA 170, 230, 85, 165, 85, 201, 0, 208, 8, 165

18960 DATA 86, 201, 1, 240, 30, 230, 86, 169, 255, 197

18965 DATA 208, 240, 8, 136, 208, 5, 165, 208, 168, 230

18970 DATA 84, 198, 210, 208, 162, 169, 0, 197, 211, 240

18975 DATA 4, 198, 211, 240, 152, 96

**PROGRAM 3. Multi-Colored Graphics In Mode 8.**

```
0100 * = $5000
```

0110 ;A = USR(LOC, N, X, Y, NX, NY, BI)

0120 ;DRAWS A LINE WITH EACH PIXEL

0130 ;PROBABILITY-TESTED TO BE

0140 ;ILLUMINATED OR NOT

0150 ;

0160 NH = $D3 ;NO.POINTS-HI BYTE

0170 NL = $D2 ;NO.POINTS-LO BYTE

0180 XH = $56 ;CURSOR X -HI BYTE

0190 XL = $55 ;CURSOR X -LO BYTE

0200 Y = $54 ;CURSOR Y

0210 NX = $D1 ;X COUNT

0220 NY = $D0 ;Y COUNT

0230 BI = $CF ;PROB. BIAS

0240 RANDOM = $D20A; RANDOM # = 0 - 255

0250 CIO = $E456 ;CENTRAL I/O

0260 ICCOM = $342 ;IoCb COMmand to CIO

0270 ICBLEN = $348 ;IoCb Buffer LENgth

0280 CPBINR = $B ;Comnd.Put BINary Rec.

0290 ;

0300 PLA ;CLEAR STACK

0310 PLA

0320 STA NH ;N - HIGH BYTE

0330 PLA

0340 STA NL ;N - LOW BYTE

0350 PLA

0360 STA XH ;X - HIGH BYTE

0370 PLA

0380 STA XL ;X - LOW BYTE

0390 PLA

0400 PLA

0410 STA Y ;Y - LOW BYTE

0420 PLA

0430 PLA

0440 STA NX ;X COUNTER

0450 TAX ;TEMP X COUNTER

0460 PLA

0470 PLA

0480 STA NY ;Y COUNTER

0490 TAY ;TEMP Y COUNTER

0500 PLA

0510 PLA

0520 STA BI ;PROB. BIAS

0530 ;

0540 LOOP LDA RANDOM

0550 CLC ;CLEAR CARRY

0560 ADC BI ;ADD BIAS W. CARRY

0570 BCC DOX ;BYP. IF CARRY NOTSET

0580 TXA

0590 PHA ;SAVE TEMP X

0600 TYA

0610 PHA ;SAVE TEMP Y

0620 LDA XH

0630 PHA ;SAVE CURSOR XH

0640 LDA XL

0650 PHA ;SAVE CURSOR XL

0660 LDA Y

0670 PHA ;SAVE CURSOR Y

0680 LDX #6 * $10 ;OFFSET TO IOCB#6

0690 LDA #CPBINR;Comd.Put BINary Rec

0700 STA ICCOM, X

0710 LDA #0

0720 STA ICBLEN, X

0730 STA ICBLEN + 1, X

0740 LDA #1 ;COLOR Reg.#

0750 JSR CIO ;Use CIO to PLOT

0760 PLA

0770 STA Y ;CLAIM CURSOR Y

0780 PLA

0790 STA XL ;CLAIM CURSOR XL

0800 PLA

0810 STA XH ;CLAIM CURSOR XH

0820 PLA

0830 TAY ;CLAIM TEMP Y

0840 PLA

0850 TAX ;CLAIM TEMP X

0860 ;

0870 DOX DEX ;DECR. TEMP. X

0880 BNE DOY ;BYP. & DO Y IF< >O

0890 LDA NX

0900 TAX ;RESET TEMP. X

0910 INC XL ;INCR. CURSOR X LOC

0920 LDA XL ;LOAD ACCUM. W. XL

0930 CMP #$00 ;COMPARE WITH O

0940 BNE DOY ;BYP. IF NOT SAME

0950 LDA XH

0960 CMP #$01 ;IS HI BYTE = 1?

0970 BEQ RTS ;IF IT IS, RETURN

0980 INC XH ;INC. HI BYTE

0990 ;

1000 DOY LDA #$FF

1010 CMP NY ;COMPARE NY WITH 255

1020 BEQ COUN ;BYP.IF = O(HOR.LINE)

1030 DEY ;DEC.TEMP Y

1040 BNE COUN ;BYP.& DO COUN IF< >O

1050 LDA NY

1060 TAY ;RESET TEMP. Y

1070 INC Y ;SHIFT CURSOR Y LOC

1080 ;

1090 COUN DEC NL ;COUNT PIXEL NO.

1100 BNE LOOP ;KEEP PLOTTING IF< >O

1110 LDA #$00

1120 CMP NH ;IS NH ZERO?

1130 BEQ RTS ;IF IT IS, RETURN

1140 DEC NH ;DECREMENT NH

1150 BEQ LOOP ; & LOOP

1160 RTS RTS ;RETURN

1170 .END

**PROGRAM 4. Multi-Colored Graphics In Mode 8.**

```
100 GRAPHICS 0
```

110 ? " ============================= "

120 ? " = {9 SPACES} PALETT8 {11 SPACES} = "

130 ? " = {5 SPACES} A Color-Texture {7 SPACES} = "

140 ? " = {3 SPACES} Development Program {4 SPACES} = "

150 ? " = For The POLYS Subroutine = "

160 ? " ============================= "

170 REM = {11 SPACES} by: {13 SPACES} =

180 REM = {8 SPACES} Phil Dunn {10 SPACES} =

190 REM = {6 SPACES} 12 Monroe Ave. {7 SPACES} =

200 REM = {3 SPACES} Hicksville, NY 11801 {4 SPACES} =

210 REM =============================

270 C0 = 0 : C1 = 1 : C2 = 2 : C3 = 3 : C4 = 4 : C5 = 5 : C6 = 6 : C7 = 7 : C8 = 8 : C9 = 9 : C10 = 10

275 C99 = 99 : AREA = 1050 : NP = C4 : POLY8 = 18400 : DETRA P = 40000

280 DIM X(C4), Y(C4), P(C10), S(C4), T(C4), U(C4), V(C4), C0(C3), LU(C3)

284 ? : ? : ? : ? "{4 SPACES} Reading data . . ."

285 GOSUB 18900 : REM SETUP LINEP SUB.

290 REM =============================

295 ? : ? : ? "GRAPHICS MODE (6 to 8) = ";

300 TRAP 295 : INPUT MODE : TRAP DETRAP

305 IF MODE < C6 OR MODE > C8 THEN 295

310 GRAPHICS MODE

315 IF MODE = C6 OR MODE = C7 THEN E = 0.49 : F = 0.49

320 IF MODE = C8 THEN E = C1 : F = C1

330 REM ============================

360 REM Initial color assignment . . .

370 C0(C0) = C0 : LU(C0) = C0

380 C0(C1) = C2 : LU(C1) = C8

390 C0(C2) = 12 : LU(C2) = C10

400 C0(C3) = C9 : LU(C3) = C4

410 IF MODE< >C8 THEN 500

420 C0(C0) = C0 : LU(C0) = C0

430 C0(C1) = C0 : LU(C1) = C0

440 C0(C2) = C0 : LU(C2) = 12

450 C0(C3) = C0 : LU(C3) = C0

460 SETCOLOR C0, C0(C1), LU(C1)

470 SETCOLOR C1, C0(C2), LU(C2) : REM GRAPHC

480 SETCOLOR C2, C0(C3), LU(C3) : REM BACKGR

490 SETCOLOR C4, C0(C0), LU(C0) : REM BORDER

500 COLOR C1

510 REM .............................

520 REM DATA for area numbers:

530 REM -1 = PLOT

540 REM -2 = DRAWTO

550 REM -9 = end of data

560 REM One number per DATA statement

570 DATA -1, 5, 20, -2, 5, 40

580 DATA -1, 65, 20, -2, 70, 20, -2, 65, 40, -2, 70, 40

590 DATA -1, 130, 20, -2, 135, 20, -2, 135, 40, -2, 130, 40, -1, 130, 30, -2, 135, 30

600 DATA -1, 200, 40, -2, 200, 20, -2, 195, 30, -2, 202, 30

610 DATA -1, 265, 20, -2, 260, 20, -2, 260, 30, -2, 265, 30, -2, 265, 40, -2, 260, 40

620 DATA -1, 2, 70, -2, 2, 90, -2, 7, 90, -2, 7, 80, -2, 2, 80

630 DATA -1, 65, 70, -2, 70, 70, -2, 65, 90

640 DATA -1, 130, 70, -2, 135, 70, -2, 130, 90, -2, 135, 90, -2, 130, 70

650 DATA -1, 200, 90, -2, 200, 70, -2, 195, 70, -2, 195, 80, -2, 200, 80

660 DATA -1, 259, 70, -2, 259, 90, -1, 263, 70, -2, 263, 90, -2, 267, 90, -2, 267, 70, -2, 263, 70

670 DATA -1, 3, 120, -2, 3, 140, -1, 7, 120, -2, 7, 140

680 DATA -1, 64, 120, -2, 64, 140, -1, 67, 120, -2, 72, 120, -2, 67, 140, -2, 72, 140

690 DATA -1, 129, 120, -2, 129, 140, -1, 132, 120, -2, 137, 120, -2, 137, 140, -2, 132, 140, -1, 132, 130, -2, 137, 130

700 DATA -1, 194, 120, -2, 194, 140, -1, 200, 140, -2, 200, 120, -2, 197, 130, -2, 202, 130

710 DATA -1, 259, 120, -2, 259, 140, -1, 267, 120, -2, 263, 120, -2, 263, 130, -2, 267, 130, -2, 267, 140, -2, 263, 140

720 DATA -9, -9, -9

730 REM .............................

740 REM Read DATA and draw numbers

745 RESTORE 570

750 READ I, X, Y

760 IF I = -C1 THEN PLOT X * E, Y * E

770 IF I = -C2 THEN DRAWTO X * E, Y * F

780 IF I< >-C9 THEN 750

790 REM ..............................

800 REM DATA for areas: XL, YL, XU, YU

810 DATA 10, 45, 60, 2

820 DATA 75, 45, 125, 2

830 DATA 140, 45, 190, 2

840 DATA 205, 45, 255, 2

850 DATA 270, 45, 317, 2

860 DATA 10, 95, 60, 50

870 DATA 75, 95, 125, 50

880 DATA 140, 95, 190, 50

890 DATA 205, 95, 255, 50

900 DATA 270, 95, 317, 50

910 DATA 10, 145, 60, 100

920 DATA 75, 145, 125, 100

930 DATA 140, 145, 190, 100

940 DATA 205, 145, 255, 100

950 DATA 270, 145, 317, 100

960 REM .............................

970 REM ========================

980 REM = NOTE: To RESET the =

990 REM = {3 SPACES} input sequence {5 SPACES} =

1000 REM = back to the "AREA" =

1010 REM = {6 SPACES} request {9 SPACES} =

1020 REM = RETURN the value 99 =

1030 REM = {3 SPACES} to any question {4 SPACES} =

1040 REM ========================

1050 ? : ? : ? "Which AREA (0 - 15)";

1060 TRAP AREA : INPUT A : TRAP DETRAP

1070 IF A < CO OR A > 15 THEN GOTO AREA

1080 IF A = CO THEN 1660

1090 RESTORE 800 + A * C10

1100 READ XL, YL, XU, YU

1110 X(C1) = XL * E : Y(C1) = YL * F

1120 X(C2) = XL * E : Y(C2) = YU * F

1130 X(C3) = XU * E : Y(C3) = YU * F

1140 X(C4) = XU * E : Y(C4) = YL * F

1150 REM ..........................

1160 ? "CREATE, or PRESET (1 or 2)";

1170 TRAP 1160 : INPUT I : TRAP DETRAP

1180 IF I = C99 THEN GOTO AREA

1190 IF I = C2 THEN 1900

1200 IF I< >C1 THEN 1160

1210 REM ..........................

1220 ? "Which TYPE of Painting;"

1230 ? "1 = Bar, 2 = Pixel, 7 = COLOR";

1240 TRAP 1220 : INPUT TYPE : TRAP DETRAP

1250 IF TYPE = C99 THEN GOTO AREA

1260 IF TYPE = C7 THEN 1600

1270 IF TYPE = C1 THEN 1410

1280 IF TYPE< >C2 THEN 1220

1290 REM ==========================

1300 ? "For Pixel Painting,"

1310 ? "What value for PB, (0 - 1)";

1320 TRAP 1310 : INPUT PB : TRAP DETRAP

1330 IF PB = C99 THEN GOTO AREA

1340 IF PB < C0 OR PB > C1 THEN 1310

1350 IF PB < C1 THEN 1420

1360 ? "What value for PC";

1370 TRAP 1360 : INPUT PC : TRAP DETRAP

1380 IF PC = C99 THEN GOTO AREA

1390 GOTO 1420

1400 REM ===========================

1410 ? "For Bar Painting,"

1420 ? "What Angle X/Y Ratio";

1430 TRAP 1420 : INPUT RA : TRAP DETRAP

1440 IF RA = C99 THEN GOTO AREA

1450 REM ............................

1460 ? "P(0) Parity value (0 - 2) = ";

1470 TRAP 1460 : INPUT P : TRAP DETRAP

1480 P(C0) = P : IF P < C0 OR P > C2 THEN 1460

1490 IF P = C99 THEN GOTO AREA

1500 REM ............................

1510 I = 1

1520 ? "What value for P(";I;") (0 = end)";

1530 TRAP 1520 : INPUT P : TRAP DETRAP

1540 P(I) = P : IF P = C99 THEN GOTO AREA

1550 IF I = C1 AND P = C0 THEN 1520

1560 IF P = C0 THEN 1580

1570 I = I + C1 : GOTO 1520

1580 GOSUB POLYB : GOTO AREA

1590 REM ============================

1600 ? "What COLOR (MODE 8 : 1 = on, 0 = off)";

1610 TRAP 1600 : INPUT RA : TRAP DETRAP

1620 IF RA = C99 THEN GOTO AREA

1630 GOTO 1580

1640 REM ============================

1650 REM REDEFINE THE COLORS. . .

1660 ? "Reg.No. = Hue, Luminance"

1670 ? "O = ";C0(C0); ",";LU(C0), "1 = ";C0(C1); ", "; LU(C1), "2 = ";C0(C2); ",";LU(C2), "3 = ";C0(C3); ",";LU(C3)

1680 ? "Which COLOR Register (0 - 3) ";

1690 TRAP 1660 : INPUT I : TRAP DETRAP

1700 IF I = C99 THEN GOTO AREA

1710 IF I < C0 OR I > C3 THEN 1660

1720 K = CO(I) : L = LU(I) : GOTO 1760

1730 IF STRIG(C0) = C0 THEN 1660

1740 IF CO(I) = INT(K) AND LU(I) = C2 * INT(L/C2) THEN 1800

1750 CO(I) = INT(K) : LU(I) = C2 * INT(L/C2)

1760 ? "Reg. ";I;" = Color ";CO(I); ", Luminance ";LU(I)

1770 J = I - C1 : IF J < C0 THEN J = C4

1780 SETCOLOR J, C0(I), LU(I)

1790 CO(I) = INT(K) : LU(I) = C2 * INT(L/C2)

1800 IF STICK(C0) = C7 THEN K = K + C1/C10 : IF K > 16 THEN K = C0

1810 IF STICK(C0) = 11 THEN K = K - C1/C10 : IF K < C0 THEN K = 15

1820 IF STICK(C0) = 14 THEN L = L + C2/C10 : IF L > 16 THEN L = C0

1830 IF STICK(C0) = 13 THEN L = L - C2/C10 : IF L < C0 THEN L = 14

1840 REM Joystick 0 controls :

1850 REM Left-Rignt changes hue

1860 REM Foward-Back changes luminance

1870 REM Press Trigger to fix selection

1880 GOTO 1730

1890 REM ============================

1900 ? "Which PRESET Number";

1910 TRAP 1900 : INPUT I : TRAP DETRAP

1920 IF I = C99 THEN GOTO AREA

1930 IF I < C0 OR I > 66 THEN 1900

1950 RESTORE 2070 + I * C10

1960 READ TYPE

1970 IF TYPE = C7 THEN READ P : COLOR P : GOTO 2040

1980 IF TYPE = C2 THEN READ PB, PC

1990 READ RA, P0, P

2000 P(C0) = P0 : P(C1) = P : I = C2

2010 READ P : P(I) = P

2020 IF P = C0 THEN GOSUB PoLY8 : GOTO 2040

2030 I = I + C1 : GOTO 2010

2040 READ P : IF P = C99 THEN 1960

2050 GOTO AREA

2060 REM PRESET DATA .................

2065 REM Color lables are accurate

2066 REM only for the CTIA chip, and

2067 REM are not correct for the GTIA

2070 DATA 7, 0, 99, 1, 0, 0, 1, 0, 99, 7, 1, 0, ERASER = 0

2080 DATA 1, 0, 0, 1, 0, 0, WHT = 1

2090 DATA 1, 0, 1, -2, 0, 0, BLU = 2

2100 DATA 1, 0, 2, -2, 0, 0, BRN = 3

2110 DATA 1, 0, 0, 3, 0, 0, DARK BRN VRT = 4

2120 DATA 1, 0, 0, 1, 2, 0, 0, GRN&ORG VRT = 5

2130 DATA 1, 0, 1, -1, 3, 0, 0, GRN VRT = 6

2140 DATA 1, 0, 2, -1, 3, 0, 0, RED VRT = 7

2150 DATA 1, 1, 0, 2, 0, 0, DK GRY = 8

2160 DATA 1, 1, 0, 3, 0, 0, DK GRY DIA = 9

2170 DATA 1, 2, 1, -2, 0, 0, GRN = 10

2180 DATA 1, 2, 2, -2, 0, 0, RED = 11

2190 DATA 1, 2, 1, -1, -2, 0, 0, LT GRN DIA = 12

2200 DATA 1, 2, 2, -1, -2, 0, 0, PNK DIA = 13

2210 DATA 1, 2, 1, -2, -3, 0, 0, GRN DIA = 14

2220 DATA 1, 2, 2, -2, -3, 0, 0, RED DIA = 15

2230 DATA 1, 3, 0, 2, 0, 0, NBY GRY = 16

2240 DATA 1, 3, 0, 1, 2, 0, 0, GRY DIA = 17

2250 DATA 1, 4, 1, -2, 0, 0, NBY RED = 18

2260 DATA 1, 4, 2, -2, 0, 0, NBY BLU = 19

2270 DATA 1, 4, 1, -1, -2, 0, 0, PNK DIA = 20

2280 DATA 1, 4, 2, -1, -2, 0, 0, GRN DIA = 21

2290 DATA 1, 0, 1, -2, 0, 99, 1, 1, 0, 2, 0, 0, PNK-GRY DIA = 22

2300 DATA 1, 0, 2, -2, 0, 99, 1, 1, 0, 2, 0, 0, GRN-GRY DIA = 23

2310 DATA 1, 0, 1, -2, 0, 99, 1, 1, 0, 3, 0, 0, NBY BLU-GRY = 24

2320 DATA 1, 0, 2, -2, 0, 99, 1, 1, 0, 3, 0, 0, NBY GRN-GRY = 25

2330 DATA 1, 0, 2, -2, 0, 99, 1, 2, 1, -2, 0, 0, PNK-GRY = 26

2340 DATA 1, 0, 1, -2, 0, 99, 1, 2, 2, -2, 0, 0, BLU-GRY = 27

2350 DATA 1, 0, 1, -2, 0, 99, 1, 2, 2, -1, -2, 0, 0, PNK-GRY DIA = 28

2360 DATA 1, 0, 2, -2, 0, 99, 1, 2, 2, -1, -2, 0, 0, BLU-GRY DIA = 29

2370 DATA 1, 0, 1, -2, 0, 99, 1, 3, 1, 2, 0, 0, BLU-GRY COR = 30

2380 DATA 1, 0, 2, -2, 0, 99, 1, 3, 1, 2, 0, 0, GRN-GRY COR = 31

2390 DATA 1, 0, 1, -2, 0, 99, 1, 4, 2, -2, 0, 0, NUB PNK = 32

2400 DATA 1, 0, 2, -2, 0, 99, 1, 4, 1, -2, 0, 0, NUB GRN = 33

2410 DATA 1, 1, 0, 2, 0, 99, 1, -1, 0, 2, 0, 0, GRN PLAI D = 34

2420 DATA 1, 1, 0, 2, 0, 99, 1, 1, 0, 3, 0, 0, BRN DIA = 35

2430 DATA 1, 1, 0, 2, 0, 99, 1, -1, 0, 3, 0, 0, RED-GRN-BLU DIA = 36

2440 DATA 1, 1, 1, 3, 0, 99, 1, -1, 1, 3, 0, 0, BLU CHKS = 37

2450 DATA 1, 1, 2, 3, 0, 99, 1, -1, 1, 3, 0, 0, RED CHKS = 38

2460 DATA 1, 1, 0, 2, 0, 99, 1, -2, 1, -2, 0, 0, GR/RED DIA = 39

2470 DATA 1, 1, 0, 2, 0, 99, 1, -2, 2, -2, 0, 0, RED/GRN DIA = 40

2480 DATA 1, 1, 0, 3, 0, 99, 1, -2, 1, -2, 0, 0, GRN GRI D = 41

2490 DATA 1, 1, 0, 3, 0, 99, 1, -2, 2, -2, 0, 0, RED GRI D = 42

2500 DATA 1, 1, 0, 2, 0, 99, 1, -2, 1, -1, -2, 0, 0, GRY DIA = 43

2510 DATA 1, 1, 0, 3, 0, 99, 1, -2, 1, -1, -2, 0, 0, GRN KNIT = 44

2520 DATA 1, 1, 0, 3, 0, 99, 1, -2, 2, -1, -2, 0, 0, PNK KNIT = 45

2530 DATA 1, 1, 0, 2, 0, 99, 1, -3, 0, 2, 0, 0, BLU-RED HOR = 46

2540 DATA 1, 1, 0, 2, 0, 99, 1, 3, 0, 1, 2, 0, 0, BLU-RED VRT = 47

2550 DATA 1, 1, 0, 3, 0, 99, 1, 3, 0, 2, 0, 0, PNK-BLU DIAM = 48

2560 DATA 1, 1, 0, 3, 0, 99, 1, 3, 0, 1, 2, 0, 0, PNK-BLU DIAG = 49

2570 DATA 1, 1, 0, 2, 0, 99, 1, 4, 1, -2, 0, 0, = NBY RED DIAG = 50

2580 DATA 1, 1, 0, 2, 0, 99, 1, 4, 2, -2, 0, 0, = NBY GRN DIAG = 51

2590 DATA 1, 2, 1, -2, 0, 99, 1, -2, 2, -2, 0, 0, GRY = 52

2600 DATA 1, 2, 1, -2, 0, 99, 1, 3, 0, 2, 0, 0, GRN-GRY VRT = 53

2610 DATA 1, 2, 2, -2, 0, 99, 1, 3, 0, 2, 0, 0, PNK-GRY VRT = 54

2620 DATA 1, 2, 1, -2, 0, 99, 1, 4, 1, -2, 0, 0, NBY GRN VRT = 55

2630 DATA 1, 2, 2, -2, 0, 99, 1, 4, 2, -2, 0, 0, NBY PNK VRT = 56

2640 DATA 1, 2, 1, -2, 0, 99, 1, 4, 2, -2, 0, 0, GRN VRT = 57

2650 DATA 1, 2, 2, -2, 0, 99, 1, 4, 1, -2, 0, 0, PNK VRT = 58

2660 DATA 1, 3, 0, 2, 0, 99, 1, 4, 1, -2, 0, 0, PNK VRT FAT = 59

2670 DATA 1, 3, 0, 2, 0, 99, 1, 4, 2, -2, 0, 0, GRN VRT FAT = 60

2680 DATA 1, 1, 1, 3, 0, 99, 1, -1, 1, 3, 0, 0, DULL BLU = 61

2690 DATA 1, 1, 2, 3, 0, 99, 1, -1, 2, 3, 0, 0, DULL BRN = 62

2700 DATA 1, 3, 0, 2, 3, 4, 5, 7, 10, 15, 25, 0, 0, RECEE DING = 63

2710 DATA 2, 0.5, 1, 100, 0, 2, 3, 4, 5, 7, 10, 15, 25, 0, 0, RECEEDING COLORS = 64

2720 DATA 2, 0.3, 1, 0, 0, 1, 0, 0, EVEN COLOR BLEND = 65

2730 DATA 2, 1, 1, 1, 0, 1, 0, 0, UNEVEN BLEND = 66

18000 REM ===========================

18005 REM = {4 SPACES} POLY8 Subroutine {5 SPACES} =

18010 REM = Polygon Painting For {3 SPACES} =

18015 REM = BASIC Graphics Mode 8 =

18020 REM ===========================

18023 REM = {10 SPACES} by; {12 SPACES} =

18024 REM = {7 SPACES} Phil Dunn {9 SPACES} =

18025 REM = {5 SPACES} 12 Monroe Ave. {6 SPACES} =

18026 REM = Hicksville, NY 11801{3 SPACES} =

18030 REM ===========================

18035 REM Enter with the value for

18040 REM TYPE = Type of Painting

18045 REM " {3 SPACES} = 1 for Bar Painting

18050 REM " {3 SPACES} = 2 for Pixel Painting

18053 REM " {3 SPACES} = 3 for a Line Boundary

18055 REM " {3 SPACES} = 4 to PLOT X(i), Y(i)

18057 REM " {3 SPACES} = 5 TO PLOT X(i), Y(i),

18058 REM . and DRAWTO X(i + 1), Y(i + 1)

18060 REM " {3 SPACES} = 6 to DRAWTO X(i), Y(i)

18065 REM " {3 SPACES} = 7 to COLOR RA

18070 REM ..............................

18075 REM For TYPE = 1 to 6,

18080 REM enter with the values . . .

18085 REM NP = No. of Vertex Points.

18087 REM . for i = 1 to NP :

18090 REM X(i) = DIM Vertex X values

18095 REM Y(i) = DIM Vertex Y values

18100 REM .............................

18105 REM For TYPE 1 and 2 Painting

18110 REM also enter values for . . .

18115 REM RA = Angle X/Y Ratio

18120 REM " = 0 for Vertical

18125 REM " = + -1 for + -45 degrees

18130 REM " = 100 for Horizontal

18135 REM P() = DIM array for spacing

18140 REM .Parity Color-Lock Option:

18145 REM .P(0) = 0 for no parity

18150 REM .P(0) = 1 for odd parity

18155 REM .P(0) = 2 for even parity

18160 REM .for i = 1 to something:

18165 REM .ABS(P(i)) = Spaces to move

18170 REM .SGN(P(i)) = +1, no parity

18175 REM .SGN(P(i)) = -1, parity lock

18180 REM .{4 SPACES} P(i) = 0 to end data

18185 REM ..............................

18190 REM For TYPE 2 Pixel Painting

18195 REM also enter values for . . .

18200 REM PB & PC For Pixel Blending

18205 REM * Set PB < 1 for an even

18210 REM . blend of active and

18215 REM . inactive pixels.

18220 REM . PB = the proportion of

18225 REM . active pixels. PB > 0

18230 REM * Set PB >= 1 for an uneven

18235 REM . blend across the area.

18240 REM . area. Then . . .

18245 REM . If PC > 0 then the start

18250 REM . {4 SPACES} color is inactive and

18255 REM . {4 SPACES} the end is active.

18260 REM . If PC < 0 then the start

18265 REM . {4 SPACES} color is active and

18270 REM . {4 SPACES} the end is inactive.

18275 REM . When ABS(PC) = 1 then the

18280 REM . {4 SPACES} start color phases out

18285 REM . {4 SPACES} evenly to the end.

18290 REM . When ABS(PC) > 1 then the

18295 REM . {4 SPACES} start color phases out

18300 REM . {4 SPACES} more slowly.

18305 REM . When ABS(PC) < 1 then the

18310 REM . {4 SPACES} start color phases out

18315 REM . {4 SPACES} more rapidly.

18320 REM ...........................

18325 REM For TYPE = 7, to COLOR RA,

18330 REM enter with RA = 0 or 1

18335 REM ...........................

18340 REM S() = DIM array used here

18345 REM T() = DIM array used here

18350 REM U() = DIM array used here

18355 REM V() = DIM array used here

18360 REM Variable names used . . .

18365 REM CO, C1, C2, Z3, Z4, Z5, Z9,

18370 REM X1, Y1, X2, Y2, CA, SA

18375 REM K, L, M, N, IM, IP, MAX, MIN, NOW

18380 REM ===========================

18400 C0 = 0; C1 = 1 : C2 = 2 : Z9 = 999

18405 IF TYPE = 3 THEN PLOT X(C1), Y(C1) : FOR N = C2 TO NP : DRAWTO X(N), Y(N) : NEXT N : DRAW TO X(C1), Y(C1) : RETURN

18410 IF TYPE = 4 THEN FOR N = C1 TO NP : PLOT X(N), Y(N) : NEXT N : RETURN

18415 IF TYPE = 5 THEN FOR N = C1 TO NP STEP C2 : PLOT X(N), Y(N) : DRAWTO X(N + C1), Y(N + C1) : NEXT N : RETURN

18420 IF TYPE = 6 THEN FOR N = C1 TO NP : DRAWTO X(N), Y(N) : NEXT N : RETURN

18425 IF TYPE = 7 THEN COLOR RA : RETURN

18430 Z5 = 0.5 : IF RA = C2 THEN Z5 = 0.55

18435 IF RA = -C2 THEN Z5 = 0.18

18440 Z3 = -C1 : IF RA< >CO THEN Z3 = SGN(RA)

18445 SA = SQR(1 / (1 + RA ^ C2)) * Z3 : IF ABS(SA) < 0.25 THEN SA = CO

18450 CA = SQR(1 - SA ^ C2)

18455 REM Rotate X(), Y() to U(), V() :

18460 FOR M = C1 TO NP

18465 U(M) = X(M) * CA + Y(M) * SA

18470 V(M) = -X(M) * SA + Y(M) * CA : NEXT M

18480 FOR M = C1 TO NP : N = M + C1 : IF N > NP THEN N = C1

18485 REM Calculate slopes S() and Y axis intercepts T()

18490 IF U(M) = U(N) THEN S(M) = Z9 : GOTO 18510

18495 S(M) = (V(N) - V(M)) / (U(N) - U(M)) : T(M) = V(M) - S(M) * U(M)

18500 IF ABS(S(M)) > Z9 THEN S(M) = Z9

18505 IF ABS(S(M)) < C1 / Z9 THEN S(M) = C0

18510 NEXT M : MAX = -Z9 : MIN = Z9 : FOR M = C1 TO NP : Z3 = V(M)

18515 IF MAX < Z3 THEN MAX = Z3

18520 IF MIN > Z3 THEN MIN = Z3 : N = M

18525 NEXT M : MXMN = MAX - MIN : NOW = MIN : IM = N - C1 : IF IM < C1 THEN IM = NP

18527 IP = N + C1 : IF IP > NP THEN IP = C1

18530 IF P(C1) = C0 THEN P(C1) = C1 : P(C2) = C0

18535 M = C1 : IF P(M) < C0 THEN M = C1

18540 GOTO 18675

18545 REM Calculate intercepts. . .

18550 IF S(N) = Z9 OR S(N) = C0 THEN Z3 = U(N) : GOTO 18560

18555 Z3 = (NOW - T(N)) / S(N)

18560 IF S(IM) = Z9 OR S(IM) = C0 THEN Z4 = U(IM) : GOTO 18575

18565 Z4 = (NOW - T(IM)) / S(IM)

18570 REM Rotate U(), V() to X(), Y() :

18575 X1 = INT(Z3 * CA - NOW * SA + Z5)

18580 IF NOW< >MIN AND P(M) >= C0 THEN 18595

18585 IF P(C0) = C1 THEN IF X1 = C2 * INT(X1 / C2) THEN X1 = X1 + C1

18590 IF P(C0) = C2 THEN IF X1< >C2 * INT(X1 / C2) THEN X1 = X1 + C1

18595 Y1 = INT(Z3 * SA + NOW * CA + Z5)

18600 Y2 = INT(Z4 * SA + NOW * CA + Z5)

18605 IF SA = C0 THEN X2 = Z4 * CA

18610 IF SA< >C0 THEN X2 = X1 + (Y2 - Y1) * RA

18615 REM Bar Painting...............

18620 IF TYPE = 1 THEN PLOT X1, Y1 : DRAW TO X2, Y2 : GOTO 18660

18635 REM Pixel Painting............

18643 IF PB < C1 THEN PR = PB : GOTO 18650

18645 PR = ((NOW - MIN) / MXMN) ^ ABS(PC) : IF PC < C0 THEN PR = C1 - PR

18650 GOSUB LINEP

18655 REM ...........................

18660 NOW = Y1 * CA - X1 * SA

18665 REM Increment NOW for next bar

18670 NOW = NOW + ABS(P(M)) : M = M + C1 : IF P(M) = C0 THEN M = C1

18675 IF NOW < V(IP) THEN 18690

18680 IF V(IP) = MAX THEN RETURN

18685 N = IP : IP = IP + C1 : IF IP > NP THEN IP = C1

18690 IF NOW < V(IM) THEN GOTO 18550

18695 IF V(IM) = MAX THEN RETURN

18700 IM = IM - C1 : IF IM < C1 THEN IM = NP

18705 GOTO 18550

18710 REM ===========================

18750 REM LINEP Subroutine

18751 REM by. . . Phil Dunn

18755 REM Draws a line pixel by pixel

18760 REM With a probability to plot

18765 REM or skip each pixel.

18770 REM X1, Y1, = start point

18775 REM X2, Y2, = end point

18780 REM PR = probability to PLOT

18785 REM .{3 SPACES} >= 0 and <= 1

18790 C0 = 0 : C1 = 1 : C255 = 255 : C230 = 230 : C198 = 198

18795 C92 = 92 : C97 = 97 : C103 = 103 : C106 = 106 : C120 = 120

18800 K = X2 - X1 : L = Y2 - Y1 : Z3 = ABS(K) : Z4 = ABS(L) : BI = PR * C255

18805 IF K = C0 AND L = C0 THEN RETURN

18810 IF K < C0 THEN 18840

18815 LINE$(C92, C92) = CHR$(C230) : REM INC

18820 LINE$(C97, C97) = CHR$(C0)

18825 LINE$(C103, C103) = CHR$(C1)

18830 LINE$(C106, C106) = CHR$(C230)

18835 GOTO 18860

18840 LINE$(C92, C92) = CHR$(C198) : REM DEC

18845 LINE$(C97, C97) = CHR$(C255)

18850 LINE$(C103, C103) = CHR$(C0)

18855 LINE$(C106, C106) = CHR$(C198)

18860 LINE$(C120, C120) = CHR$(C230) : IF L < C0 THEN LINE$(C120, C120) = CHR$(C198)

18865 IF Z3 = C0 THEN Z3 = C1 / C255

18870 IF Z4 = C0 THEN Z4 = C1 / C255

18875 IF Z3 >= Z4 THEN K = Z3 : Y2 = Z3 / Z4 : X2 = 1 : IF Y2 > C255 THEN Y2 = C255

18880 IF Z3 < Z4 THEN K = Z4 : X2 = Z4 / Z3 : Y2 = 1 : IF X2 > C255 THEN X2 = C255

18883 IF K < 1 THEN RETURN

18884 POKE 752, C1

18885 L = USR(ADR(LINE$), K, X1, Y1, X2, Y2, BI)

18890 RETURN

18895 REM ...........................

18900 DIM LINE$(136) : RESTORE 18910 : LINEP = 18790

18905 FOR K = 1 TO 136 : READ L : LINE$(K, K) = CHR$(L) : NEXT K : RETURN

18910 DATA 104, 104, 133, 211, 104, 133, 210, 104, 133, 86

18915 DATA 104, 133, 85, 104, 104, 133, 84, 104, 104, 133

18920 DATA 209, 170, 104, 104, 133, 208, 168, 104, 104, 133

18925 DATA 207, 173, 10, 210, 24, 101, 207, 144, 46, 138

18930 DATA 72, 152, 72, 165, 86, 72, 165, 85, 72, 165

18935 DATA 84, 72, 162, 96, 169, 11, 157, 66, 3, 169

18940 DATA 0, 157, 72, 3, 157, 73, 3, 169, 1, 32

18945 DATA 86, 228, 104, 133, 84, 104, 133, 85, 104, 133

18950 DATA 86, 104, 168, 104, 170, 202, 208, 19, 165, 209

18955 DATA 170, 230, 85, 165, 85, 201, 0, 208, 8, 165

18960 DATA 86, 201, 1, 240, 30, 230, 86, 169, 255, 197

18965 DATA 208, 240, 8, 136, 208, 5, 165, 208, 168, 230

18970 DATA 84, 198, 210, 208, 162, 169, 0, 197, 211, 240

18975 DATA 4, 198, 211, 240, 152, 96

**PROGRAM 5. Multi-Colored Graphics in Mode 8.**

```
100 REM ===========================
```

110 REM = {9 SPACES} PICTURES {11 SPACES} =

120 REM = {3 SPACES} An Example Picture {5 SPACES} =

130 REM = {5 SPACES} Program For The {7 SPACES} =

140 REM = {4 SPACES} POLYB Subroutine {6 SPACES} =

150 REM ===========================

160 REM = {11 SPACES} by: {13 SPACES} =

170 REM = {8 SPACES} Phil Dunn {10 SPACES} =

180 REM = {6 SPACES} 12 Monroe Ave. {7 SPACES} =

190 REM = {3 SPACES} Hicksville, NY 11801 {4 SPACES} =

200 REM ===========================

250 C0 = 0 : C1 = 1 : C2 = 2 : C3 = 3 : C4 = 4 : C5 = 5 : C10 = 10 : C16 = 16 : DETRAP = 40000

260 DIM P(C10), X(C16), Y(C16), S(C16), T(C16), U(C16), V(C16), EA$(C10), EF$(C10)

270 EA$ = "AT AREA = "

280 EF$ = "AT FILL = "

290 POLY 8 = 18400 : GRAPHICS 8

300 SETCOLOR C2, C5, C0 : SETCOLOR C4, C5, C0

310 SETCOLOR C1, C0, 14 : COLOR C1

320 REM ===========================

322 REM SET UP LINE SUBROUTINE

325 ? " Reading DATA. . ." : GOSUB 18900

327 REM ===========================

330 ? " CTIA or GTIA chip (1 or 2)";

332 TRAP 330 : INPUT CHIP : TRAP DETRAP

334 IF CHIP< >1 AND CHIP< >2 THEN 330

336 REM ===========================

339 AREA = C0

340 AREA = AREA + C1

350 RESTORE 3000 + C10 * AREA

360 TRAP 730 : READ FILL

362 ? "AREA, FILL = "; AREA;", ";FILL

365 IF FILL = 999 THEN 1000

370 REM ...........................

380 IF FILL< >-7 THEN 470

385 READ RA

390 IF RA< >C0 AND RA< >C1 THEN ? "COLOR = ";RA;" {3 SPACES} ";EA$; AREA : STOP

400 TYPE = ABS(FILL)

405 TRAP DETRAP : GOSUB POLY8

410 READ P : IF P = 99 THEN 360

420 GOTO 340

460 REM ...........................

470 READ NP

480 IF NP < C3 OR NP > C16 THEN ? "NP = ";NP;" {3 SPACES} "; EA$; AREA : STOP

490 FOR I = C1 TO NP : READ X, Y

493 IF X < C0 OR Y < C0 OR X > 319 OR Y > 159 THEN ? "X, Y = ";X;", ";Y;" "; EA$; AREA : STOP

496 X(I) = X : Y(I) = Y : NEXT I

500 REM ...........................

510 IF FILL < CO THEN 400

540 REM ==========================

550 RESTORE 2000 + C10 * FILL

560 TRAP 740 : READ TYPE

570 REM ...........................

580 IF TYPE< >7 THEN 620

585 READ RA

590 IF RA< >C0 AND RA< >C1 THEN ? "COLOR = ";RA;"{3 SPACES}";EF$; FILL : STOP

600 COLOR RA : GOTO 700

610 REM ...........................

620 IF TYPE< >C2 THEN 640

625 READ PB, PC

630 IF PB <= C0 OR PB > C1 THEN ? "PB = ";PB;" {3 SPACES}";EF$; FILL : STOP

640 READ RA, PO, P : P(C0) = PO : P(C1) = P : I = C2

650 IF PO < C0 OR P = C0 THEN ? "P0, P1 = ";P0;", ";P1;" {3 SPACES}"; EF$; FILL : STOP

652 IF CHIP = C1 THEN 660

654 IF P0 = 1 THEN P(C0) = 2

656 IF P0 = 2 THEN P(C0) = 1

660 READ P : P(I) = P

670 IF P = C0 THEN TRAP DETRAP : GOSUB POLY8 : GOTO 700

680 I = I + C1 : GOTO 660

690 REM ...........................

700 READ P : IF P = 99 THEN 560

710 GOTO 340

720 REM ==========================

730 ? "ERROR AT AREA DATA = "; AREA : STOP

740 ? "ERROR AT FILL DATA = "; FILL : STOP

750 REM ==========================

1000 ? " {5 SPACES} THE MOUNTAIN OF LIGHT"

1010 ? " Inspired by 'The Tiger's Fang'"

1020 ? " {4 SPACES} A book by {3 SPACES} Paul Twitchell"

1030 GOTO 1030

1100 REM ==========================

1990 REM FILL Colors & Textures

2000 DATA 7, 0, 99, 1, 100, 0, 1, 0, 99, 7, 1, 0, HORIZ.ERASER

2010 DATA 1, 100, 0, 1, 0, 0, WHITE = 1

2020 DATA 1, 0, 1, -2, 0, 0, DARK BLUE = 2

2030 DATA 1, -2, 1, 3, 0, 0, RED&GREEN = 3

2040 DATA 1, 4, 1, -9, 0, 0, NUBBY RED = 4

2050 DATA 1, -4, 2, -10, 0, 0, NUBBY RED = 5

2060 DATA 1, 4, 1, -10, 0, 0, NUBBY BLUE = 6

2070 DATA 1, -4, 2, -10, 0, 0, NUBBY BLUE = 7

2080 DATA 1, 0, 2, -1, 3, 0, 0, BAR RED = 8

2090 DATA 2, 1, -1, 100, 0, 2, 2, 3, 4, 5, 7, 10, 13, 17, 0, 0, RECEEDING BARS = 9

2100 DATA 2, 1, 1, -0.5, 0, 1, 0, 0, LEFT BLEND = 10

2110 DATA 2, 1, 1, 0.5, 0, 1, 0, 0, RIGHT BLEND = 11

2120 DATA 1, -2, 1, -2, 0, 0, LIGHT GREEN = 12

2130 DATA 1, 2, 1, -2, 0, 0, LIGHT GREEN = 13

2140 DATA 2, 0.2, 1, 100, 0, 2, 0, 0, TEXTURIZER = 14

2990 REM ==========================

3000 REM AREA Datas

3010 DATA -7, 1, 0, DUMMY = 1

3020 DATA -7, 1, 0, DUMMY = 2

3030 DATA 8, 4, 65, 100, 65, 95, 275, 95, 275, 100, 0, CITY WALLS = 3

3040 DATA 2, 4, 1, 158, 1, 100, 318, 100, 318, 158, 0, OCEAN = 4

3050 DATA 9, 4, 1, 158, 1, 100, 318, 100, 318, 158, 0, REFLEC = 5

3060 DATA 0, 9, 1, 158, 1, 115, 25, 108, 56, 113, 59, 117, 59, 126, 75, 130, 75, 156, 80, 158, 0, ERASE LEFT CLIF = 6

3070 DATA 12, 9, 1, 158, 1, 115, 25, 108, 56, 113, 59, 117, 59, 126, 75, 130, 75, 156, 80, 158, 0, FILL LEFT CLIF = 7

3080 DATA 14, 9, 1, 158, 1, 115, 25, 108, 56, 113, 59, 117, 59, 126, 75, 130, 75, 156, 80, 158, 0, TEXTURE LEFT CLIF = 8

3090 DATA 0, 3, 75, 130, 56, 140, 75, 156, 0, ERASE LEFT NEAR FACE = 9

3100 DATA 3, 3, 75, 130, 56, 140, 75, 156, 0, FILL LEFT NEAR FACE = 10

3110 DATA 0, 3, 59, 117, 45, 122, 59, 126, 0, ERASE LEFT FAR FACE = 11

3120 DATA 3, 3, 59, 117, 45, 122, 59, 126, 0, FILL LEFT FAR FACE = 12

3130 DATA 0, 6, 205, 158, 245, 135, 290, 125, 305, 130, 305, 155, 310, 158, 0, ERASE RIGHT CLIF = 13

3140 DATA 13, 6, 205, 158, 245, 135, 290, 125, 305, 130, 305, 155, 310, 158, 0, FILL RIGHT CLIF = 14

3150 DATA 14, 6, 205, 158, 245, 135, 290, 125, 305, 130, 305, 155, 310, 158, 0, TEXTURE RIGHT CLIF = 15

3160 DATA 0, 3, 305, 130, 280, 145, 305, 155, 0, ERAS E RIGHT FACE = 16

3170 DATA 3, 3, 305, 130, 280, 145, 305, 155, 0, FILL RIGHT FACE = 17

3180 DATA 1, 4, 155, 125, 162, 132, 168, 145, 155, 141, 0, SAIL = 18

3190 DATA 1, 8, 154, 141, 156, 141, 159, 146, 159, 148, 156, 151, 154, 151, 151, 148, 151, 146, 0, BOAT = 19

3200 DATA -7, 0, 99, -4, 10, 153, 145, 153, 146, 153, 147, 154, 146, 154, 147, 156, 147, 156, 148, 157, 146, 157, 147, 157, 148, 0

3210 DATA -7, 1, 0, PAUL & REBEZAR = 21

3220 DATA -7, 0, 99, -5, 8, 160, 144, 174, 158, 158, 152, 162, 158, 152, 152, 146, 158, 150, 144, 136, 158, 99, -7, 1, 0, WAKE = 22

3230 DATA 10, 10, 70, 95, 95, 95, 102, 87, 120, 60, 130, 36, 145, 18, 160, 5, 165, 5, 170, 10, 170, 95, 0, MTN.LEFT = 23

3240 DATA 11, 9, 170, 95, 170, 10, 182, 7, 192, 20, 205, 32, 212, 35, 225, 65, 245, 95, 275, 95, 0, MTN.RIGHT = 24

3250 DATA 6, 4, 145, 2, 60, 2, 100, 77, 105, 27, 0, LEFT RAYS BLUE = 25

3260 DATA 7, 4, 205, 5, 290, 5, 235, 80, 235, 30, 0, RIGHT RAYS BLUE = 26

3270 DATA 4, 3, 150, 1, 95, 85, 50, 1, 0, LEFT RAYS RED = 27

3280 DATA 5, 3, 200, 1, 240, 85, 300, 1, 0, RIGHT RAYS RED = 28

3290 DATA 999

18000 REM ===========================

18005 REM = {4 SPACES} POLY8 Subroutine {5 SPACES} =

18010 REM = Polygon Painting For {3 SPACES} =

18015 REM = BASIC Graphics Mode 8 =

18020 REM ===========================

18025 REM = by : Phil Dunn {9 SPACES} =

18030 REM ===========================

18035 REM Enter with the value for

18040 REM TYPE = Type of Painting

18045 REM " {3 SPACES} = 1 for Bar Painting

18050 REM " {3 SPACES} = 2 for Pixel Painting

18053 REM " {3 SPACES} = 3 for a Line Boundary

18055 REM " {3 SPACES} = 4 to PLOT X(i), Y(i)

18057 REM " {3 SPACES} = 5 TO PLOT X(i), Y(i),

18058 REM . and DRAWTO X(i + 1), Y(i + 1)

18060 REM " {3 SPACES} = 6 to DRAWTO X(i), Y(i)

18065 REM " {3 SPACES} = 7 to COLOR RA

18070 REM ...........................

18075 REM For TYPE = 1 to 6,

18080 REM enter with the values. . .

18085 REM NP = No. of Vertex Points.

18087 REM . for i = 1 to NP :

18090 REM X(i) = DIM Vertex X values

18095 REM Y(i) = DIM Vertex Y values

18100 REM ...........................

18105 REM For TYPE 1 and 2 Painting

18110 REM also enter values for. . .

18115 REM RA = Angle X / Y Ratio

18120 REM " = 0 for Vertical

18125 REM " = +-1 for +-45 degrees

18130 REM " = 100 for Horizontal

18135 REM P() = DIM array for spacing

18140 REM .Parity Color-Lock Option:

18145 REM .P(0) = 0 for no parity

18150 REM .P(0) = 1 for odd parity

18155 REM .P(0) = 2 for even parity

18160 REM .for i = 1 to something:

18165 REM .ABS(P(i)) = Spaces to move

18170 REM .SGN(P(i)) = +1, no parity

18175 REM .SGN(P(i)) = -1, parity lock

18180 REM .{4 SPACES} P(i) = 0 to end data

18185 REM ...........................

18190 REM For TYPE 2 Pixel Painting

18195 REM also enter values for. . .

18200 REM PB & PC For Pixel Blending

18205 REM * Set PB < 1 for an even

18210 REM . blend of active and

18215 REM . inactive pixels.

18220 REM . PB = the proportion of

18225 REM . active pixels. PB > 0

18230 REM * Set PB >= 1 for an uneven

18235 REM . blend across the area.

18240 REM . area. Then . . .

18245 REM . If PC > 0 then the start

18250 REM . {4 SPACES} color is inactive and

18255 REM . {4 SPACES} the end is active.

18260 REM . If PC < 0 then the start

18265 REM . {4 SPACES} color is active and

18270 REM . {4 SPACES} the end is inactive.

18275 REM . When ABS(PC) = 1 then the

18280 REM . {4 SPACES} start color phases out

18285 REM . {4 SPACES} evenly to the end.

18290 REM . When ABS(PC) > 1 then the

18295 REM . {4 SPACES} start color phases out

18300 REM . {4 SPACES} more slowly.

18305 REM . When ABS(PC) < 1 then the

18310 REM . {4 SPACES} start color phases out

18315 REM . {4 SPACES} more rapidly.

18320 REM ...........................

18325 REM For TYPE = 7, to COLOR RA,

18330 REM enter with RA = 0 or 1

18335 REM ...........................

18340 REM S() = DIM array used here

18345 REM T() = DIM array used here

18350 REM U() = DIM array used here

18355 REM V() = DIM array used here

18360 REM Variable names used. . .

18365 REM C0, C1, C2, Z3, Z4, Z5, Z9,

18370 REM X1, Y1, X2, Y2, CA, SA

18375 REM K, L, M, N, IM, IP, MAX, MIN, NOW

18380 REM ==========================

18400 C0 = 0 : C1 = 1 : C2 = 2 : Z9 = 999

18405 IF TYPE = 3 THEN PLOT X(C1), Y(C1) : FOR N = C2 TO NP : DRAWTO X(N), Y(N) : NEXT N : DRAWTO X(C1), Y(C1) : RETURN

18410 IF TYPE = 4 THEN FOR N = C1 TO NP : PLOT X(N), Y(N) : NEXT N : RETURN

18415 IF TYPE = 5 THEN FOR N = C1 TO NP STEP C2 : PLOT X(N), Y(N) : DRAWTO X(N + C1), Y(N + C1) : NEXT N : RETURN

18420 IF TYPE = 6 THEN FOR N = C1 TO NP : DRAWTO X(N), Y(N) : NEXT N : RETURN

18425 IF TYPE = 7 THEN COLOR RA : RETURN

18430 Z5 = 0.5 : IF RA = C2 THEN Z5 = 0.55

18435 IF RA = -C2 THEN Z5 = 0.18

18440 Z3 = -C1 : IF RA< >CO THEN Z3 = SGN(RA)

18445 SA = SQR(1 / (1 + RA ^ C2)) * Z3 : IF ABS(SA) < 0.2 THEN SA = CO

18450 CA = SQR(1 - SA ^ C2)

18455 REM Rotate X(), Y() to U(), V() :

18460 FOR M = C1 TO NP

18465 U(M) = X(M) * CA + Y(M) * SA

18470 V(M) = -X(M) * SA + Y(M) * CA : NEXT M

18480 FOR M = C1 TO NP : N = M + C1 : IF N > NP THEN N = C1

18485 REM Calculate slopes S() and Y axis intercepts T()

18490 IF U(M) = U(N) THEN S(M) = Z9 : GOTO 18510

18495 S(M) = (V(N) - V(M)) / (U(N) - U(M)) : T(M) = V(M) - S(M) * U(M)

18500 IF ABS(S(M)) > Z9 THEN S(M) = Z9

18505 IF ABS(S(M)) < C1 / Z9 THEN S(M) = C0

18510 NEXT M : MAX = -Z9 : MIN = Z9 : FOR M = C1 TO NP : Z3 = V(M)

18515 IF MAX < Z3 THEN MAX = Z3

18520 IF MIN > Z3 THEN MIN = Z3 : N = M

18525 NEXT M : MXMN = MAX - MIN : NOW = MIN : IM = N - C1 : IF IM < C1 THEN IM = NP

18527 IP = N + C1 : IF IP > NP THEN IP = C1

18530 IF P(C1) = C0 THEN P(C1) = C1 : P(C2) = C0

18535 M = C1 : IF P(M) < C0 THEN M = C1

18540 GOTO 18675

18545 REM Calculate intercepts. . .

18550 IF S(N) = Z9 OR S(N) = C0 THEN Z3 = U(N) : GOTO 18560

18555 Z3 = (NOW - T(N)) / S(N)

18560 IF S(IM) = Z9 OR S(IM) = C0 THEN Z4 = U(IM) : GOTO 18575

18565 Z4 = (NOW - T(IM)) / S(IM)

18570 REM Rotate U(), V() to X(), Y() :

18575 X1 = INT(Z3 * CA - NOW * SA + Z5)

18580 IF N0W< >MIN AND P(M) >= C0 THEN 18595

18585 IF P(C0) = C1 THEN IF X1 = C2 * INT(X1 / C2) THEN X1 = X1 + C1

18590 IF P(C0) = C2 THEN IF X1< >C2 * INT(X1 / C2) THEN X1 = X1 + C1

18595 Y1 = INT(Z3 * SA + NOW * CA + Z5)

18600 Y2 = INT(Z4 * SA + NOW * CA + Z5)

18605 IF SA = C0 THEN X2 = Z4 * CA

18610 IF SA< >C0 THEN X2 = X1 + (Y2 - Y1) * RA

18615 REM Bar Painting...............

18620 IF TYPE = 1 THEN PLOT X1, Y1 : DRAW TO X2, Y2 : GOTO 18660

18635 REM Pixel Painting...............

18643 IF PB < C1 THEN PR = PB : GOTO 18650

18645 PR = ((NOW - MIN) / MXMN) ^ ABS(PC) : IF PC < C0 THEN PR = C1 - PR

18650 GOSUB LINEP

18655 REM ...........................

18660 NOW = Y1 * CA - X1 * SA

18665 REM Increment NOW for next bar

18670 NOW = NOW + ABS(P(M)) : M = M + C1 : IF P(M) = C0 THEN M = C1

18675 IF NOW < V(IP) THEN 18690

18680 IF V(IP) = MAX THEN RETURN

18685 N = IP : IP = IP + C1 : IF IP > NP THEN IP = C1

18690 IF NOW < V(IM) THEN GOTO 18550

18695 IF V(IM) = MAX THEN RETURN

18700 IM = IM - Cl : IF IM < C1 THEN IM = NP

18705 GOTO 18550

18710 REM ==========================

18750 REM LINEP Subroutine

18755 REM Draws a line pixel by pixel

18760 REM With a probability to plot

18765 REM or skip each pixel.

18770 REM XI, Yl = start point

18775 REM X2, Y2 = end point

18780 REM PR = probability to PLOT

18785 REM . {3 SPACES} >= 0 and <= 1

18790 C0 = 0 : C1 = 1 : C255 = 255 : C230 = 230 : C198 = 198

18795 C92 = 92 : C97 = 97 : C103 = 103 : C106 = 106 : C120 = 120

18800 K = X2 - X1 : L = Y2 - Y1 : Z3 = ABS(K) : Z4 = ABS(L) : BI = PR * C255

18805 IF K = C0 AND L = C0 THEN RETURN

18810 IF K < C0 THEN 18840

18815 LINE$(C92, C92) = CHR$(C230) : REM INC

18820 LINE$(C97, C97) = CHR$(C0)

18825 LINE$(C103, C103) = CHR$(C1)

18830 LINE$(C106, C106) = CHR$(C230)

18835 GOTO 18860

18840 LINE$(C92, C92) = CHR$(C198) : REM DEC

18845 LINE$(C97, C97) = CHR$(C255)

18850 LINE$(C103, C103) = CHR$(C0)

18855 LINE$(C106, C106) = CHR$(C198)

18860 LINE$(C120, C120) = CHR$(C230) : IF L < C0 THEN LINE$(C120, C120) = CHR$(C198)

18865 IF Z3 = C0 THEN Z3 = C1 / C255

18870 IF Z4 = C0 THEN Z4 = C1 / C255

18875 IF Z3 >= Z4 THEN K = Z3 : Y2 = Z3 / Z4 : X2 = 1 : IF Y2 > C255 THEN Y2 = C255

18880 IF Z3 < Z4 THEN K = Z4 : X2 = Z4 / Z3 : Y2 = 1 : IF X2 > C255 THEN X2 = C255

18883 IF K < 1 THEN RETURN

18884 POKE 752, C1

18885 L = USR(ADR(LINE$), K, X1, Y1, X2, Y2, BI)

18890 RETURN

18895 REM ...........................

18900 DIM LINE$(136) : RESTORE 18910 : LINEP = 18790

18905 FOR K = 1 TO 136 : READ L : LINE$(K, K) = CHR$(L) : NEXT K : RETURN

18910 DATA 104, 104, 133, 211, 104, 133, 210, 104, 133, 86

18915 DATA 104, 133, 85, 104, 104, 133, 84, 104, 104, 133

18920 DATA 209, 170, 104, 104, 133, 208, 168, 104, 104, 133

18925 DATA 207, 173, 10, 210, 24, 101, 207, 144, 46, 138

18930 DATA 72, 152, 72, 165, 86, 72, 165, 85, 72, 165

18935 DATA 84, 72, 162, 96, 169, 11, 157, 66, 3, 169

18940 DATA 0, 157, 72, 3, 157, 73, 3, 169, 1, 32

18945 DATA 86, 228, 104, 133, 84, 104, 133, 85, 104, 133

18950 DATA 86, 104, 168, 104, 170, 202, 208, 19, 165, 209

18955 DATA 170, 230, 85, 165, 85, 201, 0, 208, 8, 165

18960 DATA 86, 201, 1, 240, 30, 230, 86, 169, 255, 197

18965 DATA 208, 240, 8, 136, 208, 5, 165, 208, 168, 230

18970 DATA 84, 198, 210, 208, 162, 169, 0, 197, 211, 240

18975 DATA 4, 198, 211, 240, 152, 96

Return to Table of Contents | Previous Section | Next Section