Flowering Vines

by Daniel Temkin 25. April 2010 21:40  

This is a C64 program which uses pseudographics to create a circuit board-like pattern of vines across the screen, starting in the upper left and flowing to the bottom right. Each vine randomly changes direction as it goes. It uses box-drawing characters for vines and circles for the fruit or flowers (or what have you).

It's my first crack at a C64 program -- in the last 20 years anyway. The difference in programming for this type of system vs. what I work with on a daily basis is astonishing. It requires unlearning every good programing practice I've used since college, in order to get something that will run in any resonable amount of time. It was a challenge keeping lines under 80 characters, using two-letter variable names (and trying to carry meaning in those two letters enough to keep track of what they represent), skimping on comments, keeping track of line numbers, etc. Luckily, since this is a short program that doesn't need this to run too fast, I was able to compromise between the two approaches. It's a little slower than I'd like, but I kept it pretty comprehensible; luckily we have emulators with Warp mode.

This is leading up to a C64 Glitch program that's in development now: more on that later.

Images from the program:



Multi-color version:



More C64 goodness to follow soon. This is all warming up for a C64 glitch program I'm working on now.

Here's the actual code:

100 print chr$(147) : rem clear screen

110 print "drawing..."

: rem constants
120 let c0 = 9216 : rem upper left block
125 let c1 = 25 : rem number of rows
130 let c2 = 40 : rem number of cols
135 let c3 = 55296 : rem upper left color

220 for co = 0 to 10
230 read a :let al(co) = a :rem left-facing images
240 next co
250 data 64,67,73,75,110,125,113,114,115,91,87

260 for co = 0 to 10
270 read a :let ar(co) = a :rem right-facing images
280 next co
290 data 64,67,74,85,91,109,112,107,113,114,91

300 for co = 0 to 10
310 read a :let au(co) = a :rem up-facing images
320 next co
330 data 66,74,93,109,125,107,113,114,115,91,87

340 for co = 0 to 10
350 read a :let ad(co) = a :rem down-facing images
360 next co
370 data 66,66,73,85,93,110,107,114,115,91,87

373 for co = 0 to 5
375 read a :let ab(co) = a :rem both-facing (up and left) images
377 next co
380 data 75,91,87,113,115,125

400 for a = c0 to c0 + (c1 * c2)
410 let pc = peek(a-1) :rem pc = prior char
412 let uc = peek(a-c2) :rem uc = upper char
415 let hl = 0 :rem hl = has left
417 let hu = 0 :rem hu = has up

420 for b = 0 to 10
425 if pc = ar(b) then hl = 1
430 if pc - 128 = ar(b) then hl = 1
435 next

440 for b = 0 to 10
443 if uc = ad(b) then hu = 1
445 if uc - 128 = ad(b) then hu = 1
447 next

:rem initial row and column
450 let rg = int(rnd(0)*20)
451 if rg = 0 then rg = 1
452 if rg = 2 then rg = 3
453 if a < c0 + c2 then goto 460 : rem if top row, choose upfacing
455 if (a - c0) / c2 = 0 then goto 480 : rem if left col, choose rightfacing
458 goto 495
460 let ri = int(rnd(0)*3)
465 if ri = 0 then let rg = 2
470 if ri > 0 then let rg = 4
475 goto 495
480 let ri = int(rnd(0)*3)
485 if ri = 0 then let rg = 0
490 if ri > 0 then let rg = 4

495 rh = int(rnd(0)*11) :rem random char indexer
500 rem get items for left or down facing items nearby
505 if hl = 1 and hu = 1 then goto 540
510 if hl = 1 then im = al(rh)
520 if hu = 1 then im = au(rh)
530 goto 590
540 rj = int(rnd(0)*6) :rem random char index
550 im = ab(rj)

590 if hu = 1 or hl = 1 then poke a, im
595 if (hu = 1 or hl = 1) and im = 87 then poke a + c3 - c0, 15

599 rem ordinary random chars
600 if rg = 0 then im = al(rh)
610 if rg = 1 then im = ar(rh)
620 if rg = 2 then im = au(rh)
630 if rg = 3 then im = ad(rh)
640 if rg >= 4 then im = 32 :rem space

700 if hl = 0 and hu = 0 then poke a, im :rem 128 + im for inverse
720 if hl = 0 and hu = 0 and im = 87 then poke a + c3 - c0, 15
730 next

800 poke 53272,(peek(53272)and15)or144
810 rem activate drawing

999 end