Housepainter
Inverted Video On The Commodore 64
Jim Butterfield, Associate Editor
By fooling the eye with reverse characters, you can make a single-colored object appear to pass over a multicolored background—without sprites or machine language. The technique can also be adapted to the VIC-20, Plus/4, and 16.
If you've ever played around with video effects on the Commodore 64, you know that ordinary video involves one background color and a choice of printing colors. In other words, you can print green, red, and yellow on a white background, but you can't go the other way and print, say, white on a multicolored background. However, you can use an easy trick to get the same effect.
Here's the objective: Assume you want to move an object over a multicolored background. Maybe it's a small black bug flying over terrain which is green (grass), blue (water), and white (ice). You don't want the bug to change color as it passes these areas; it must stay black. Yet the 64 seems to be set up to work the opposite way. The foreground color may change from one character cell to another, but the background must be one solid color across the whole screen.
There are many special features you could use to get around this problem, of course. Extended color mode allows you a choice of backgrounds; it's attractive for many uses and too little used by most programmers. Sprites may be placed anywhere on the screen over existing character patterns, giving a color-over-color effect. You could even use a split-screen technique to create multiple backgrounds.
But you can also achieve the effect without resorting to special features. To invert the screen effects, we must invert our thinking.
Holes In The Sky
When I was a small child, I used to think that stars were tiny holes in a black curtain that covered the night sky. In other words, they were points of light shining through. I couldn't tell the difference between a white light source set against a black background and a white background shining through gaps in a black foreground.
That's the technique we'll use here. Since the 64 has one background color and a choice of many foreground colors, let's flip them over to create one "foreground" color against a mixture of many "background" colors. We'll have to work in reverse characters to switch background and foreground, but that's no hardship.
Let's try a simple example program which moves a white letter A over a multicolored background:
100 PRINT CHR$(144);CHR$(147) 110 POKE 53281, 1
This clears the screen (147) and sets the colors—background to white (53281) and cursor to black (144).
120 FOR J=0 TO 39 130 POKE 1024+J, 160 140 POKE 55296+J, RND(l)*14+2 150 NEXT J
This POKEs reverse spaces (160) into the top line of screen memory, and puts random colors into color memory beginning at 55296. Note that we need reverse space characters. Ordinary spaces would show the background color only, but the reversed ones show the random foreground colors. These colors will seem to be background, because they won't change.
160 FOR J=0 TO 38 170 POKE 1024+J, 160 180 POKE 1025+J, 129 190 FOR K=l TO 100 200 NEXT K, J
These final lines move the white letter A from left to right across the top of the screen. The screen code for A is a value of 1, but the program adds 128 to get a value of 129 for a reverse A. As the A moves to its new position, it is erased from its old spot by POKEing a reverse space there (160).
An Optical Illusion
We know the program moves a reverse A along the top line of the screen. And we know that each character is a different, random, color as we print it. But when we enter RUN and watch the program work, we see a white A moving across the top. Why? Because we're really seeing the white background color "peeking through" the reversed foreground. The optical illusion is complete: A single foreground color seems to be moving across a multicolored background.
Let's use this principle in a short program called "House-painter." It's part game, part puzzle, and part coordination exercise. You have five minutes to paint the house, using the four special function keys to move the brush. You are not allowed to paint over any area twice, so be careful and plan your work. By the way, it is possible to succeed, although you may have a lot of trouble at first.
The program is entirely in BASIC, which accounts for the delay as it sets up the screen. The house is drawn with several rectangles defined in DATA statements. Note that the characters showing the time in the upper left of the screen seem normal, but are really in reverse video. The white is the background color peeking through. Similarly, the white paint itself and the circular brush are really background colors. That's how the white brush can move inside a red shed and across a yellow house: It's inverted video.
Housepainter
Please refer to "COMPUTE!'S Guide to Typing in Programs" before entering this listing.
100 PRINT "{CLR}{DOWN}HOUSEPAI NTER{2 SPACES}-{2 SPACES}J IM BUTTERFIELD" :rem 228 110 PRINT "{3 SPACES}TRY TO PA INT THE HOUSE USING THE :rem 43 120 PRINT "FUNCTION KEYS TO MO VE THE BRUSH. :rem 81 130 PRINT "{3 SPACES}YOU'RE NO T ALLOWED TO PAINT OVER :rem 82 140 PRINT "AN AREA … SO DON' T PAINT YOURSELF :rem 105 150 PRINT "INTO A CORNER. :rem 183 160 PRINT "{3 SPACES} YOU HAVE {SPACE} FIVE MINUTES. {2 SPACES} LEAVE THE:rem 50 170 PRINT "PAINT BRUSH IN THE {SPACE} RED SHED WHEN :rem 240 180 PRINT "YOU'RE FINISHED. {2 SPACES} PRESS ANY KEY TO GO. :rem 64 190 FOR J=1 TO 1E4:GET X$:IF X $="" THEN NEXT J :rem 154 200 DATA 3,0,24,0,39 :rem 193 210 DATA 7,10,20,10,30 :rem 27 220 DATA 7,8,9,15,18 :rem 213 230 DATA 3,15,17,13,15 :rem 42 240 DATA 3,16,18,25,27 :rem 51 250 DATA 3,17,20,19,21 :rem 43 260 DATA 2,18,20,31,33 :rem 41 270 DATA -1 :rem 17 300 PRINT CHR$(159) ;CHR$(147); "WAIT" ;CHR$(142);CHR$(8):P OKE 53281,1 :rem 160 310 C0=55296 :S0=1024 :rem 16 320 REM :rem 121 330 READ C:IF C<0 GOTO 400 :rem 58 340 READ V1, V2, H1, H2 :rem 57 350 FOR J=V1*40 TO V2*40 STEP {SPACE}40 :rem 116 360 FOR X=C0+J+H1 TO C0+J+H2 :rem 209 370 POKE X, C :rem 144 380 NEXT X, J :rem 168 390 GOTO 330 :rem 107 400 FOR J=S0+4 TO S0+999:POKE {SPACE}J,160:NEXT J :rem 25 410 FOR J=C0 TO C0+999 :rem 98 420 IF (PEEK(J)AND15)=7 THEN N =N+1 :rem 71 430 NEXT J :rem 32 440 TI$="000000" :rem 250 450 V=19:H=32 :rem 186 460 POKE V0*40+H0+S0, 160 :rem 241 470 POKE V*40+H+S0, 209:rem 150 480 V0=V:H0=H :rem 236 490 PRINT CHR$(19);CHR$(18);TI $ :rem 216 500 IF TI$> "000499" GOTO 680 :rem 116 510 K=PEEK(203) :rem 41 520 GET K$:K1=ASC(K$+CHR$(0)) :rem 29 530 IF K1=133 THEN V1=-1:rem 200 540 IF K1=134 THEN H1=-1:rem 188 550 IF K1=135 THEN H1=1:rem 145 560 IF K1=136 THEN V1=1:rem 161 570 IF K<64 GOTO 590 :rem 243 580 V1=0:H1=0 :rem 177 590 V=V0+V1:H=H0+H1 :rem 68 600 P=C0+V*40+H:IF P=P9 GOTO 4 90 :rem 205 610 C=PEEK(P) AND15 :rem 22 620 IF C<>7 AND C<>2 GOTO 490 :rem 179 630 IF C9=7 THEN POKE P9, 1:N=N -1 :rem 205 640 P9=P :C9=C :rem 230 650 IF C<>2 OR N>0 GOTO 460 :rem 73 660 PRINT " WINNER! " :rem 97 670 END :rem 116 680 PRINT " YOU MISSED" ;STR$(N ); " SQUARES" :rem 203