--- title: "Firepower" id: 71309 type: "computer_media" slug: "firepower" url: "http://localhost/computer_media/firepower/" markdown_url: "http://localhost/computer_media/firepower.md" published_at: "2026-09-02T07:06:04+00:00" modified_at: "2026-09-02T07:06:05+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/firepower.png" excerpt: "Pilot a crosshair around a starfield to intercept falling UDG bombs before the 60-second timer expires — scoring depends on how precisely you aim." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Firepower%20(198x)(-)(TS2068)(US)(Program).zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/firepower.png" media_type_tags: "Arcade" --- # Firepower Firepower is a single-screen shooting gallery game in which the player maneuvers a gun sight around the screen to intercept falling enemy sprites. The player’s turret graphic is built from a 65-character DIM array using CHR$ codes for vertical bars, dashes, and a plus sign to form a crosshair shape. A User Defined Graphic (UDG) is loaded via a DATA statement and POKE loop into the UDG area (USR CHR$ 144) to display the falling target — an oval or bomb shape defined by the byte pattern 0,60,126,126,126,126,60,0. Timing is handled by reading the system frames counter at addresses 23672–23673, converting ticks to seconds by dividing by 60, giving a 60-second countdown. Scoring awards 2 points for a direct hit (same screen position) and 1 point for a near-miss (adjacent cell), detected by comparing linearized screen coordinates. *** ### Program Structure The program is organized into distinct phases: 1. **Initialization (lines 2–15):** UDG data is POKEd, the crosshair string array is constructed, and the screen is set up. 2. **Star field generation (line 20):** 50 asterisks are placed at random positions. 3. **Game variable reset (lines 25–45):** Score, player position, frame counter, and bomb state are initialized. 4. **Main game loop (lines 100–240):** Timer update, score display, bomb movement, player movement, collision detection, and redraw all occur here. 5. **End screen (lines 1000–1010):** Game over message with restart prompt. 6. **Data (line 1020):** Eight bytes defining the UDG sprite. ### UDG Sprite Line 5 loads 8 bytes from the `DATA` statement at line 1020 into the UDG slot at `USR CHR$ 144`, defining a symmetrical oval/bomb shape: `0,60,126,126,126,126,60,0`. This is displayed via `CHR$ 144` throughout the game. The loop iterates from `USR CHR$ 144` to `USR CHR$ 144+7`, covering all 8 pixel rows of the character. ### Crosshair Construction The player’s gun sight is stored in a 65-character string array `a$`. Rather than printing individual characters, the array is populated sparsely: position 1 gets `CHR$ 73` (pipe/vertical bar), position 32 gets `CHR$ 45` (dash), position 33 gets `CHR$ 43` (plus), position 34 gets `CHR$ 45` (dash), and position 65 gets `CHR$ 73`. The remaining characters default to spaces, giving a two-row crosshair occupying a 32-wide by 2-row region when printed with `AT x,y`. ### Timing Mechanism The system’s frame counter is stored across two bytes at addresses 23672 and 23673. Line 100 reads these with `PEEK 23673*256 + PEEK 23672` and divides by 60 to convert frames to seconds, storing the result in `t1`. Line 105 detects when `t` changes to produce a tick beep and update the displayed time. The POKE statements at line 35 reset this counter to zero at the start of each game. ### Bomb Movement Logic A single bomb is tracked by position variables `a` (row) and `b` (column), with a horizontal drift value `d` set to −1, 0, or 1 randomly. Line 120 spawns a new bomb when `b=0` (inactive); line 125 erases the old position (via OVER 1 XOR mode) and advances the bomb down and sideways; line 130 deactivates the bomb if it reaches row 21 or the screen edges. The character code `\{16}\{0}` in the conditional at line 120 is an INK 0 color control embedded in the condition check — effectively printing an invisible character or acting as a flag to test `b`. ### Collision Detection Collision uses linearized screen coordinates. Line 205 computes `p = (x+1)*22 + y` for the player and `p1 = a*22 + b` for the bomb. A direct hit (`p = p1`) awards 2 points and triggers a long beep. Line 215 checks for a near-miss by testing `ABS(p-p1) = 1` (same row, adjacent column) or `ABS(p-p1) = 22` (adjacent row), awarding 1 point. This uses a column-width of 22 rather than 32 in the linearization, which is a minor inaccuracy but produces a workable approximation. ### Player Movement Lines 220–225 read `INKEY$` for keys 5/6/7/8 and compute new coordinates `x1` and `y1` using Boolean arithmetic — adding or subtracting 1 based on the result of logical comparisons. Boundary checks (`x<19`, `x>0`, `y<30`, `y>1`) are embedded in the same expressions. Line 230 erases the crosshair at the old position (OVER 1 mode), then lines 235–240 update the position and loop. ### Display Technique `OVER 1` is set globally at line 15 and used throughout the main loop. This XOR drawing mode means printing a character twice restores the background, enabling flicker-free movement of both the bomb and the player crosshair without explicitly clearing them. The star field placed at line 20 persists beneath the sprites because OVER 1 toggles pixels rather than overwriting them. ### Notable Anomalies - The linearization factor of 22 (instead of 32) at line 205 means near-miss detection is slightly off for columns beyond 22, but the hit detection at exact equality is unaffected. - Line 205 redraws the UDG at the bomb position after a direct hit (`PRINT AT a,b; CHR$ 144`), which in OVER 1 mode XORs it again — this may visually leave a ghost, though the bomb variable `b` is immediately zeroed. - The crosshair occupies two rows (65 characters = 2×32 + 1), but only specific positions are non-space, so the printed region looks like a sparse two-row symbol rather than a solid block. ## Source Code ``` 2 REM "firepower" 5 FOR j= USR CHR$ 144 TO USR CHR$ 144+7:READ a:POKE j,a:NEXT j 10 DIM a$(65):LET a$(1)= CHR$ 73:LET a$(32)= CHR$ 45:LET a$(34)= CHR$ 45:LET a$(65)= CHR$ 73 12 LET a$(33)= CHR$ 43 15 BORDER 5:PAPER 5:INK 0:OVER 1:CLS 20 FOR j=1 TO 50:PRINT AT INT (RND*22), INT (RND*32);"*":NEXT j 25 LET s=0 30 LET x=11:LET y=15 35 POKE 23673,0:POKE 23672,0 40 LET t=0 45 LET b=0 100 LET t1= INT ((PEEK 23673*256+ PEEK 23672)/60) 105 IF t <>t1 THEN BEEP .01,t:LET t=t1 110 PRINT AT 0,0; OVER 0;"SCORE ";s,"TIME ";t 115 IF t >=60 THEN GO TO 1000 120 IF \{16}\{0} NOT b THEN LET b= INT (RND*31)+1:LET a=1:LET d= INT (RND*3)-1:GO TO 130 125 PRINT AT a,b; CHR$ 144:LET a=a+1:LET b=b+d 130 IF a=21 OR b=0 OR b=32 THEN LET b=0:GO TO 200 135 PRINT AT a,b; INK 6; CHR$ 144 200 PRINT AT x,y; INK 8;a$ 205 LET p=(x+1)*22+y:LET p1=a*22+b:IF p=p1 THEN BEEP 1,50:LET s=s+2:PRINT AT a,b; CHR$ 144:LET b=0:GO TO 220 210 IF INKEY$ <>"0" THEN GO TO 220 215 IF ABS (p-p1)=1 OR ABS (p-p1)=22 THEN BEEP .5,50:LET s=s+1 220 LET x1=x+(INKEY$="6" AND x<19)-(INKEY$="7" AND x>0) 225 LET y1=y+(INKEY$="8" AND y<30)-(INKEY$="5" AND y>1) 230 PRINT AT x,y; INK 8;a$ 235 LET x=x1:LET y=y1 240 GO TO 100 1000 PRINT OVER 0; FLASH 1; PAPER 2; INK 7; AT 10,12;"GAME OVER"; FLASH 0; AT 21,5;"PRESS""R"" TO PLAY AGAIN" 1005 IF INKEY$="r" OR INKEY$="R" THEN RUN 1010 GO TO 1005 1020 DATA 0,60,126,126,126,126,60,0 ```