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