FILL

This file is part of and CATS Library Tape 6. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Demo, Graphics

This program implements a pixel-level flood-fill routine for the 256×176 pixel graphics area. A crosshair pointer is moved around the screen using the 5–8 cursor keys, and pressing F triggers a subroutine that fills the enclosed area containing the pointer’s location. The fill algorithm works by first walking outward along a vertical column to find the top and bottom boundary pixels, then scanning horizontally row by row to paint unset pixels, and separately handling four corner regions (top-right, top-left, bottom-right, bottom-left) that extend beyond the central column. Line 1010 pre-loads subroutine entry points into variables so that GO TO statements can target symbolic labels rather than hard-coded line numbers. A sample pattern is drawn using PLOT and DRAW with arc segments (lines 120–140) to create a web of intersecting curved lines that define closed regions suitable for filling.


Program Analysis

Program Structure

The program is divided into four logical sections:

  1. Lines 10–80: Introduction screen — displays instructions and waits for a keypress.
  2. Lines 100–140: Sample pattern generator — draws a series of intersecting arcs using PLOT/DRAW to create closed regions to fill.
  3. Lines 500–630: Pointer movement and selection loop — moves a pixel cursor and waits for the F key to trigger the fill.
  4. Lines 1000–1510: The fill subroutine itself, entered via GO SUB fill.

Pattern Generation

Lines 120–140 loop p from 0 to 255 in steps of 51, using DRAW with a third argument (the arc angle in radians) to produce curved lines. Each iteration plots two arcs from the same starting pixel, creating a symmetrical web of intersecting curves that enclose distinct regions suitable for flood-filling. Six iterations produce a visually rich pattern without any bitmap data.

Pointer Movement Loop

The pointer is represented by a single pixel toggled with PLOT OVER 1 — XOR-plotting — so the pixel can be shown and hidden without corrupting underlying graphics. Variables x and y track the pointer coordinates. Lines 570–600 use a compact Sinclair BASIC idiom where boolean expressions (INKEY$="8" etc.) evaluate to 1 or 0, allowing a single arithmetic expression to handle four-directional movement. Boundary wrapping at lines 580 and 600 uses the same trick to keep coordinates in range. Line 550 polls INKEY$ in a tight loop and line 560 erases the old pixel before movement — a standard PAUSE 0 / INKEY$ idiom adapted without PAUSE 0, instead looping on empty INKEY$.

Symbolic Line-Number Variables

Line 1010 pre-assigns a large set of variables whose names match subroutine labels (e.g., fillright, toppoint, loopbotleft) to the actual line numbers of corresponding REM statements. Line 1020 assigns select, fill, move, and wait near the top of the program (line 20). This allows GO TO toppoint, GO TO fillright, etc., to be written symbolically. The approach is a well-known memory and maintainability technique in Sinclair BASIC: VAL is not needed here because the variable itself holds the numeric line number directly.

Fill Algorithm

The fill subroutine uses a custom scanline-style approach rather than a recursive flood fill. It operates in several stages:

  • Vertical scan (lines 1030–1060): Starting from the pointer’s Y coordinate, a walks upward and b walks downward using POINT to find the top and bottom boundary pixels of the enclosed area along column x.
  • Corner extent detection (lines 1070–1140): Four variables (cmax, cmin, dmax, dmin) are walked outward from x to find how far the enclosed region extends horizontally at the top and bottom edges.
  • Main horizontal fill (lines 1160–1230): For each row between b+2 and a-2, xmax and xmin walk right and left from x, plotting unset pixels until a boundary is hit.
  • Corner fills (lines 1250–1510): Four separate loops handle the top-right, top-left, bottom-right, and bottom-left corner regions, each walking vertically outward from the boundary row.

Notable Techniques

  • PLOT OVER 1 is used for the cursor pixel so it can be toggled without corrupting the underlying pattern.
  • All inner loops use GO TO with symbolic variables rather than FOR/NEXT, which is faster for tight pixel-scanning loops in Sinclair BASIC.
  • The POINT function is used extensively as a boundary detector — the fill stops when it encounters a set pixel, making the algorithm implicitly shape-agnostic.
  • Early exit conditions (e.g., IF cmax=x+1 THEN GO TO filltopleft at line 1250) skip corner-fill phases when no corner extent exists, avoiding unnecessary work.

Bugs and Anomalies

  • Lines 570–600 read INKEY$ multiple times in sequence. Because each read samples the keyboard independently, rapidly pressed or released keys may cause only some of the four direction checks to fire correctly in a single pass, though in practice this is rarely noticeable.
  • The fill algorithm assumes the pointer is placed strictly inside a closed boundary. If the pointer is on or near a boundary pixel, or if the shape is not truly closed, the boundary-walking loops have no guard against running off-screen, which could cause erratic behavior or an infinite loop.
  • Line 1220 has a comment “fill toleft” (missing space), a minor typographical error in the source.
  • The variable name filleft at line 1010 appears to be a typo for fillleft (or fillleft), though it is consistent with its usage at line 1220 (GO TO filleft), so no actual bug results.

Variable Summary

VariableRole
fill, wait, move, selectLine-number aliases for major GO TO targets
x, yCurrent pointer pixel coordinates
a, bTop and bottom boundary Y coordinates on column x
cmax, cminRightmost/leftmost X extent at top boundary
dmax, dminRightmost/leftmost X extent at bottom boundary
xmax, xminHorizontal fill extents for main body scanlines
ymax, yminVertical fill extents for corner region scanlines
nLoop counter for row/column iteration
pPattern generation loop counter

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

FILL

Source Code

   10 REM P51 FILL
   20 LET fill=1000: LET wait=540: LET move=520: LET select=500
   29 REM 
   30 REM set up PRINT ser display
   31 REM 
   40 BORDER 1: PAPER 7: INK 9: BRIGHT 1: CLS 
   50 PRINT PAPER 1;AT 1,14;"Fill"
   60 PRINT "This program lets you select    any enclosed area in a pattern  and fill it in.  Select the     area by moving a pixel pointer  which starts in the bottom left hand corner of the screen.  Movethe pointer using the arrow keys(5 TO 8).  When the pointer is  in the middle of the selected   area press key F to fill. After the fill is complete the point- er returns to its original      position."
   70 PRINT FLASH 1;AT 19,3;"Press any key to continue"
   80 PAUSE 0
   89 REM 
   90 REM sample program 100-490
   91 REM 
  100 REM pattern program
  101 REM 
  110 BORDER 2: PAPER 1: INK 6: BRIGHT 1: CLS 
  120 FOR p=0 TO 255 STEP 51
  130 PLOT p,0: DRAW 255-2*p,175,1: DRAW 2*p-255,-175,1
  140 NEXT p
  499 REM 
  500 REM select area
  501 REM 
  510 LET x=0: LET y=0
  520 REM move
  530 PLOT OVER 1,x,y
  540 REM wait
  550 IF INKEY$="" THEN GO TO wait: REM no space between inverted commas
  560 PLOT OVER 1;x,y
  570 LET x=x+(INKEY$="8")-(INKEY$="5")
  580 LET x=x-(x>255)+(x<0)
  590 LET y=y+(INKEY$="7")-(INKEY$="6")
  600 LET y=y-(y>175)+(y<0)
  610 IF INKEY$<>"f" AND INKEY$<>"F" THEN GO TO move
  620 GO SUB fill
  630 GO TO select
  900 REM subroutines
 1000 REM fill - fills enclosed space
 1010 LET loopbotleft=1490: LET fillbotleft=1450: LET loopbotright=1420: LET fillbotright=1380: LET looptopleft=1350: LET filltopleft=1310: LET looptopright=1280: LET filleft=1200: LET fillright=1180: LET bottomleft=1130: LET bottomright=1110: LET topleft=1090: LET topright=1070: LET bottompoint=1050: LET toppoint=1030
 1020 LET a=y: LET b=y: LET cmax=x+1: LET cmin=x-1: LET dmax=x+1: LET dmin=x-1
 1030 REM toppoint
 1040 IF POINT (x,a)=0 THEN LET a=a+1: GO TO toppoint: REM find pixel (x,a)
 1050 REM bottompoint
 1060 IF POINT (x,b)=0 THEN LET b=b-1: GO TO bottompoint: REM find pixel (x,b)
 1070 REM topright
 1080 IF POINT (cmax,a-1)=0 THEN LET cmax=cmax+1: GO TO topright: REM test if area exists above and to right of pixel (x,a) and, if so find cmax
 1090 REM topleft
 1100 IF POINT (cmin,a-1)=0 THEN LET cmin=cmin-1: GO TO topleft: REM test if area exists above and to left of pixel (x,a) and, if so find cmax
 1110 REM bottomright
 1120 IF POINT (dmax,b+1)=0 THEN LET dmax=dmax+1: GO TO bottomright: REM test if area exists below and to right of pixel (x,b) and, if so find dmax
 1130 REM bottomleft
 1140 IF POINT (dmin,b+1)=0 THEN LET dmin=dmin-1: GO TO bottomleft: REM test if area exists below and to left of pixel (x,b) and, if so find dmin
 1150 REM The important point coordinates have now been found. Now fill the area.
 1160 FOR n=b+2 TO a-2
 1170 LET xmax=x: LET xmin=x-1
 1180 REM fillright
 1190 IF POINT (xmax,n)=0 THEN PLOT xmax,n: LET xmax=xmax+1: GO TO fillright: REM fill to right of line between pixels(x,b) and (x,a)
 1200 REM filleft
 1220 IF POINT (xmin,n)=0 THEN PLOT xmin,n: LET xmin=xmin-1: GO TO filleft: REM fill toleft of line between pixels (x,b) and (x,a)
 1230 NEXT n
 1240 REM fill the top and bottom areas
 1250 IF cmax=x+1 THEN GO TO filltopleft
 1260 FOR n=x-1 TO cmax-1
 1270 LET ymax=a-1
 1280 REM looptopright
 1290 IF POINT (n,ymax)=0 THEN PLOT n,ymax: LET ymax=ymax+1: GO TO looptopright: REM fill top right hand space
 1300 NEXT n
 1310 REM filltopleft
 1320 IF cmin=x-1 THEN GO TO fillbotright
 1330 FOR n=x+1 TO cmin+1 STEP -1
 1340 LET ymax=a-1
 1350 REM looptopleft
 1360 IF POINT (n,ymax)=0 THEN PLOT n,ymax: LET ymax=ymax+1: GO TO looptopleft: REM fill top lefthand space
 1370 NEXT n
 1380 REM fillbotright
 1390 IF dmax=x+1 THEN GO TO fillbotleft
 1400 FOR n=x-1 TO dmax-1
 1410 LET ymin=b+1
 1420 REM loopbotright
 1430 IF POINT (n,ymin)=0 THEN PLOT n,ymin: LET ymin=ymin-1: GO TO loopbotright: REM fill bottom right hand space
 1440 NEXT n
 1450 REM fillbotleft
 1460 IF dmin=x-1 THEN RETURN 
 1470 FOR n=x+1 TO dmin+1 STEP -1
 1480 LET ymin=b+1
 1490 REM loopbotleft
 1500 IF POINT (n,ymin)=0 THEN PLOT n,ymin: LET ymin=ymin-1: GO TO loopbotleft: REM fillbottom left hand space
 1510 NEXT n: RETURN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top