Joystick

This file is part of ISTUG Public Domain Library 6. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Demo

This program is a joystick-controlled drawing tool that moves a cursor around the screen, leaving a trail of randomly colored characters. The cursor position is tracked with variables `A` (row, 0–21) and `B` (column, 0–31), and at each step the character is printed using a random INK color chosen via `INT(RND*7)`. Movement is handled by reading the joystick with the `STICK` function using port 1, checking standard directional values for up, down, left, and right, including diagonal combinations. Pressing the second joystick button randomizes the drawn character to a random printable symbol from CHR$ 91–143, allowing the user to vary the trail glyph.


Program Analysis

Program Structure

The program is a tight 10-line main loop. Lines 10–20 initialize the cursor position and the drawing character. Lines 30–80 form the core loop: print the current character at the current position, then test joystick directions and update row (A) and column (B) accordingly. Line 90 handles a button press to change the drawing character, and line 100 loops back to line 30 unconditionally.

  1. Line 10 — Initialize row A and column B to 0.
  2. Line 20 — Set the drawing character Z$ to the copyright/block symbol (char 127, the © escape resolving to the checkerboard graphic).
  3. Line 30 — Print Z$ at row A, column B with a random INK color 0–6.
  4. Line 40 — Ensure FLASH is off (defensive reset each loop iteration).
  5. Lines 50–80 — Four directional tests using STICK.
  6. Line 90 — If fire button 2 is pressed, randomize Z$.
  7. Line 100 — Return to line 30.

STICK Function Usage

Direction input is read using the STICK keyword (|), a TS2068 extension. The call |(1,2) reads joystick port 1 in digital mode, returning a bitmask. Standard directional values tested are:

ValueDirectionLines tested
1Up50
2Down70
4Left60
8Right80
5Up+Left diagonal50, 60
6Down+Left diagonal60, 70
9Up+Right diagonal50, 80
10Down+Right diagonal70, 80

Diagonals are handled by listing the combined bitmask value alongside the cardinal values in each directional line, so a diagonal press moves both the row and the column simultaneously across two separate IF tests.

Drawing Mechanics

The program works as a persistent drawing tool: because there is no screen clear, each printed character remains on screen as the cursor moves, building up a trail. The INK color for each character is randomized independently with INK INT(RND*7) directly inside the PRINT AT statement, producing a multicolored trail without any extra lines of code.

Boundary clamping is performed inline within each directional IF block. If a movement would take A below 0 or above 21, or B below 0 or above 31, the value is clamped and a GO TO 30 is issued immediately to skip the remaining direction tests and redraw at the clamped position.

Brush Character Selection

Line 90 reads |(2,2), the second joystick’s fire button. When pressed (value = 1), Z$ is set to CHR$(INT(RND*53)+91), yielding a random character in the range CHR$ 91–143. This range spans punctuation, uppercase letters, and the block graphic characters (128–143), giving the user a variety of brush shapes.

Notable Techniques and Anomalies

  • FLASH 0 on line 40 is reset every loop iteration, which is defensive but redundant since FLASH is not set anywhere else in the program.
  • The GO TO 30 within the boundary-clamping sub-expressions short-circuits the remaining direction checks. This is an efficient but slightly unconventional use of GO TO inside a compound IF chain.
  • Value 5 appears in both line 50 (up) and line 60 (left), which correctly represents the diagonal up-left bitmask being detected in both axes simultaneously.
  • The initial character Z$="\*" uses the zmakebas escape \* for the © character (char 127 in Spectrum character set), which renders as a checkerboard block graphic — a visually solid default brush.
  • No PAPER attribute is set, so the background color defaults to whatever was last used, which may cause minor color attribute bleed depending on screen state at startup.

Appears On

Run a lemonade stand, manage a radio factory through crises, catch drips as a plumber, or compose three-voice music note by note — ISTUG Library 6 balances business simulations and financial tools with arcade action and creative software.

Image Gallery

Source Code

   10 LET A=0: LET B=A
   20 LET Z$="\*"
   30 PRINT AT A,B; INK INT (RND*7);Z$
   40 FLASH 0
   50 IF |(1,2)=1 OR |(1,2)=5 OR |(1,2)=9 THEN LET A=A-1: IF A<0 THEN LET A=0: GO TO 30
   60 IF |(1,2)=4 OR |(1,2)=6 OR |(1,2)=5 THEN LET B=B-1: IF B<0 THEN LET B=0: GO TO 30
   70 IF |(1,2)=2 OR |(1,2)=10 OR |(1,2)=6 THEN LET A=A+1: IF A>21 THEN LET A=21: GO TO 30
   80 IF |(1,2)=8 OR |(1,2)=10 OR |(1,2)=9 THEN LET B=B+1: IF B>31 THEN LET B=31: GO TO 30
   90 IF |(2,2)=1 THEN LET Z$=CHR$ (INT (RND*53)+91)
  100 GO TO 30

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