Towering Inferno

Date: 1985
Type: Program
Platform(s): TS 2068
Tags: Game

Inferno is a falling-rescue arcade game in which the player maneuvers a boat along the bottom of the screen to catch people jumping from a burning building. The program uses User Defined Graphics (UDGs) loaded via POKEs to USR addresses, defining characters for the jumper, boat, and flame sprites stored as DATA bytes at line 870. The multi-story building backdrop is constructed entirely from block graphics characters stored in string variables and printed with precise AT coordinates across lines 890–1090. Fire spread is driven by a READ/DATA mechanism: after every ten jumps the fire advances one floor by reading pre-calculated screen coordinates from DATA lines 1110–1170, with each round using a progressively shorter data set controlled by variable z. Scoring uses odd-numbered random column values (lines 150–310) mapped to point values, with catches only scoring when the jumper lands in column d+1, the center of the three-character boat.


Program Analysis

Program Structure

The program is organized into clearly separated subroutines called from a linear main loop:

  1. Lines 10–30: Title, setup, and call to instructions subroutine (700)
  2. Lines 40–60: Initialize play area, call graphics loader (820) and building renderer (880)
  3. Lines 70–110: Set up HUD labels and initialize game variables
  4. Lines 120–500: Main game loop — outer loop r (rounds/fire levels), inner loop x (10 jumps per round), innermost loop b (falling object animation)
  5. Lines 510–590: Movement subroutines for right (520) and left (560)
  6. Lines 600–630: Fire spread subroutine, reads DATA coordinates
  7. Lines 640–690: End-of-game sequence with replay prompt
  8. Lines 700–810: Instructions display (two pages)
  9. Lines 820–870: UDG loader — POKEs 56 bytes into UDG memory
  10. Lines 880–1090: Building construction using block graphic strings
  11. Lines 1100–1170: DATA tables for fire spread coordinates

Sprite and Graphics Definitions

Three UDG characters are defined by the loader at line 840–860, which POKEs bytes starting at USR "\a" (UDG A). The 56 bytes of DATA at line 870 define seven 8-byte patterns. The characters used in gameplay are:

  • \a — the falling person sprite
  • \b\c\d — the three-character rescue boat (stored in a$)
  • \e — a window character used in the building backdrop
  • \f — a flame character, printed at the fire’s current position

The building backdrop (subroutine 880) uses two block-graphic strings: b$ (solid wall, 32 \:: blocks) and c$ (wall with windows, alternating \e\::), and a two-character segment d$. Slices of these strings are printed with AT coordinates to construct a detailed multi-story facade. String slicing syntax such as b$( TO PI) exploits the fact that INT(PI) = 3, a common Sinclair BASIC space-saving trick.

Main Game Loop and Falling Object Logic

The outer loop variable r counts rounds (1–7); each round fires 10 jumpers (inner loop x). For each jumper, a random odd column is chosen: c=2*INT(RND*15)+1 produces odd values from 1 to 29. A chain of IF statements (lines 160–310) maps each possible value of c to a point value t and an initial row b for the fall animation. Higher point values are assigned to columns near the edges and lower rows (harder catches), while central high-floor windows yield fewer points.

The fall itself is animated in the loop at line 320: FOR b=b TO 18. During each step the player may press “0” to move right (GO SUB 520) or “1” to move left (GO SUB 560). A catch is registered only when b=18 (ground level) and c=d+1 — the jumper’s column equals one ahead of the boat’s left edge, placing it at the center character of the three-character boat string.

Fire Spread Mechanism

After every 10 jumps, subroutine 600 reads z pairs of coordinates from the DATA statements and prints a flame character (\f) with PAPER 2 at each position. The variable z is set by a chain of IF statements (lines 420–480) to decrease with each round:

Round (r)Pairs read (z)DATA line
1241110
2151120
3111130
4131140
571150
641160
731170

The READ pointer advances continuously across all DATA lines, so each round consumes a fresh set of coordinates representing the fire creeping upward through the building floors.

Key BASIC Idioms and Techniques

  • PAUSE NOT PI: NOT PI evaluates to 0, so PAUSE 0 waits indefinitely for a keypress. Used at lines 660, 810.
  • PI as integer 3: AT PI,2 uses PI≈3.14159, which BASIC truncates to row 3. Also used in string slices like b$( TO PI) to extract the first 3 characters.
  • Variable name reuse: The loop variable b is overwritten at line 320 (FOR b=b TO 18) after being set by the IF chain. The loop variable x is similarly reused as a loop counter in the end-of-game fanfare at line 640.
  • Erasing sprites: Both the boat and falling figure are erased by printing spaces or the block-graphic background character (\:: at line 390, spaces at lines 530 and 570) before redrawing at the new position.
  • DATA anomaly — literal l: Line 870 contains l tokens interspersed in the DATA list (e.g., DATA 60,189,...,l,36,66,56,l,...). These appear to be the numeric variable l, which is never assigned a value and would default to 0. This is likely the intended zero-byte padding for UDG rows that should be blank, using a short variable name as a space-saving substitute for the literal 0.

End-of-Game Sequence

After all 7 rounds, line 640 flashes the final score with FLASH 1 and plays a brief ascending fanfare using nested loops. Line 650 prompts for replay; PAUSE NOT PI at line 660 halts until a key is held, then line 670 reads it with INKEY$. Pressing “Y” or “y” restarts from line 30 via RUN 30, which resets all variables and re-enters the instruction sequence.

Bugs and Anomalies

  • Line 380 prints a flame at row 20 when a jumper is missed (reaches row 18 without being caught), but immediately erases it. The row 20 print position is off-screen relative to the building and may overlap the boat area — likely a visual “splash” effect that is intentionally brief.
  • The movement subroutines at 520 and 560 print four and five spaces respectively to erase the boat, but the boat sprite a$ is only three characters wide. This leaves one or two extra spaces, which may erase adjacent building detail at the edges of the play field.
  • The replay path RUN 30 skips re-loading UDGs (subroutine 820 is called at line 60 via 50), but since RUN does not clear POKE’d memory, the UDGs remain intact and gameplay is unaffected.

Content

Appears On

Library tape of the Indiana Sinclair Timex User’s Group.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 REM INFERNO
   20 PAPER 6: BORDER 6: INK 0
   30 GO SUB 700
   40 PAPER 5: CLS 
   50 GO SUB 820
   60 GO SUB 880
   70 INK 0: PRINT AT 1,23;"SAVES ";AT 1,1;"POINTS"
   80 LET A$="\b\c\d"
   90 LET p=0: LET s=p: LET d=14
  100 PRINT PAPER 2; INK 0;AT 16,14;"\f"
  110 PRINT AT 19,d; PAPER 0; INK 7;a$
  120 FOR r=1 TO 7
  130 FOR x=1 TO 10
  140 PAUSE 25
  150 LET c=2*INT (RND*15)+1
  160 IF c=1 THEN LET b=4: LET t=50
  170 IF c=3 THEN LET b=13: LET t=150
  180 IF c=5 THEN LET b=9: LET t=75
  190 IF c=7 THEN LET b=6: LET t=50
  200 IF c=9 THEN LET b=10: LET t=50
  210 IF c=11 THEN LET b=3: LET t=25
  220 IF c=13 THEN LET b=9: LET t=25
  230 IF c=15 THEN LET b=8: LET t=25
  240 IF c=17 THEN LET b=5: LET t=25
  250 IF c=19 THEN LET b=7: LET t=25
  260 IF c=21 THEN LET b=4: LET t=25
  270 IF c=23 THEN LET b=11: LET t=50
  280 IF c=25 THEN LET b=5: LET t=25
  290 IF c=27 THEN LET b=9: LET t=75
  300 IF c=29 THEN LET b=13: LET t=150
  310 IF c=31 THEN LET b=8: LET t=100
  320 FOR b=b TO 18
  330 IF b=18 AND c=d+1 THEN LET s=s+1: PRINT PAPER 6; INK 0;AT 1,29;s: LET p=p+t: PRINT PAPER 6; INK 0;AT 1,8;p: BEEP .1,30
  340 PAPER 0: INK 7: PRINT AT b,c;"\a"
  350 IF INKEY$="0" AND d<29 THEN GO SUB 520
  360 BEEP .02,b
  370 IF INKEY$="1" AND d>0 THEN GO SUB 560
  380 IF b=18 AND c<>d+1 THEN PRINT INK 7; PAPER 1;AT 20,c;"\f": BEEP .1,-15: PRINT AT 20,c; PAPER 1; INK 7;" "
  390 INK 0: PRINT AT b,c;"\::"
  400 NEXT b
  410 NEXT x
  420 IF r=1 THEN LET z=24
  430 IF r=2 THEN LET z=15
  440 IF r=3 THEN LET z=11
  450 IF r=4 THEN LET z=13
  460 IF r=5 THEN LET z=7
  470 IF r=6 THEN LET z=4
  480 IF r=7 THEN LET z=3
  490 GO SUB 600
  500 NEXT r
  510 GO TO 640
  520 REM **MOVE RIGHT**
  530 PRINT PAPER 0;AT 19,d;"    "
  540 LET d=d+1
  550 PAPER 0: INK 7: PRINT AT 19,d;a$: RETURN 
  560 REM **MOVE LEFT**
  570 PRINT PAPER 0;AT 19,d;"     "
  580 LET d=d-1
  590 PAPER 0: INK 7: PRINT AT 19,d;a$: RETURN 
  600 REM **FIRE**
  610 FOR w=1 TO z
  620 READ x,y
  630 PRINT PAPER 2; INK 0;AT x,y;"\f": NEXT w: RETURN 
  640 PRINT INK 0; PAPER 6; FLASH 1;AT 1,8;p: FOR r=1 TO 10: LET t=8: FOR n=1 TO 5: BEEP .05,t: LET t=t+1: NEXT n: NEXT r: BEEP 2,-12
  650 PRINT INK 7; PAPER 1;AT 20,1;"**FINISH** Another go? (Y OR N)"
  660 PAUSE NOT PI
  670 LET x$=INKEY$
  680 IF x$="y" OR x$="Y" THEN PAPER 6: CLS : RUN 30
  690 CLS : PRINT AT 10,5; PAPER 6; INK 1;"THANK YOU FOR PLAYING": STOP 
  700 REM INSTRUCTIONS
  710 CLS : PAPER 6: INK 2: PRINT AT 5,8;"TOWERING INFERNO"
  720 INK 0: PRINT AT 7,10; "DAVID PEAT"
  730 PRINT AT 10,2;"Fire rages through a block of   flats,try to catch the people   as they jump. Move the rescue   boat to the right with key 0,   and left with key 1"
  740 PRINT #0;"    Press any key to continue"
  750 GO SUB 810
  760 PAPER 6: INK 0: PRINT AT PI,2;"The fire rises through the      building one level for every    10 jumps until the game ends    when the fire reaches the top        Points are awarded for     the difficulty of the catch.    25 Points for high and centr-   al windows, 50 Points for       left or right of center,and     75,100,150 for low and edge     windows"  
  770 PRINT #0;"    Press any key to continue"
  780 GO SUB 810
  790 PRINT AT PI,2;"The falls are from random        positions making it a gamble    to try to catch only those      falling from edge windows.      A catch must be in the middle   of the boat." 
  800 PRINT #0;"    PRESS ANY KEY TO START"
  810 PAUSE NOT PI: CLS : RETURN 
  820 REM Graphics
  840 FOR n=0 TO 55
  850 READ l: POKE USR "\a"+n,l
  860 NEXT n: RETURN 
  870 DATA 60,189,153,126,24,l,36,66,56,l,17,58,188,251,l,63,0,l,l,l,l,l,255,l,0,l,l,l,1,195,254,252,255,l,195,l,l,l,l,255,34,149,66,36,129,90,36,24,0,l,60,l,l,l,l,0
  880 REM Building
  890 LET b$="\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  900 LET c$="\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::\e\::"
  910 LET d$="\e\e"
  920 PRINT PAPER 5; INK 1;AT 20,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  930 PRINT PAPER 5; INK 1;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  940 PAPER 5: INK 0
  950 PRINT AT 19,0;b$;AT 18,0;b$
  960 PRINT AT 17,0;b$;AT 16,0;c$
  970 PRINT AT 15,0;b$;AT 14,0;c$
  980 PRINT AT 13,0;b$( TO PI);AT 13,PI;c$( TO 2);AT 13,5;b$( TO 24);AT 13,29;c$( TO 2);AT 13,31;b$(1)
  990 PRINT AT 12,0;c$( TO 2);AT 12,4;c$(5 TO 22);AT 12,23;c$(2 TO 7);AT 12,31;b$(1)
 1000 PRINT AT 11,0;b$( TO 2);AT 11,4;b$( TO 18);AT 11,23;c$( TO 2);AT 11,25;b$( TO 4);AT 11,31;b$(1)
 1010 PRINT AT 10,0;c$( TO 2);AT 10,4;c$( TO 18);AT 10,24;c$( TO 5);AT 10,31;b$(1)
 1020 PRINT AT 9,0;b$( TO 2);AT 9,4;c$(2 TO 4);AT 9,7;b$( TO 2);AT 9,10;b$( TO 2);AT 9,12;c$(2 TO 4);AT 9,15;b$( TO 7);AT 9,24;b$( TO PI);AT 9,27;c$( TO 2);AT 9,31;b$(1)
 1030 PRINT AT 8,0;c$( TO 2);AT 8,7;c$(2 TO PI);AT 8,10;c$( TO PI);AT 8,15;d$;AT 8,17;c$(2 TO 6);AT 8,24;c$( TO 2);AT 8,31;d$(1)
 1040 PRINT AT 7,0;b$( TO 2);AT 7,7;b$( TO 2);AT 7,10;b$( TO PI);AT 7,17;b$( TO 2);AT 7,19;c$( TO 2);AT 7,21;b$(1);AT 7,24;b$( TO 2);
 1050 PRINT AT 6,0;c$( TO 2);AT 6,7;d$;AT 6,10;c$( TO PI);AT 6,17;c$(2 TO PI);AT 6,20;c$( TO 2);AT 6,24;c$( TO 2);
 1060 PRINT AT 5,0;b$( TO 2);AT 5,10;b$( TO PI);AT 5,17;c$( TO 2);AT 5,20;b$( TO 2);AT 5,24;c$(2 TO PI);
 1070 PRINT AT 4,1;d$(1);AT 4,10;c$( TO PI);AT 4,20;d$
 1080 PRINT AT 3,10;c$(2 TO 4)
 1090 RETURN 
 1100 REM ** DATA for Fire**
 1110 DATA 16,0,16,2,14,2,16,4,16,6,14,6,16,8,16,10,14,10,16,12,16,14,14,14,16,16,16,18,14,18,16,20,16,22,14,22,16,24,16,26,14,26,16,28,16,30,14,30
 1120 DATA 14,0,14,4,12,4,14,8,12,8,14,12,12,12,14,16,12,16,14,20,12,20,14,24,12,24,14,28,12,28
 1130 DATA 12,0,12,6,10,6,12,10,10,10,12,14,10,14,12,18,10,18,12,26,10,26
 1140 DATA 10,0,10,4,10,8,8,8,10,12,8,12,10,16,8,16,10,20,8,20,10,24,8,24,10,28
 1150 DATA 8,0,6,8,8,10,6,12,8,18,6,20,8,31
 1160 DATA 6,0,6,10,6,18,6,24
 1170 DATA 4,10,4,12,4,20
 1180 SAVE "INFERNO" LINE 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