Part 2: Textured Graphics

Phil Dunn

This article extends the techniques covered in Part 1, the Polyfil subroutine. You'll be surprised at what "textured" graphics can do.

With the Polygon Fill subroutine, we showed how easy it was to create a picture. However, the picture quality suffered because of the limitations of the Atari Graphics Mode 7 in terms of variety of color. Being limited to only four colors puts quite a constraint on our ability to develop an interesting picture. Here we are going to use some simple texture-creating effects.

Although we are restricting ourselves to the development of static pictures, this is just the necessary initial work that we can later build upon as we move into the creation of dynamically changing scenes with action, movement, and sound.

Polygon Fill Becomes PolyPaint

The key tool that we had developed in Polygon Fill we will now expand upon to do a much greater task. I call this new subroutine PolyPaint because it provides so much variety of possible textures and colors within any defined polygon shape.

First let's get an overview of what is being presented here. Program 1 shows the PolyPaint subroutine which is going to do all this picture painting for us. It starts off with a long list of REM statements which summarize its requirements and abilities. We will go over these in detail in the following paragraphs.

With all REM statements deleted, these programs will run with only a 16K memory system up to Graphics Mode 7.

Program 2 is the Picture program. Although the listing does not show it, it must be understood that the PolyPaint subroutine is to be attached to this program before it can be RUN. All that is needed in order to use this program will be explained in the remainder of this article.

Program 3, Palette, enables us to study the effects of various command options, pattern characteristics, hue-luminance assignments, and resolutions in the various graphics modes. Naturally, this too requires the PolyPaint subroutine to be appended before it will RUN.

Now let's take a close look at Program 1, the PolyPaint subroutine. Starting at the top, there are the REM statements which summarize the requirements and capabilities of PolyPaint. The first item mentioned is the variable NP, which must have the value of the number of vertex points around the perimeter of the polygon. The actual values for the X, Y coordinates of these vertex points are stored in the array variables X() and Y(). These variables are to be DIMensioned by the program that GOSUBs to PolyPaint, and the vertex points are to be stored in them with the first point being in X(1), Y(1), the second point in X(2), Y(2), etc.

Vertex Data Point Restrictions

There are some restrictions upon how the vertex data point values may be specified. First, they must be defined in a sequential order around the polygon perimeter. Second, there can be no indentations that require the fill technique to skip over empty spaces. The previous Polygon Fill subroutine used a series of horizontally drawn lines to fill in the polygon. That method prevents trouble filling in "L," "E" or "F" shapes, for example, but it cannot fill in a "U" shape properly.

The same restriction exists for this PolyPaint routine when the option selected consists of either horizontal bars, or horizontal pixel sweep. On the other hand, if PolyPaint is used with the vertical bars or vertical pixel sweep options, it would have no trouble filling in the "L" or "U" shapes, but it would not fill the "E" or "F" shapes properly. Naturally, any indented shape can be divided into two or more non-indented shapes, which can then be filled properly by any option.

We have jumped ahead of ourselves by referring to the options before this point, but now we will cover the various options that are available by assigning the appropriate value to the variable called TYPE. When TYPE = 1, the PolyPaint routine will allow us to "paint" our polygon with bars, or lines. I prefer to use the word bar here, to distinguish this option from the option available when TYPE = 4.

When TYPE = 1 the polygon is painted a whole bar at a time with the PLOT-DRAWTO commands. When TYPE = 2 the polygon is painted a single pixel at a time using only the PLOT command. When TYPE = 3 the polygon is painted a single pixel at a time also, but only with a specific checkerboard pattern.

The TYPE = 4 option is a special feature that has nothing to do with polygon filling at all, but is very useful for drawing pictures in general. The TYPE = 4 option allows us to draw a line a pixel at a time, where the pixel can alternate between two colors.

If we set TYPE = 1 for bar painting, then we must assign values to four additional variables to specify how these bars will be used. The first variable, DIR, specifies the direction of the bar orientation. A value of DIR = 0 provides horizontal bars, and a value of DIR = 1 provides vertical bars. The variable SPA sets spaces between the bars. When SPA = 0 there are no spaces, when SPA = 1 there is one space between each bar, when SPA = 2 there are two spaces between each bar, etc. "FAC" is a variable space factor. When FAC = 0, the spaces between the bars (if any) are constant across the polygon. When FAC = 1 the spaces between the bars increase as they are placed within the polygon. When FAC = 1 the spaces between the bars decrease as they are drawn.

The bars are always drawn from the low value of the screen variable to the high value. Thus, the first horizontal bar will be drawn at the lowest value of Y, the top of the polygon, and the last horizontal bar will be drawn at the largest value of Y, at the bottom of the polygon. Similarly, vertical bars will be drawn from left (the smallest X) to right (to the largest X).

The last variable that must be assigned a value for bar painting is CLO. This value is used to set the color register for the bars. All the bars are drawn with the color of the CLO register.

When we set TYPE = 2 for pixel painting, this too requires four additional variables to be set. The DIR variable is used to determine the pixel "sweep" direction. The pixels are drawn in a sweep of one line at a time. When DIR = 0 the sweep lines are horizontal, and when DIR = 1, the sweep lines are vertical, much like the bar painting convention.

The FAC variable is used to specify the color – blending characteristic for the two color registers that are specified in the variables CLO and CHI. There are two different blending techniques that may be used; the FAC variable is used to specify which of the two techniques will be used and how the technique will be applied.

When FAC › 0.0 and FAC ‹ 1.0, the polygon will be filled evenly with a proportional blend between the two colors of CLO and CHI, where the color of each pixel is selected at random with a probability determined by the value of FAC. The smaller the value of FAC the more the CLO color will predominate, and the higher the value of FAC the more the CHI color will be represented. FAC is the percentage of the CHI color. When FAC = .2, there will be 80% of the CLO color, and 20% of the CHI color. When FAC = .5, there will be a 50– 50 mix between the two colors. When FAC = .9, there will be 10% of CLO and 90% of CHI.

Creating Shading Effects And Multiple Overlays

When FAC is equal to or greater than 1.0, a completely different color blending technique is used. With this technique, the CLO color always predominates at the end of the polygon with the low value for the screen variable, and the CHI color always predominates at the high value end of the polygon. For horizontal sweep (DIR = 0), the CLO color will predominate at the top of the polygon and the CHI color will predominate at the bottom of the polygon. For vertical sweep (DIR = 1), the CLO color will predominate at the left side of the polygon and the CHI color will predominate at the right side. (This is useful for shading effects.)

The rate at which the color ratio changes from CLO to CHI as the polygon is filled is determined by the value of FAC. When FAC is small (equal to or close to one), then the CLO color will dominate the polygon until the very end, when some amount of CHI color will appear. When FAC is large (ten or more), some amount of CLO color will appear in the beginning, but the CHI color will rapidly take over and will dominate the finished polygon. A value of FAC = 5 will provide a fairly even balance between CLO and CHI, with the center of the polygon being about a 50-50 mixture.

This pixel painting technique allows the possibility of multiple color overlays. If the color register number assigned to CLO or CHI is -1, that color becomes the "transparent" color. In other words, that pixel is passed over and its color remains unchanged. Thus, the same polygon can be painted several different times; each time the transparent color will allow the previously drawn pattern to show through.

Polygon painting TYPE = 3 provides a checkerboard pattern that alternates between CLO and CHI. The checkerboard may be painted by sweeping horizontally (DIR = 0) or vertically (DIR = 1). In the high resolution mode of Graphics 7, the checkerboard pattern is sufficiently small so that it can be used as a whole new color. Thus, by blending the allowable four colors of Graphics 7 two at a time in the checkerboard pattern, we can obtain six more colors. This gives us ten colors in Graphics Mode 7! This color blending technique works best when the two colors used have about the same luminance level. When the luminance level is vastly different between the two colors, the checkerboard characteristic becomes more visually obvious.

The final option found in this routine, TYPE = 4, does not fill a polygon at all, but simply draws a line. The starting point is specified by variables X(0), Y(0) and the ending point by X(1), Y(1). However, this option allows the pixel line elements to alternate between the color of the CLO register and the color of the CHI register. Naturally, the same register number can be used for both CLO and CHI to plot a line of that one color.

If you plan to use this routine in a program of your own, you should make note of the variable names that are used internally here. These names are given in the REM statements in lines 17295 to 17305.

The structure of the PolyPaint routine is a direct expansion from the structure of the Polygon Fill subroutine presented previously. Many of the lines are identical. The routine uses the polygon perimeter vertex points to calculate the slope and Y-axis intercepts of the polygon perimeter line segments, and stores this information in the array variables S() and T() in line 17335. The maximum and minimum polygon values are calculated in lines 17345 to 17360. The intercept points for horizontal bars or pixel-sweep are calculated in lines 17395 to 17410, and for vertical bars or pixel-sweep, in lines 17420 to 17435.

Bar painting is done in lines 17455 to 17470, checkerboard painting is done in lines 17495 to 17515, and pixel painting is done in lines 17520 to 17595. The sweep line, or bar, is incremented in line 17600. At lines 17615 to 17650 the incremented line is checked to find if it passed over an adjacent vertex point. If it did, that point is checked against the maximum point on the polygon. If it is not beyond the maximum, the index pointer to the perimeter slope-intercept array elements is incremented.

So much for the PolyPaint subroutine itself. Now let's take a look at how it may be used. The example program (Program 2) is called the Picture program. This program has been written in a very general and useful form. To use it to create your own pictures, just redefine the Graphics mode and SETCOLOR assignments in lines 240 to 280, and the DATA and PLOT-DRAWTO commands after line 1020. The rest of the program is designed to read the DATA statements that are set up and let the PolyPaint subroutine do its job. Error detecting logic has been coded into this program so that if a mistake is made in setting up the DATA statements, the chances are that the program will catch it and tell us what it is and where it is located.

The PICTURE program sets up the necessary array variables in line 300. No polygon used here has more than 15 vertex points. Line 310 establishes the first statement which can be executed in the PolyPaint subroutine as being at line 17315. The polygon or area counter variable, A, is set to zero at line 370 and then the first data value is read in.

The DATA in lines 1080 to 1370 is arranged in a very specific way to minimize the difficulty of reading and debugging it. The first number in every DATA statement corresponds to the TYPE variable for the PolyPaint subroutine. The number should only be from one to four, depending upon the TYPE of painting that is desired. The only exception to this is the very last DATA statement where the TYPE value of 999 tells the PICTURE program that there is no more data. The value for TYPE determines the interpretation of the remaining numeric values on the remainder of each DATA statement.

When TYPE = 1, the next four DATA numbers represent the values for the PolyPaint subroutine variables DIR, SPA, FAC, and CLO, respectively. When TYPE = 2, the next four numbers represent the variables DIR, FAC, CLO and CHI. When TYPE = 3, the next three values represent the variables DIR, CLO and CHI.

The following DATA value for TYPE = 1, 2, or 3 is for the variable NP, and the remaining "NP" pair of values are for the vertex point array variables X(1), Y(1), X(2), Y(2), etc.

When TYPE = 4, the remaining six DATA values correspond to the variables CLO, CHI, X(0), Y(0), X(1), and Y(1), respectively.

How The Picture Is Painted

Now let's take a look at how this particular picture is being painted. As you read this, you might want to RUN this program so you can see each area being painted as we mention it.

The first item painted is the mountain, in line 1080. It is first established as a TYPE = 3 checkerboard blend, using a DIR = 1 vertical sweep, and blending the two colors CLO = 3 (white) and CHI = 2 (green). This mountain is a polygon with NP = 6 vertex points, the first one being 54, 42, the second 68, 30, etc. Then, in line 1090, the left half of the mountain is repainted with TYPE = 2 pixel painting, DIR = 1 vertical sweep, FAC = 9 for mostly CHI color, and the color values CLO = 2 (green) and CHI = -1 (transparent). This gives a green shading effect at the left edge of the mountain. Line 1100 continues repainting the right side of the mountain with TYPE = 2 pixel painting, DIR = 1 vertical sweep, FAC = 2 for mostly CLO color, and CLO = -1 (transparent) and CHI = 2 (green). This gives a green shading effect to the right edge of the mountain.

On line 1120, the mountaintop is defined by a TYPE = 2 pixel painting form, with DIR = 0 horizontal sweep, FAC = 1 for mostly CLO color, and CLO = 3 (white), CHI = -1 (transparent). This gives a mountaintop that is completely white at the top, but lets a variable amount of the former color show through at the lower altitudes.

On line 1140 the lowlands around the mountain are painted first with a TYPE = 3 checkerboard blend and a DIR = 0 horizontal sweep, with the blended colors CLO = 3 (white) and CHI = 2 (green). Then this same area is repainted in line 1150 with TYPE = 2 pixel painting, DIR = 0 horizontal sweep, FAC = .5 for a 50-50 even mix of CLO and CHI, where CLO = -1 (transparent) and CHI = 2 (green).

The foreground scene is first painted on line 1190 with TYPE = 3 checkerboard blending, with a DIR = 0 horizontal sweep technique, and the two blended colors CLO = 2 (green) and CHI = 0 (blue). Then the foreground is repainted with TYPE = 2 pixel painting with DIR = 0 horizontal sweep, FAC = 3 color blending, with the CLO color at the top predominating over the CHI color at the bottom. The CLO = -1 transparent color will allow the previous blue-green blend to show through, while the CHI = 2 green color gives some texture overlay effects.

The river is defined at line 1230, first as a TYPE = 3 checkerboard blend with a horizontal sweep DIR = 0, and the two blended colors CLO = 0, the blue background, and CHI = 3, white. Then the river is repainted with TYPE = 1 bar painting, using DIR = 0 horizontal bars, SPA = 3 spaces between bars, FAC = 1 for the spaces to increase across the polygon, and CLO = 3 for the white color.

The next two DATA statements define the tops of two trees and, while the shapes and locations differ, they are both painted in the same way. They use TYPE = 2 pixel painting with a horizontal sweep DIR = 0 and a FAC = .2 for an even mixture of 80% CLO and 20% CHI, where CLO = 2 (green) and CHI = 0 (blue).

The tree trunks are both painted in the TYPE = 1 bar mode, using DIR = 0 horizontal bars with SPA = 0 for no spaces between the bars, and FAC = 0 for no variability in the bar spacing across the polygon. The color register CLO = 1 gives a reddish maroon shade.

The remaining details of the picture consist of two human figures. These figures are so small that the PolyPaint routine cannot be used efficiently to display them. The high-resolution detail required by figures like these must be achieved by specific PLOT and DRAWTO commands. The PolyPaint routine is suitable for painting relatively large screen areas.

At this point you can take this Picture program and change the Graphics mode, SETCOLOR assignments, and DATA statements and use it to paint your own picture. However, the key word here is paint, not create. We don't create our picture with this program, we just manifest it.

The actual creation of the picture is done away from the computer, with a pencil and a paper that has a grid pattern marked off corresponding to the screen's horizontal and vertical coordinate numbers for the Graphics mode that we choose. We then sketch out our picture on this grid paper, noting the various areas, their vertex point values, the colors we would like to assign, and the painting and overlay methods that we might want to use. We also must define which high-resolution detail we must draw pixel-by-pixel or line-by-line. Only after all this homework is done can we sit down at our machine and paint our picture.

The Palette Utility

I found that, to use this PolyPaint subroutine effectively, I needed a utility program which allowed me to study the effects available by using the various painting command options, a variety of overlay effects, different color and luminance values, and the different resolutions available from the various Graphics modes. The utility program that allows this study is Program 3, the Palette program.

A brief survey of this program will prove informative. The first question asked by the program is for the Graphics mode. The program presently allows the BASIC modes 3 through 8. Depending upon the mode selected, two scale factor variables, E and F, are assigned appropriate numeric values. As we scan through the remainder of this program we see that every X, Y value in a PLOT or DRAWTO statement is multiplied by these scale factors.

The initial color assignment to the four registers is done between lines 370 and 430. The background is white and the color registers 1, 2, and 3 are assigned the colors red, green, and blue.

If you RUN this program you will see that it proceeds to display three rectangular areas showing the colors in registers in 1, 2, and 3; the areas are numbered appropriately. Above each of these primary colors is a checkerboard blend of the primary color with the background color. Below the primary colors are three rectangular areas that show checkerboard blends of each of the three primary colors against each other. The connecting lines clarify which color is being blended with which.

Then, on the right part of the picture, four areas are reserved for us to try out various patterns. On line 1480 we are asked which area we wish to use. We can answer this question with the value zero to four. If we answer with the value zero, then we are given the option of redefining any of the hue or luminance values in the four color registers. We are shown the hue and luminance numbers for each register, and are then asked which register number we wish to change.

After we select a register number we then use joystick zero to change the hue and luminance for that register. Moving the stick sideways changes the hue and moving it forward or back changes the luminance. When we are ready to "fix" that hue and luminance we press the trigger button. We then return to the "Which COLOR" question. At this point we can return to the "Which AREA" question by RETURNing with the value 99.

It should be noted that if, in response to any question, we return with the value 99, then we will always be shifted back to the "Which AREA" question in the program. Thus, if we change our minds while specifying a certain type of painting technique, we can always abort the sequence by typing the number 99.

Instead of giving suggestions on how this Palette program might be used, I'll just let you explore it yourself. It is self-explanatory anyway, and fairly well error-protected.

It should be understood that the area of textured graphics is completely open-ended. The texturizing options in this version of PolyPaint just scratch the surface, so to speak, of what is possible within this category. Anyone who wants to can modify or expand this program to incorporate a much greater variety of effects. If you develop something in this area, I would certainly be happy to learn about it.

The Palette program also can be expanded. The present version of this program only allows the BASIC graphics modes 3 to 8. As we learn more about the Atari system, we should be able to modify this program to include the additional ANTIC graphics modes and thus expand our repertoire of picture-creating capabilities.

PROGRAM 1. Textured Graphics.

17000 REM ===========================
17005 REM POLYPAINT Subroutine
17010 REM Polygon Color Painting
17015 REM ...........................
17020 REM by Phil Dunn, with The ECK *
17025 REM ...........................
17030 REM Enter with the values…
17035 REM NP = No. of vertex points.
17040 REM X() = DIM array of X values
17045 REM Y() = DIM array of Y values
17050 REM S() = DIM array used here
17055 REM T() = DIM array used here
17060 REM TYPE = Type of painting
17065 REM " {3 SPACES} = 1 for bar painting
17070 REM " {3 SPACES} = 2 for pixel painting
17075 REM " {3 SPACES} = 3 for checkerboard
17080 REM " {3 SPACES} = 4 to draw a line
17085 REM ...........................
17090 REM ****** Bar painting input:
17095 REM DIR = Bar Direction
17100 REM " = 0 for horizontal bars
17105 REM " = 1 for vertical bars
17110 REM SPA = Spaces between bars
17115 REM " = 0 for no spaces
17120 REM " >= 1 to skip spaces
17125 REM FAC = Variable space factor
17130 REM " = 1 for increasing spaces
17135 REM " = 0 for constant spaces
17140 REM " = -1 for decreasing spaces
17145 REM CLO = Color register number
17150 REM ...........................
17155 REM ***** Pixel painting input:
17160 REM DIR = Sweep Direction
17165 REM " = 0 for horizontal sweep
17170 REM " = 1 for vertical sweep
17175 REM FAC = Blending factor from
17180 REM .{5 SPACES} low end to high end
17185 REM " = 0 -. 99 for an even mix
17190 REM " {5 SPACES} < . 5 = more CLO color
17195 REM " {5 SPECES} > .5 = more CHI color
17200 REM " >= 1 for uneven color mix
17205 REM " {5 SPACES} = 1 - 3 for more low end
17210 REM " {5 SPACES} > 7 for more high end
17215 REM CLO = Low end color reg.
17220 REM CHI = High end color reg.
17225 REM Note: Setting CLO or CHI to
17230 REM -1 will hold the previous
17235 REM color on those pixels.
17240 REM ...........................
17245 REM **** Checkerboard painting:
17246 REM DIR = Sweep Direction
17247 REM " = 0 for horizontal sweep
17248 REM " = 1 for vertical sweep
17250 REM CLO = First color register
17255 REM CHI = Second color register
17260 REM ...........................
17265 REM *********** To Draw A Line :
17270 REM X(0), Y(0) = Start point
17275 REM X(1), Y(1) = End point
17280 REM CL0 = Start color
17285 REM CHI = Alternate color
17290 REM ...........................
17295 REM Uses the variable names Q0,
17300 REM Q1, Q2, Q3, Q4, Q5, COL, IM, IP, DL
17305 REM K, L, M, N, R, MAX, MIN, MXMN, NOW
17310 REM ...........................
17315 Q0 = 0 : Q1 = 1 : Q2 = 1000 : IF TYPE = 4 THEN 17660
17320 FOR M = Q1 TO NP : N = M + Q1 : IF N > NP THEN N = Q 1
17325 IF X(M) = X(N) THEN S(M) = Q2 : GOTO 17340
17330 REM Slopes = S(), Intercepts = T()
17335 S(M) = (Y(N) - Y(M)) / (X(N) - X(M)) : T(M) = Y(M) - S(M) * X(M)
17340 NEXT M : MAX = - Q2 : MIN = Q2
17345 FOR M = Q1 TO NP : Q3 = Y(M) : IF DIR > QO THEN Q3 = X(M)
17350 IF MAX < Q3 THEN MAX = Q3
17355 IF MIN > Q3 THEN MIN = Q3 : N = M
17360 NEXT M : MXMN = MAX - MIN : NOW = MIN : IM = N - Q1 : IF IM < Q1 THEN IM = NP
17365 IP = N + Q1 : IF IP > NP THEN IP = Q1
17375 M = 17395 : IF DIR > Q0 THEN M = 17420
17380 IF TYPE = Q1 THEN COLOR CLO
17385 GOTO 17615
17390 REM Horizontal.................
17395 IF S(N) = Q2 OR S(N) = Q0 THEN Q3 = X(N) : GOTO 17405
17400 Q3 = (NOW - T(N)) / S(N)
17405 IF S(IM) = Q2 OR S(IM) = Q0 THEN Q4 = X(IM) : GOTO 17445
17410 Q4 = (NOW - T(IM)) / S(IM) : GOTO 17445
17415 REM Vertical...................
17420 IF S(N) = Q2 THEN Q3 = Y(N) : GOTO 17430
17425 Q3 = NOW * S(N) + T(N)
17430 IF S(IM) = Q2 THEN Q4 = Y(IM) : GOTO 17445
17435 Q4 = NOW * S(IM) + T(IM)
17440 REM ...........................
17445 IF TYPE > Q1 THEN 17480
17450 REM BAR-FILL ...................
17455 IF DIR = Q0 THEN PLOT Q3, NOW : DRAWTO Q4, NOW
17460 IF DIR > Q0 THEN PLOT NOW, Q3 : DRAWTO NOW, Q4
17465 Q3 = (NOW - MIN) / MXMN : Q4 = INT(SPA * (2 * FAC * Q3 + 1 - FAC))
17470 NOW = NOW + Q1 + Q4 : GOTO 17615
17475 REM PIXEL - FILL(PF)............
17480 Q5 = INT(ABS(Q4 - Q3)) : DL = SGN(Q4 - Q3) : L = Q3 : R = FAC * (NOW - MIN) / MXMN
17485 IF TYPE< >3 THEN 17520
17490 REM CHECKERBOARD ..............
17495 Q3 = CLO : Q4 = CHI : R = INT(L + NOW + 0.5) : IF R = 2 * INT(R/2) THEN Q3 = CHI : Q4 = CLO
17500 R = DL + DL + 0.5
17505 IF DIR = 0 THEN FOR K = Q1 TO Q5 / 2 : COLOR Q 3 : PLOT L, NOW : COLOR Q4 : PLOT L + DL, NOW : L = INT(L + R) : NEXT K
17506 IF DIR = 1 THEN FOR K = Q1 TO Q5 / 2 : COLOR Q 3 : PLOT NOW, L : COLOR Q4 : PLOT NOW, L + DL : L = INT(L + R) : NEXT K
17510 IF Q5 = 2 * INT(Q5 / 2) THEN 17600
17511 IF DIR = 0 THEN COLOR Q3 : PLOT L, NOW
17512 IF DIR = 1 THEN COLOR Q3 : PLOT NOW, L
17515 GOTO 17600
17520 IF FAC < Q1 AND DIR = Q0 THEN 17540
17525 IF FAC < Q1 AND DIR > Q0 THEN 17555
17530 IF FAC >= Q1 AND DIR = Q0 THEN 17570
17535 IF FAC >= Q1 AND DIR > Q0 THEN 17585
17540 FOR K = Q0 TO Q5 : COL = CLO : IF RND(Q0) < FAC THEN COL = CHI
17545 IF COL >= Q0 THEN COLOR COL : PLOT L, NOW
17550 L = L + DL : NEXT K : GOTO 17600
17555 FOR K = Q0 TO Q5 : COL = CLO : IF RND(Q0) < FAC THEN COL = CHI
17560 IF COL >= Q0 THEN COLOR COL : PLOT NOW, L
17565 L = L + DL : NEXT K : GOTO 17600
17570 FOR K = Q0 TO Q5 : COL = CLO : IF R * RND(Q0) > 0.5 THEN COL = CHI
17575 IF COL >= Q0 THEN COLOR COL : PLOT L, NOW
17580 L = L + DL : NEXT K : GOTO 17600
17585 FOR K = Q0 TO Q5 : COL = CLO : IF R * RND(Q0) > 0.5 THEN COL = CHI
17590 IF COL >= Q0 THEN COLOR COL : PLOT NOW, L
17595 L = L + DL : NEXT K : GOTO 17600
17600 NOW = INT(NOW + Q1)
17605 REM Check for vertex point
17610 REM passover & end of polygon
17615 Q3 = Y(IP) : Q4 = Y(IM) : IF DIR > Q0 THEN Q3 = X(IP) : Q4 = X(IM)
17620 IF NOW <= Q3 THEN 17635
17625 IF Q3 = MAX THEN RETURN
17630 N = IP : IP = IP + Q1 : IF IP > NP THEN IP = Q1
17635 IF NOW <= Q4 THEN GOTO M
17640 IF = Q4 = MAX THEN RETURN
17645 IM = IM - Q1 : IF IM < Q1 THEN IM = NP
17650 GOTO M
17655 REM Line Drawing...............
17660 K = X(Q1) - X(Q0) : Q2 = ABS(K)
17665 L = Y(Q1) - Y(Q0) : Q3 = ABS(L)
17670 IF Q2 >= Q3 THEN N = Q2 : Q4 = SGN(K) : Q5 = L/Q2
17675 IF Q2 < Q3 THEN N = Q3 : Q5 = SGN(L) : Q4 = K/Q3
17680 Q2 = X(Q0) : Q3 = Y(Q0) : S(Q0) = CLO : S(Q1) = CHI : IP = QO
17685 FOR M = Q1 TO N : COLOR S(IP) : PLOT Q2, Q3 : Q2 = Q2 + Q4 : Q3 = Q3 + Q5 : IP = Q1 - IP : NEXT M
17690 RETURN
17695 REM =============================

PROGRAM 2. Textured Graphics.

100 REM ===========================
105 REM = {5 SPACES} PICTURE Program {7 SPACES} =
107 REM = {8 SPACES} for the {12 SPACES} =
110 REM = {3 SPACES} POLYPAINT Subroutine {4 SPACES} =
120 REM ===========================
125 REM = {11 SPACES} by : {13 SPACES} =
130 REM = {8 SPACES} Phil Dunn {10 SPACES} =
140 REM = {6 SPACES} 12 Monroe Ave. {7 SPACES} =
150 REM = {3 SPACES} Hicksville, NY 11801 {4 SPACES} =
160 REM =============================
220 REM Set the graphics mode
230 REM and the color registers…
240 GRAPHICS 7 + 16
250 SETCOLOR 0, 5, 6 : REM C. 1 = MAROON
260 SETCOLOR 1, 10, 8 : REM C. 2 = GREEN
270 SETCOLOR 2, 9, 10 : REM C. 3 = WHITE, WINDO
280 SETCOLOR 4, 8, 8 : REM C. 0 = BLUE, BACKG.
290 REM =============================
300 DIM X(15), Y(15), S(15), T(15)
310 POLYPAINT = 17315
330 REM =============================
340 REM Read areas and fill them in
350 REM ............................
360 REM First read the TYPE of painting to be done for this area.
370 A = 0
380 READ TYPE
390 A = A + 1
400 REM Test for end of data
410 IF TYPE = 999 THEN 1020
420 REM Now go to proper line to read the rest of the data for this TYPE.
430 IF TYPE = 4 THEN 820
440 IF TYPE = 3 THEN 730
450 IF TYPE = 2 THEN 620
460 IF TYPE< >1 THEN ? "TYPE = "; TYPE, "for AREA = "; A : STOP
470 REM ............................
480 REM Read data for TYPE 1
490 REM bar painting.
500 READ DIR
510 IF DIR< >0 AND DIR< >1 THEN ? "DIR = "; DIR, " for AREA = "; A : STOP
520 READ SPA
530 IF SPA < 0 THEN ? "SPA = "; SPA, " for AREA = "; A : STOP
540 READ FAC
550 IF FAC < -1 OR FAC > 1 THEN ? " FAC = " ; FAC, " for AREA = "; A : STOP
560 READ CLO
570 IF CLO < -1 OR CLO > 3 THEN ? " CLO = ";CLO, " for AREA = "; A : STOP
580 GOTO 920
590 REM ............................
600 REM Read data for TYPE 2
610 REM pixel painting.
620 READ DIR
630 IF DIR< >0 AND DIR< >1 THEN ? " DIR = "; DIR, " for AREA = "; A : STOP
640 READ FAC
650 IF FAC < 0 THEN ? " FAC = "; FAC, " for AREA = "; A : STOP
660 READ CLO
670 IF CLO < -1 OR CLO > 3 THEN ? " CLO = "; CLO, " for AREA = "; A : STOP
680 READ CHI
690 IF CHI < -1 OR CHI > 3 THEN? " CHI = "; CHI, " for AREA = "; A : STOP
700 GOTO 920
710 REM ............................
720 REM Input for TYPE 3
725 REM checkerboard painting.
730 READ DIR
735 IF DIR< >0 AND DIR< >1 THEN? " DIR = "; DIR, " for AREA = "; A : STOP
740 READ CLO
750 IF CLO < 0 OR CLO > 3 THEN ? " CLO = "; CLO, " for AREA = "; A : STOP
760 READ CHI
770 IF CHI < 0 OR CHI > 3 THEN ? " CHI = "; CHI, " for AREA = "; A : STOP
780 GOTO 920
790 REM ............................
800 REM Input for TYPE 4,
810 REM to draw a line.
820 READ CLO
830 IF CLO < 0 OR CLO > 3 THEN ? " CLO = "; CLO, " for AREA = "; A : STOP
840 READ CHI
850 IF CHI < 0 OR CHI > 3 THEN ? " CHI = " CHI, " for AREA = "; A : STOP
860 READ X, Y : X(0) = X : Y(0) = Y
870 READ X, Y : X(1) = X : Y(1) = Y
880 GOSUB POLYPAINT
890 GOTO 380
900 REM .............................
910 REM Now read the polygon perimeter data
920 READ NP : REM Number of points
930 IF NP < 3 THEN ? "NP = ";NP, "for AREA = ";A : ST OP
940 FOR N = 1 TO NP
950 READ X, Y
960 X(N) = X
970 Y(N) = Y
980 NEXT N
990 REM Now let the subroutine fill it in
1000 GOSUB POLYPAINT
1010 GOTO 380
1020 REM ============================
1030 REM = {3 SPACES}Scene from the book {4 SPACES} =
1040 REM = 'Stranger By The River' =
1050 REM = {4 SPACES}by Paul Twitchell {5 SPACES} =
1060 REM ============================
1070 REM MOUNTAIN
1080 DATA 3, 1, 3, 2, 6, 54, 42, 68, 30, 85, 22, 110, 35, 118, 45, 54, 45
1090 DATA 2, 1, 9, 2, -1, 5, 54, 42, 68, 30, 85, 22, 85, 45, 54, 45
1100 DATA 2, 1, 2, -1, 2, 4, 85, 22, 110, 35, 118, 45, 85, 45
1110 REM MOUNTAIN TOP
1120 DATA 2, 0, 1, 3, -1, 6, 85, 22, 98, 29, 95, 30, 88, 32, 78, 29, 74, 27
1130 REM LOWLANDS
1140 DATA 3, 0, 3, 2, 3, 0, 45, 80, 40, 159, 45
1150 DATA 2, 0, .5, -1, 2, 3, 0, 45, 80, 40, 159, 45
1180 REM FOREGROUND
1190 DATA 3, 0, 2, 0, 4, 0, 69, 159, 66, 159, 95, 0, 95
1200 DATA 2, 0, 3, -1, 2, 4, 0, 80, 159, 80, 159, 95, 0, 95
1210 REM RIVER
1230 DATA 3, 0, 0, 3, 12, 0, 50, 159, 50, 159, 66, 140, 68, 125, 70, 105, 74, 80, 77, 60, 78, 47, 78, 40, 7, 7, 25, 75, 0, 69
1260 DATA 1, 0, 3, 1, 3, 6, 0, 45, 159, 45, 159, 60, 90, 75, 40, 75, 0, 60
1270 REM LEFT TREE TOP
1280 DATA 2, 0, .2, 2, 0, 12, 25, 25, 37, 34, 33, 36, 36, 40, 31, 43, 33, 55, 18, 59, 5, 50, 13, 42, 8, 37, 16, 34, 12, 30
1310 REM RIGHT TREE TOP
1320 DATA 2, 0, .2, 2, 0, 8, 130, 32, 149, 39, 145, 46, 153, 56, 135, 68, 116, 61, 122, 52, 115, 47
1340 REM LEFT TREE TRUNK
1350 DATA 1, 0, 0, 0, 1, 6, 11, 80, 16, 56, 19, 52, 21, 57, 17, 81, 14, 83
1360 REM RIGHT TREE TRUNK
1370 DATA 1, 0, 0, 0, 1, 6, 131, 83, 130, 65, 133, 59, 136, 65, 141, 82, 136, 85
1380 REM END OF DATA
1390 DATA 999
1400 REM ============================
1410 REM Human figures…
1420 REM Paul
1430 COLOR 3
1440 XX = 55
1450 YY = 80
1460 PLOT XX - 1, YY + 3 : DRAWTO XX - 1, YY + 8
1470 PLOT XX, YY : DRAWTO XX, YY + 8
1480 PLOT XX + 1, YY + 3 : DRAWTO XX + 1, YY + 8
1490 PLOT XX + 4, YY + 4 : DRAWTO XX + 4, YY + 8
1500 PLOT XX + 1, YY : PLOT XX + 1, YY + 1
1510 PLOT XX + 2, YY + 4 : PLOT XX + 3, YY + 4
1520 PLOT XX + 3, YY + 5 : PLOT XX + 3, YY + 6
1530 PLOT XX + 2, YY + 6 : PLOT XX + 2, YY + 7
1540 PLOT XX + 5, YY + 8
1550 PLOT XX + 1, YY : PLOT XX + 1, YY + 1
1560 PLOT XX + 2, YY + 4 : PLOT XX + 3, YY + 4
1570 REM Rebezar
1580 COLOR 1
1590 XX = 65
1600 YY = 70
1610 PLOT XX - 1, YY + 2 : DRAWTO XX - 1, YY + 13
1620 PLOT XX, YY : DRAWTO XX, YY + 10
1630 PLOT XX + 1, YY : DRAWTO XX + 1, YY + 10
1640 PLOT XX + 2, YY + 2 : DRAWTO XX + 2, YY + 13
1650 PLOT XX + 5, YY + 1 : DRAWTO XX + 5, YY + 13
1660 PLOT XX - 4, YY + 1 : PLOT XX - 3, YY + 2
1670 PLOT XX - 2, YY + 2 : PLOT XX + 3, YY + 3
1680 PLOT XX + 4, YY + 4
1690 GOTO 1690
1700 REM ============================

PROGRAM 3. Textured Graphics.

100 REM =============================
105 REM = {5 SPACES} PALETTE Program {7 SPACES} =
110 REM = A Color-Texture Development =
120 REM = Utility Program For The =
130 REM = {3 SPACES}POLYPAINT Subroutine {4 SPACES} =
140 REM =============================
145 REM = {11 SPACES}by : {13 SPACES} =
150 REM = {8 SPACES}Phil Dunn{10 SPACES} =
160 REM = {6 SPACES}12 Monroe Ave. {7 SPACES} =
170 REM = {3 SPACES}Hicksville, NY 11801{4 SPACES} =
180 REM =============================
240 DIM A$(2), X(4), Y(4), S(4), T(4), U(50)
245 DIM HU(3), LU(3)
250 POLYPAINT = 17315
260 REM =============================
270 REM Input mode & scale palette
280 GRAPHICS 0
290 ? "Which Graphics MODE (3 - 8)";
300 TRAP 290 : INPUT MODE
310 IF MODE < 3 OR MODE > 8 THEN 290
320 GRAPHICS MODE
325 POKE 752, 1 : REM Blank Cursor
330 IF MODE = 3 THEN E = 0.25 : F = 0.25
340 IF MODE = 4 OR MODE = 5 THEN E = 0.5 : F = 0.5
350 IF MODE = 6 OR MODE = 7 THEN E = 1 : F = 1
360 IF MODE = 8 THEN E = 2 : F = 2
370 REM =============================
372 REM Initial color assignment…
374 HU(0) = 0 : LU(0) = 8 : REM = WHITE
376 HU(1) = 5 : LU(1) = 8 : REM = RED
378 HU(2) = 10 : LU(2) = 6 : REM = GREEN
380 HU(3) = 8 : LU(3) = 8 : REM = BLUE
390 SETCOLOR 0, HU(1), LU(1)
400 SETCOLOR 1, HU(2), LU(2)
410 SETCOLOR 2, HU(3), LU(3) : REM WINDOW
420 SETCOLOR 4, HU(0), LU(0) : REM BACKGR
430 REM =============================
440 REM Primary colors numbers
450 COLOR 1
460 REM Number 1…
470 PLOT 3 * E, 22 * F
480 DRAWTO 3 * E, 28 * F
490 REM Number 2…
500 PLOT 19 * E, 22 * F
510 DRAWTO 21 * E, 22 * F
520 PLOT 22 * E, 23 * F
530 DRAWTO 19 * E, 28 * F
540 DRAWTO 22 * E, 28 * F
550 REM Nunber 3…
560 PLOT 37 * E, 22 * F
570 DRAWTO 40 * E, 22 * F
580 DRAWTO 40 * E, 28 * F
590 DRAWTO 37 * E, 28 * F
600 PLOT 38 * E, 25 * F
610 DRAWTO 40 * E, 25 * F
620 REM =====================
630 REM Display Primary Colors
640 NP = 4 : TYPE = 1 : DIR = 0 : SPA = 0 : FAC = 0
650 FOR I = 1 TO 3
660 CLO = I
670 FOR J = 1 TO 4
680 READ X, Y : X(J) = X * E : Y(J) = Y * F
690 NEXT J
700 GOSUB POLYPAINT
710 NEXT I
720 REM =============================
730 REM Display Secondary Colors
740 TYPE = 3 : REM Checkerboard
745 DIR = 0
750 FOR I = 1 TO 6
760 FOR J = 1 TO 4
770 READ X, Y : X(J) = X * E : Y(J) = Y * F
780 NEXT J
790 IF I <= 3 THEN CLO = 0 : CHI = 1
800 IF I = 4 THEN CLO = 1 : CHI = 2
810 IF I = 5 THEN CLO = 1 : CHI = 3
820 IF I = 6 THEN CLO = 2 : CHI = 3
830 GOSUB POLYPAINT
840 NEXT I
850 REM ============================
860 REM Areas for primary colors.…
870 DATA 0, 45, 0, 30, 15, 30, 15, 45
880 DATA 18, 45, 18, 30, 33, 30, 33, 45
890 DATA 36, 45, 36, 30, 51, 30, 51, 45
900 REM Areas for secondary colors..
910 DATA 0, 20, 0, 5, 15, 5, 15, 20
920 DATA 18, 20, 18, 5, 33, 5, 33, 20
930 DATA 36, 20, 36, 5, 51, 5, 51, 20
940 DATA 0, 70, 0, 55, 15, 55, 15, 70
950 DATA 18, 70, 18, 55, 33, 55, 33, 70
960 DATA 36, 70, 36, 55, 51, 55, 51, 70
970 REM Connect the colors
980 DATA 8, 30, 8, 20, 8, 45, 8, 55, 12, 45, 22, 55
990 DATA 26, 30, 26, 20, 22, 45, 12, 55, 28, 45, 39, 55
1000 DATA 44, 30, 44, 20, 44, 45, 44, 55, 40, 45, 29, 55
1010 REM Palette Display Areas.......
1020 DATA 60, 35, 60, 0, 105, 0, 105, 35
1030 DATA 115, 35, 115, 0, 159, 0, 159, 35
1040 DATA 60, 75, 60, 40, 105, 40, 105, 75
1050 DATA 115, 75, 115, 40, 159, 40, 159, 75
1060 REM ============================
1070 REM Connect the colors
1080 FOR I = 1 TO 3
1090 COLOR I
1100 FOR J = 1 TO 3
1110 READ X1, Y1, X2, Y2
1120 PLOT X1 * E, Y1 * F
1130 DRAWTO X2 * E, Y2 * F
1140 NEXT J : NEXT I
1150 REM ============================
1160 COLOR 1
1170 REM Number the palette areas…
1180 REM Number 1
1190 PLOT 57 * E, 15 * F
1200 DRAWTO 57 * E, 25 * F
1210 REM Number 2
1220 PLOT 109 * E, 15 * F
1230 DRAWTO 112 * E, 15 * F
1240 DRAWTO 113 * E, 17 * F
1250 DRAWTO 109 * E, 25 * F
1260 DRAWTO 113 * E, 25 * F
1270 REM Number 3
1280 PLOT 54 * E, 55 * F
1290 DRAWTO 58 * E, 55 * F
1300 DRAWTO 58 * E, 65 * F
1310 DRAWTO 54 * E, 65 * F
1320 PLOT 55 * E, 60 * F
1330 DRAWTO 58 * E, 60 * F
1340 REM Number 4
1350 PLOT 110 * E, 57 * F
1360 DRAWTO 110 * E, 60 * F
1370 DRAWTO 113 * E, 60 * F
1380 PLOT 113 * E, 55 * F
1390 DRAWTO 113 * E, 65 * F
1400 NP = 4
1410 REM ======================
1420 REM = NOTE : TO RESTART THE{4 SPACES} =
1430 REM = INPUT SEQUENCE AT ANY{4 SPACES} =
1440 REM = TIME BACK TO THE 'AREA' =
1450 REM = INPUT REQUEST, RETURN{4 SPACES} =
1460 REM = WITH THE VALUE 99. {7 SPACES} =
1470 REM ============================
1480 ? "Which AREA to use (0 - 4)";
1490 TRAP 1480 : INPUT A
1500 IF A < 0 OR A > 4 THEN 1480
1505 IF A = 0 THEN 2140
1510 RESTORE 1010 + A * 10
1520 FOR I = 1 TO 4
1530 READ X, Y : X(I) = INT(X * E) : Y(I) = INT(Y * F)
1540 NEXT I
1550 REM ============================
1560 ? " What painting TYPE (1, 2, or 3),"
1570 ? " Bar, pixel, or checkerboard";
1580 TRAP 1560 : INPUT TYPE
1590 IF TYPE = 99 THEN 1480
1600 IF TYPE < 1 OR TYPE > 3 THEN 1560
1610 IF TYPE = 2 THEN 1850
1620 IF TYPE = 3 THEN 2020
1630 REM
1640 REM Bar painting input…
1650 ? "HORIZ. or VERTICAL Bars (0 or 1)";
1660 TRAP 1650 : INPUT DIR
1670 IF DIR = 99 THEN 1480
1680 IF DIR< >0 AND DIR< >1 THEN 1650
1690 ? "SPACES between bars, >= 0 ";
1700 TRAP 1690 : INPUT SPA
1710 IF SPA = 99 THEN 1480
1720 IF SPA < O THEN 1690
1730 ? "Space VARIABILITY (-1 to +1)";
1740 TRAP 1730 : INPUT FAC
1750 IF FAC = 99 THEN 1480
1760 IF FAC < -1 OR FAC > 1 THEN 1730
1770 ? "COLOR register (0 - 3)";
1780 TRAP 1770 : INPUT CLO
1790 IF CLO = 99 THEN 1480
1800 IF CLO < O OR CLO > 3 THEN 1770
1810 GOSUB POLYPAINT
1820 GOTO 1480
1830 REM =============================
1840 REM PIXEL Painting...
1850? "HORIZ. or VERTICAL Sweep (O or 1)";
1860 TRAP 1850 : INPUT DIR
1870 IF DIR = 99 THEN 1480
1880 IF DIR< >O AND DIR< >1 THEN 1850
1890 ? "BLENDING Factor, 0 - 0.99, or >= 1";
1900 TRAP 1890 : INPUT FAC
1910 IF FAC = 99 THEN 1480
1920 IF FAC < 0 THEN 1890
1930 ? "LOW Color (-1 to 3)";
1940 TRAP 1930 : INPUT CLO
1950 IF CLO = 99 THEN 1480
1960 ? "HIGH Color (-1 to 3)";
1970 TRAP 1960 : INPUT CHI
1980 IF CHI = 99 THEN 1480
1990 GOSUB POLYPAINT
2000 GOTO 1480
2010 REM = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2015 REM CHECKERBOARD Painting…
2020 ? "HORIZ. or VERTICAL Sweep (0 or 1)";
2024 TRAP 2020 : INPUT DIR
2026 IF DIR = 99 THEN 1480
2028 IF DIR< >0 AND DIR< >1 THEN 2020
2030 ? "First Color (0 to 3)";
2040 TRAP 2030 : INPUT CLO
2050 IF CLO = 99 THEN 1480
2055 IF CLO < 0 OR CLO > 3 THEN 2030
2060 ? "Alternate Color (0 to 3)";
2070 TRAP 2060 : INPUT CHI
2080 IF CHI = 99 THEN 1480
2085 IF CHI < 0 OR CHI > 3 THEN 2060
2090 GOSUB POLYPAINT
2100 GOTO 1480
2110 REM = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2130 REM Redefine the colors…
2140 ? "Reg. No. = Hue, Luminance"
2145 ? "0 = "; HU(0); ","; LU(0), "1 = "; HU(1); "," LU(1), "2 = "; HU(2); ","; LU(2), "3 = "; HU(3); ","; LU(3)
2150 ? "Which COLOR Register (0 - 3) ";
2160 TRAP 2140 : INPUT I
2170 IF I = 99 THEN 1480
2180 IF I < 0 OR I > 3 THEN 2140
2190 K = HU(I) : L = LU(I) : GOTO 2230
2200 IF STRIG(0) = 0 THEN 2140
2210 IF HU(I) = INT(K) AND LU(I) = 2 * INT(L / 2) THEN 2260
2220 HU(I) = INT(K) : LU(I) = 2 * INT(L / 2)
2230 ? "Reg. "; I; " = Hue "; HU(I) ; ", Luminan ce "; LU(I)
2240 J = I - 1 : IF J < 0 THEN J = 4
2250 SETCOLOR J, HU(I), LU(I)
2255 HU(I) = INT(K) : LU(I) = 2 * INT(L / 2)
2260 IF STICK(0) = 7 THEN K = K + 0.1 : IF K > 16 THEN K = 0
2270 IF STICK(0) = 11 THEN K = K - 0.1 : IF K < 0 THEN K = 15
2280 IF STICK(0) = 14 THEN L = L + 0.2 : IF L > 16 THEN L = 0
2290 IF STICK(0) = 13 THEN L = L - 0.2 : IF L < 0 THEN L = 14
2292 REM Joystick 0 controls :
2293 REM Left - Right changes hue
2294 REM Foward - Back changes luminance
2295 REM Press Trigger to fix selection
2300 GOTO 2200

Return to Table of Contents | Previous Section | Next Section