A bar for the drift, and a lighter touch sideways

A moon has no air, so a sideways drift never stops by itself and stopping
one means cancelling the velocity EXACTLY. That is not hard to do; it is
hard to do blind, which is what it was - a number nothing on the screen
said anything about.

So sprite one is a bar whose width is the drift. It runs right from the
middle of the screen for a rightward one and left for a leftward one, so
which way is as plain as how fast, and stopped is the one state with
nothing drawn at all. The whole of it is a target width written once a
frame; the device stretches one tile into it and the program draws
nothing.

Sideways thrust is one a tick rather than two. At two, the smallest
correction available was twice the size it needed to be and overshooting
was the normal outcome.

WHICH ZERO MEANS NOTHING TURNED OUT TO MATTER. A target width of nought is
the NATURAL width, not an empty sprite - so a bar with no drift in it came
out eight pixels wide, sitting at the middle of the screen, saying
"stopped" in the same shape it says "drifting slightly". What draws
nothing is a SIZE of nought, which is the other zero in the other byte.
Both meanings are deliberate and documented and it still caught me out
inside a week of writing them down.

The check for it earned its place by failing on that before it was found,
which is the best evidence a check can offer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-02 22:14:36 -04:00
co-authored by Claude Opus 5
parent b1dde7908c
commit db0c26e13f
13 changed files with 197 additions and 13 deletions
+149 -2
View File
@@ -78,6 +78,7 @@ everyFrame:
CALL move
CALL follow
CALL showLander
CALL showDrift
SETD.0 Flying
LDA.0
BNA everyFrame
@@ -529,6 +530,137 @@ showLander:
OUTA 0xE9
RET
; ---- How fast sideways, as a bar ----
;
; A moon has no air, so a drift never stops by itself and stopping one means cancelling the
; velocity EXACTLY. That is not hard to do; it is hard to do BLIND, which is what it was - a
; number nothing on the screen said anything about.
;
; So sprite one is a bar whose width is the drift and which disappears at nought. It grows
; right from the middle of the screen for a rightward drift and left for a leftward one, so
; which way is as plain as how fast, and "stopped" is the one state with nothing drawn.
;
; The whole of it is the sprite's target width, which the device stretches one tile into. The
; program does no drawing at all: it works out one number a frame and writes it.
showDrift:
; The magnitude, and which way. A two's complement pair is inverted and stepped, and the
; step's carry is what runs into the high half.
SETD.0 SpeedAcross
LDA.0
SETD.1 DriftLow
STA.1
INCD.0
LDA.0
SETD.1 DriftHigh
STA.1
INIB 0x80
AND
SETD.1 DriftLeftward
STQ.1 ; The top bit of the high half, which is the sign.
BRQ driftSized
SETD.0 DriftLow
LDA.0
NOTA
MVQA
INCA
STA.0
SETD.0 DriftHigh
LDA.0
NOTA
MVQA
RSTB
ADD ; Plus the carry the step above left, which is the other half.
STQ.0
driftSized:
; ---- Clamped, because a bar wider than the screen says nothing a full one does not ----
;
; And because a target width is sixteen bits: an unclamped one would be asking the device to
; draw a bar sixty thousand pixels wide, which it clips, but only after being asked.
SETD.0 DriftHigh
LDA.0
BNA driftWide ; Anything in the high half is already past the limit.
SETD.0 DriftLow
LDA.0
INIB 0d120
CCF
SUB
BRC driftReady ; Borrowed, so it is under the limit and stands.
driftWide:
INIA 0d120
SETD.0 DriftLow
STA.0
driftReady:
; ---- Two zeros, meaning two different things ----
;
; A TARGET WIDTH OF NOUGHT IS THE NATURAL WIDTH, not an empty sprite. So a bar with no drift
; in it came out eight pixels wide - one whole tile, sitting at the middle of the screen,
; saying "stopped" in the same shape it says "drifting slightly". What draws nothing is a
; SIZE of nought, which is the other zero and the other byte.
SETD.0 DriftLow
LDA.0
BRA driftEmpty
INIA 0x11 ; One tile by one, however wide it ends up drawn.
BRI driftSized2
driftEmpty:
RSTA ; No tiles at all, which is the off switch.
driftSized2:
SETD.1 DriftSize
STA.1
; Where it starts: the middle for a rightward drift, and that much back for a leftward one.
INIA 0d160
SETD.0 DriftLeftward
LDB.0
BRB driftAt ; Nought is rightward, so the bar starts at the middle.
SETD.0 DriftLow
LDB.0
CCF
SUB
MVQA
driftAt:
SETD.1 DriftAt
STA.1
INIA 0d4
OUTA 0xE3
INIA 0xC0
OUTA 0xE4
INIA 0x10
OUTA 0xE5 ; Sprite one begins sixteen bytes in.
INIA 0xC8
OUTA 0xE9 ; The ground block, which is a solid tile.
INIA 0x01
OUTA 0xE9 ; Attribute one, so the bar is not the colour of the moon.
SETD.0 DriftAt
LDA.0
OUTA 0xE9
RSTA
OUTA 0xE9 ; X.
INIA 0d188
OUTA 0xE9
RSTA
OUTA 0xE9 ; Y, near the bottom and clear of the ground most places.
SETD.0 DriftSize
LDA.0
OUTA 0xE9 ; One tile by one, or nothing at all when there is no drift.
RSTA
OUTA 0xE9 ; No flags.
SETD.0 DriftLow
LDA.0
OUTA 0xE9
RSTA
OUTA 0xE9 ; The width, which is the drift. NOUGHT DRAWS NOTHING.
INIA 0d3
OUTA 0xE9
RSTA
OUTA 0xE9 ; Three pixels tall.
OUTA 0xE9 ; And no depth.
RET
; ---- Sums ----
;
; DP0 names the two byte value being changed, low half first, and DP1 the one being added to
@@ -666,14 +798,29 @@ ThrustRight:
; it is one byte each.
PadUp:
0xFE 0xFF ; Minus two.
; ---- Sideways, at half the vertical ----
;
; ONE, not two. There is no air on a moon, so nothing slows a drift but the opposite thruster
; and stopping means cancelling the velocity exactly. At two a tick the smallest correction
; was twice as big as it needed to be and overshooting was the normal outcome.
PadLeft:
0xFE 0xFF ; Minus two.
0xFF 0xFF ; Minus one.
PadRight:
0x02 0x00
0x01 0x00
Held:
0x00
HasPad:
0x00
DriftLow:
0x00
DriftHigh:
0x00
DriftLeftward:
0x00
DriftAt:
0x00
DriftSize:
0x00
HalfScreen:
0xA0 0x00 ; 160 pixels, which is half of a forty column screen.