Add to your holiday pleasure by decking out these cybernetic trees using this PILOT program. It comes complete with colored lights, a scrolling message, and Jingle Bells in one-part harmony. To do this we will use some innovative techniques that will expand your understanding of PILOT programming.
Let's wander through the listing. After the title lines, we find a J:ump command at line 50. As you'll see, we U:se *PARSE, *COLORS, and *LLOOP over and over as the program operates. Each time PILOT hits a U:se or J:ump command, it goes to the first instruction (in this case, line 1) and reads every line until it finds the required module name. Putting often-used modules near the front of the listing makes the program run faster. PILOT is fast. Even putting the modules at the end of the 225 lines of this program did not noticeably slow down the song, but this programming concept makes it run even faster.
Now J:ump to *DRAWTREES (lines 1000-1540). This module uses a mirror-image concept to draw two trees for nearly the price of one. Notice that the first tree is drawn at X = -40, Y = 32 (lines 1050-1070) and the second at X = 40, Y = 32 (lines 1080 & 1090). This means that the Y positions in both trees are the same while the X positions differ by only the sign. As a result, we can draw in the same location in both trees by using positive and negative values of the same number for the X position.
We use this concept to draw the stars and balls with a single position and *MIRRORSTAR and *MIRRORBALL modules (lines 2100-2160 and 2400-2460). The C:ompute instruction in line 2140 changes the sign of #X by multiplying it by -1. Simple and neat!
Back to the -TREE module. PILOT graphics uses only four colors. Although it calls these RED, BLUE, YELLOW and ERASE, PILOT really looks at a memory location each time it draws in a PEN color to see what color should be used. Normally, of course, it finds a number in BLUE which means blue. In line 1650, we force a different number into location 708 to tell PILOT that we want it to draw in green whenever it hits a BLUE command. Line 1760 sets the RED pen to brown. Location 709 controls YELLOW and 711 the ERASE commands. You might want to experiment (or refer to ANTIC #3 or Atari's BASIC Manual) to see how these "registers" work.
After we finish drawing and decorating the trees, we end up at line 1530, which C:omputes a string into the $MESSAGE variable. I had to double space the message because the A:ccept command, used later in the '-PARSE module, automatically inserts blanks at the start and end of each string. At present, there doesn't seem to be a good way around this restriction, but we end up with a nice message anyway. Although the printer doesn't show it, an ESCAPE character is placed between each word to preserve word spacing. This is necessary because A:ccept also condenses all multiple spaces to single spaces. The ESCAPE character will not print the message: you enter it by pressing the ESCAPE key twice.
You'll probably want to enter your own message. Just type [space] [ESC] [space] between each word and two ESC's at the end. Also, keep the message less than 255 letters long.
When finished drawing the trees, we J:ump to *MAINLOOP (lines 600-699). This module is the workhorse, it plays the song, calls for the message and color changes. It's rather long but really simple to type in. All the '-LLOOP commands are on multiples of three--just type it once and use Atari's wonderful screen editor to change the line number. Ditto for the SO:ound and PA:use commands.
*MAINLINE does one other important thing. Since the program doesn't use any keystrokes, the ATARI would soon begin changing screen colors. The C:ompute in line 688 puts a 0 in location 77 to tell the computer that a key has been pressed even when none was. This delays the "attract" mode each time through the loop.
The next module, *LLOOP, simply calls *PARSE and *COLORS. The *PARSE module breaks strings into into individual characters ("parsing"). As you type it, remember the two right arrows in line 150 and 37 in line 180. The arrows tell the MS: command to skip a character for each arrow before looking for a M:atch.
After skipping 37 characters in line 180, the MS:$RIGHT in line 190 forces the first 37 letters into the $LEFT string which we T:ype in line 210. That's the billboard section of the message. By repeatedly stripping off the first character and adding it to the end of the message, we make the words march across the text window at the bottom of the graphic screen. Oh yes, C:@B656? That's a memory location which tells PILOT to T:ype the message on the second line of the text window. Without that, each message would T:ype on a different line and would scroll off the top. (Just for fun, the lines are numbered 0 through 3.)
Although *PARSE is busy, *COLORS (lines 300-400) is a speedy devil too. By C:omputing different values for location 709, *COLORS changes the color in the YELLOW pen. This flashes red, blue, brown, and yellow in the stars and balls.
To close, let me answer two questions. How do I get PILOT to number the modules in different series? Simple. As I build a program, each module is stored in a different disk file. After all modules are debugged, each is LOADed into memory and RENumbered in a number series which doesn't overlap with any other module. It's then SAVEd, memory NEWed and the next module loaded. After all are RENumbered, all are LOADed into a complete program and SAVEd in a different file.
Last, how do I get those big letters in the R:emarks? Just enter a control N (a bar symbol) right after the colon.
Best wishes for a happy holiday season watching your cybernetic trees!
by Ken Harms