PROGRAMMING WITH A MUSICAL SPRITE
Last month, we began a program that moves a musical sprite with a joystick. Let's continue from the point where we placed a green quarter note on a musical treble clef staff.
We'll be able to play 41 notes, from two octaves below middle C to the fourth A above middle C. The 64's Programmer's Reference Guide provides the frequency values; from them we calculate POKEable values. First we must dimension the arrays.
200 DIMFU(41), FL(41), C(41)
FU() and FL() are the upper- and lower-frequency arrays that will hold the values to be POKEd into voice 1's frequency control registers. C() is the array for the colors that correspond to the musical notes.
Let's read the 41 decimal values and colors and calculate two POKEable values for each.
210 K = 256 : FORJ = 41 TO 1 STEP-1 : READ D, C(J) : FU(J) = INT(D/K) : FL(J) = D-FU(J)*K : NEXT 220 DATA 1072, 5, 1204, 2, 1351, 3, 1432, 4, 1607, 12, 1804, 6, 2025, 7, 2145, 5, 2408, 2, 2703, 3 225 DATA 2864, 4, 3215, 12, 3608, 6, 4050, 7, 4291, 5, 4817, 2, 5407, 3, 5728, 4, 6430, 12, 7216, 6 235 DATA 8101, 7, 8583, 5, 9634, 2, 10814, 3, 11457, 4, 12860, 12, 14435, 6, 16203, 7, 17167, 5 240 DATA 19269, 2, 21629, 3, 22915, 4, 25721, 12, 28871, 6, 32407, 7, 34334, 5, 38539, 2 250 DATA 43258, 3, 45830, 4, 51443, 12, 57743, 6
Now we define JS, the memory register for joystick port 2.
300 JS = 56320
Lines 310-390 form an infinite loop; the only way to break out is to press the Run/Stop key or to turn off the computer. First, PEEK at the joystick port to see what value is there (JD means Joystick Direction).
310 JD = PEEK(JS)
We need to check only for certain values that correspond to particular directions. To detect if the stick is pushed up, enter
320 IFJD = 126 THEN N = N-4 : IFN <49 THENN = 49
The note should move up when the stick is pressed up. N is the vertical position of the sprite on the screen (see lines 110 and 180). N must be decremented by four pixels for the sprite to move up a note.
We limit the value of N to keep the note on the screen. In this case, the top line's position has the value N = 49. Now look to detect a downward press.
330 IFJD = 125 THENN = N + 4 : IFN >209 THENN = 209
In this case N is incremented by 4 and the bottom line of the staff corresponds to a value of 209 for N.
We haven't moved the sprite yet; we've only assigned it a new vertical position. Let's look at the port again to detect a press of the fire button, which will sound a note.
340 IFJD = 111 THENGOSUB 400
Press the fire button and port 2 contains the value 111. We also want to detect if the joystick is pushed up or down with the button pressed. This sounds notes as it moves, with gliding arpeggios. GOSUB400 to play the note, assign a new vertical position to the sprite, and check vertical limits.
350 IFJD = 110THENGOSUB400 : N = N-4 :IFN<49 THENN = 49 360 IFJD = 109THENGOSUB400 : N = N + 4 : IFN>209 THENN = 209
Here's where we actually move the sprite to the new position N:
370 POKEV + 1, N : Q = INT(N/4-11)
V + 1 is sprite 1's vertical postion. Q is a calculated index to the color array. (Remember reading the color numbers in line 210?). The colors cycle through seven changes, then repeat.
Thus all Cs are green, all Ds are red, and so on. Now POKE the color number into sprite 1's color memory register.
380 POKEV + 39, C(Q)
End the main loop by returning to its beginning:
390 GOTO 310
To sound the note, POKE voice 1's frequency registers with the figures calculated in 210:
400 POKES, FL(Q) : POKES + 1, FU(Q)
S and S + 1 are the first two registers of the sound chip; they control voice 1's frequency. We now turn on the note in a rather strange way: by turning it off first. This, combined with our envelope (defined in line 20), ensures that our notes can sound either one at a time or as an arpeggio.
410 POKES + 4, 64 : POKES + 4,65 420 RETURN
When you run the program, try playing a tune with the joystick.