Colour Cycling Effects with Grids

This is a continuation in a series of posts about writing BBC Basic programs for the @bbcmicrobot twitter bot.

In the last post we looked at implementing effects on the BBC Micro using colour cycling with lines. This time we will look at similar effects but scrolling a grid.

Setting up the Grid

We will jump right into making a small program to draw vertical strips of different colours that we can animate with colour cycling.

First we will set the graphics mode.

   10 MODE 2

Then we will loop and draw a number of rectangles across the screen.

We set W to the number of rectangles we will draw

   20 W=64

Each rectangle will be made up from two triangles. We will draw this as a triangle strip so that two of the points will be shared with the previous rectangle.

To start things off we will set the location of the first two points at the bottom left and top left of the screen.

   30 MOVE 0,0
   40 MOVE 0,1023

Now we can draw the bars. Each with a logical colour value one more than the previous one (wrapping back to zero when the colour goes above 15).

   50 FOR U=1 TO W
   60 GCOL 0,U MOD 16
   70 X=U*1280/W  
   80 PLOT 85,X,0   
   90 PLOT 85,X,1023  
  100 NEXT U

Our program now looks like this:

   10 MODE 2
   20 W=64
   30 MOVE 0,0
   40 MOVE 0,1023
   50 FOR U=1 TO W
   60 GCOL 0,U MOD 16
   70 X=U*1280/W  
   80 PLOT 85,X,0   
   90 PLOT 85,X,1023  
  100 NEXT U

and produces this output:

Vertical bars with different colours

Setting the Palette

We can now set the palette to make half the logical colours be drawn with one colour and the other half with a different colour.

Logical Colour 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Physical Colour 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5
  110 FOR L=0 TO 15   
  120 IF L<8 P=2 ELSE P=5 
  130 VDU 19,L,P,0,0,0
  140 NEXT L

Vertical green and pink stripes

We can animate the stripes scrolling smoothly to the right by moving which logical colours are green / pink up one value.

Notice that we only need to change the palette for two logical colour values to do this.

Logical Colour 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Frame 0 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5
Frame 1 5 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5
Changed ^ ^

We will use F to store which frame we are on and use this to calculate which logical colour needs to change to green and which one needs to change to pink.

  150 F=0 
  160 *FX 19
  170 VDU 19,F MOD 16,2,0,0,0  
  180 VDU 19,(F+8) MOD 16,5,0,0,0  
  190 F=F+1
  200 GOTO 160

Green and pink stripes scrolling to the right

We actually don’t need the part of the program we made to setup the palette initially as, after 8 frames, every palette entry will have been written to by the animation. We can simplify things a little if we remove lines 110 to 140 that setup the palette initially.

Here is our full program if we remove those lines.

   10 MODE 2
   20 W=64
   30 MOVE 0,0
   40 MOVE 0,1023
   50 FOR U=1 TO W
   60 GCOL 0,U MOD 16
   70 X=U*1280/W  
   80 PLOT 85,X,0   
   90 PLOT 85,X,1023  
  100 NEXT U
  150 F=0 
  160 *FX 19
  170 VDU 19,F MOD 16,2,0,0,0  
  180 VDU 19,(F+8) MOD 16,5,0,0,0  
  190 F=F+1
  200 GOTO 160

Making a Grid

We have animated some stripes scrolling to the right. We can turn this into a grid if, instead of drawing single rectangles all the way up the screen, we split each vertical rectangle horizontally into several smaller rectangles.

For every horizontal row, we want to offset the colour we use by 8 so that it will eventually form a grid pattern.

We add a new loop to draw the rows of rectangles and keep track of Y0 and Y1 which are the vertical position of the top and bottom of the rectangle we are drawing.

   21 H=6
   22 Y1=0
   23 FOR V=1 TO H 
   24 Y0=Y1
   25 Y1=V*1024/H

We need to set the first two points for each row without drawing anything. We need to change our MOVE to use the Y co-ordinates we have calculated.

   30 MOVE 0,Y0
   40 MOVE 0,Y1

We also need to modify the colour we are using to offset by the row number times 8.

   60 GCOL 0,(U+V*8) MOD 16 

We need to change the PLOT co-ordinates to also use the new Y values.

   80 PLOT 85,X,Y0
   90 PLOT 85,X,Y1

and we need to end our new loop.

  120 NEXT V

This is the pattern the program has drawn without colour cycling.

Pattern for drawing animated grid

Our program now looks like this:

   10 MODE 2
   20 W=64
   21 H=6
   22 Y1=0
   23 FOR V=1 TO H 
   24 Y0=Y1
   25 Y1=V*1024/H
   30 MOVE 0,Y0
   40 MOVE 0,Y1
   50 FOR U=1 TO W
   60 GCOL 0,(U+V*8) MOD 16 
   70 X=U*1280/W  
   80 PLOT 85,X,Y0
   90 PLOT 85,X,Y1
  100 NEXT U
  120 NEXT V
  150 F=0 
  160 *FX 19
  170 VDU 19,F MOD 16,2,0,0,0  
  180 VDU 19,(F+8) MOD 16,5,0,0,0  
  190 F=F+1
  200 GOTO 160

And will produce this output:

Pink and green grid scrolling to the right

Squishing it Down

To run the program on @bbcmicrobot we need to reduce the size to fit in a tweet.

We can abbreviate the commands, remove whitespace, remove NEXT variables, use a comma for the nested NEXT statements, chain VDU commands together and use WORD parameters for the VDU commands.

1MO.2:W=64:H=6:Y1=0:F.V=1TOH:Y0=Y1:Y1=V*1024/H:MOV.0,Y0:MOV.0,Y1:F.U=1TOW:GC.0,(U+V*8)MOD16:X=U*1280/W:PL.85,X,Y0:PL.85,X,Y1:N.,:F=0
2*FX 19
3V.19,F MOD16,2;0;19,(F+8)MOD16,5;0;:F=F+1:G.3

We also need to tweak W and H to make sure the program will finish before the bot starts capturing video. I think I was one frame too late!

Similar Programs

I made a number of @bbcmicrobot programs that use a similar colour cycling grid scrolling effect.

Scrolling Plane Grid

This effect is similar to the program described above but a perspective projection is applied to make the grid appear like a flat plane in 3d.

Grid Tunnel

The grid does not have to be flat. Here we draw the same pattern but on the inside of a tunnel.

This program is complicated by trying to do the maths fast enough to complete the drawing before the bot starts recording the video.

To make things faster, some of the slow parts of the calculation that need to be evaluated several times are pre-computed. A table of SIN values is calculated and a table containing the radius to use for each depth is calculated and stored to memory using ! to write a 4 byte integer. When we are in the drawing loop, ! is used to read the values from this table.

This effect uses four different colours for the grid.

As this effect covers the whole screen, we can use all 16 colours for our animation. We simply split this into four sections, one for each colour.

Logical Colour 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Physical Colour 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6

As the colours are updated in a regular way we can write a loop to cycle the colours here.

7A=A+1:F.I=3TO6:V.19,(A+I*4)A.15,I,0;0;:N.:G.7

Expanded out, this would be:

7 A=A+1 : REM A is our Frame counter
8 FOR I=3 TO 6 : I is the Physical colour we will set
9 VDU 19,(A+I*4) AND 15,I,0,0,0
10 NEXT I
11 GOTO 7

AND 15 here replaces a MOD 16 but makes the program slightly smaller. We can only use AND in this way for positive numbers when the number we would MOD with is a power of two. In those cases we can and with one less than the value we would use for MOD.

e.g.

  • AND 1 === MOD 2
  • AND 3 === MOD 4
  • AND 7 === MOD 8
  • AND 15 === MOD 16
  • AND 31 === MOD 32

BBC Boing Ball

The rotation of the ball in this program is also using the grid scrolling effect. We will look at this program further in the next post.