Sprite Editor

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Graphics

This program implements a simple 8×8 grid editor where the user moves a cursor (“+”) around the grid and can mark or clear individual cells. The grid is stored as a two-dimensional string array A$(8,8), with each cell holding either “O” (empty) or an inverse space character (marked). Navigation uses keys 5/6/7/8 (up/down/left/right style), while “D” marks a cell, “E” erases it, “C” clears the entire grid, and “I” reinitialises the program. The editor uses single-character cell access via A$(row,col) and restores the previous cell’s display character before drawing the cursor at its new position, implementing a lightweight sprite-style cursor movement. A SAVE command at line 600 stores the program under a filename, though it is never reached by normal program flow.


Program Analysis

Program Structure

The program is organised into a main initialisation block, an input/display loop, and several subroutine-like sections reached by GOTO:

  1. Lines 1–2: Initialise cursor position variables X (row) and Y (column) to 1.
  2. Lines 10–100: Declare the 8×8 string array A$, fill every cell with "O", and print the grid.
  3. Lines 101–250: Main editor loop — display cursor, poll keyboard, dispatch commands, move cursor with wrapping.
  4. Lines 300–320: “Draw” handler — marks the current cell with an inverse space character.
  5. Lines 400–420: “Erase” handler — resets the current cell to "O".
  6. Lines 500–590: “Clear” handler — reinitialises the whole grid and redraws it.
  7. Lines 600–610: A SAVE and restart block that is unreachable from normal program flow.

Grid Representation

The grid is stored in DIM A$(8,8), a two-dimensional string array where each element is a single character. Cells hold either "O" for empty or an inverse-video space ("% " in the source) for marked. Individual cells are accessed with the two-index form A$(Z,M) and A$(X,Y), while entire rows are written using the single-index form A$(A) during initialisation, assigning the string "OOOOOOOO" to fill all eight columns at once.

Cursor Movement and Display

Before moving the cursor, the program saves the current position into Z and M (lines 145–146) and reads both the old cell content D$ and the new cell content C$ from A$ (lines 231–232). It then restores the vacated cell’s original character (line 240) and draws "+" or inverse "%+" at the new position depending on whether that cell is marked (lines 241–242). This ensures the cursor does not corrupt the underlying grid data.

Keyboard Polling Idiom

Lines 105–107 implement a busy-wait for a keypress using a short FOR loop (lines 105–106) followed by a check on INKEY$. The loop target at line 104 does not exist, so GOTO 104 falls through to line 105 — a well-known technique to re-enter a loop efficiently. The key is then read again into B$ at line 110 to capture the value for dispatch.

Wrapping Logic

Cursor wrapping at the grid boundaries is handled by a series of IF statements on lines 200–230. When X or Y reaches 0 it wraps to 8, and when it reaches 9 it wraps to 1, producing a toroidal grid where movement off any edge reappears on the opposite side.

Key Bindings

KeyAction
8Move cursor right (Y+1)
5Move cursor left (Y−1)
7Move cursor up (X−1)
6Move cursor down (X+1)
DMark (draw) current cell
EErase current cell
CClear entire grid
IReinitialise (restart program)

Bugs and Anomalies

  • Missing line 104: GOTO 104 at line 107 targets a non-existent line; execution resumes at line 105, which is the intended behaviour for re-entering the polling loop.
  • Double INKEY$ read: Lines 107 and 110 both call INKEY$. The first read at line 107 is used only to test for “no key pressed”; the actual key value is re-read at line 110. In theory a very brief keypress could be detected at line 107 but missed at line 110, though this is unlikely in practice.
  • Unreachable SAVE: Line 600 (SAVE "1008%8") is never reached during normal execution. It appears to be a developer utility for saving the program state.
  • Redundant status messages: Lines 20 and 510 print initialisation/clearing status text but lines 102 and 586 print "ED " in a fixed corner regardless of state, with no semantic distinction between editing modes.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 LET X=1
   2 LET Y=1
  10 DIM A$(8,8)
  20 PRINT AT 0,10;"INITIALIZING";AT 1,12;"       "
  30 FOR A=1 TO 8
  40 LET A$(A)="OOOOOOOO"
  50 NEXT A
  70 PRINT AT 0,0;
  80 FOR A=1 TO 8
  90 PRINT A$(A)
 100 NEXT A
 101 PRINT AT X-1,Y-1;"+"
 102 PRINT AT 0,19;"ED "
 105 FOR A=1 TO 4
 106 NEXT A
 107 IF INKEY$="" THEN GOTO 104
 110 LET B$=INKEY$
 120 IF B$="E" THEN GOTO 400
 125 IF B$="D" THEN GOTO 300
 130 IF B$="C" THEN GOTO 500
 140 IF B$="I" THEN GOTO 1
 145 LET Z=X
 146 LET M=Y
 160 IF B$="8" THEN LET Y=Y+1
 170 IF B$="5" THEN LET Y=Y-1
 180 IF B$="7" THEN LET X=X-1
 190 IF B$="6" THEN LET X=X+1
 200 IF X=0 THEN LET X=8
 210 IF X=9 THEN LET X=1
 220 IF Y=0 THEN LET Y=8
 230 IF Y=9 THEN LET Y=1
 231 LET D$=A$(Z,M)
 232 LET C$=A$(X,Y)
 240 PRINT AT Z-1,M-1;D$
 241 IF C$="% " THEN PRINT AT X-1,Y-1;"%+"
 242 IF C$="O" THEN PRINT AT X-1,Y-1;"+"
 250 GOTO 105
 300 LET A$(X,Y)="% "
 310 PRINT AT X-1,Y-1;"%+"
 320 GOTO 105
 400 LET A$(X,Y)="O"
 410 PRINT AT X-1,Y-1;"O"
 420 GOTO 105
 500 DIM A$(8,8)
 510 PRINT AT 0,10;"           ";AT 1,12;"CLEARING"
 520 FOR A=1 TO 8
 530 LET A$(A)="OOOOOOOO"
 540 NEXT A
 555 PRINT AT 0,0;
 560 FOR A=1 TO 8
 570 PRINT A$(A)
 580 NEXT A
 585 PRINT AT X-1,Y-1;"+"
 586 PRINT AT 1,17;"ED "
 590 GOTO 105
 600 SAVE "1008%8"
 610 GOTO 1

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

People

No people associated with this content.

Scroll to Top