An altitude bar, and orbital speed marked on the drift bar

The orbit takes the lander off the top of the screen, and the panel only
worked while the ground was in sight. Both other bars are rates: they say
how fast, and neither says where.

The altitude bar is height above the surface underneath, up the left edge,
half a pixel of bar to a pixel of sky - the flyable band is about 256
pixels and the screen is 200 tall, so pixel for pixel would run off the
top of the very screen it describes. Above the surface rather than above
some fixed line, so it reads NOUGHT the moment the lander is down.

The marks say where 64 sixteenths is. Without one that number is folklore:
a pilot can feel that somewhere around here the falling stops and has no
way to see where. The bar is a pixel a sixteenth from the middle at 160,
so the marks sit at 224 and at the two pixels before 96, adjacent rather
than overlapping - a bar at orbital speed would otherwise hide the thing
it is being measured against.

Both in magenta. Red and green are taken and they MEAN something here,
how fast and whether it can be landed with, and an altitude is neither.
White was the first choice and the ceiling check counts white to find its
warning, so it read a warning that was never up - the suite caught that.
Cyan was the second and it is the colour of a landing pad, which is
checked as whole cells of it.

groundLevel is factored out of restOnSurface, which had the same sum.

Three checks, each seen to fail on its own break. Two flights, because no
one flight holds both ends of the bar well: the climb reads 219 pixels and
the descent lands and then stays landed. They fly on their own keyboard
file - the shared one holds a key down every forty eight bytes for the
held-thruster check, so borrowing it flew the lander from the keyboard and
the controller at once and turned the gentle descent into a crash.
This commit is contained in:
Anachronaut
2026-09-03 20:57:16 -04:00
parent c514d5328e
commit 85029d3b85
12 changed files with 315 additions and 12 deletions
+239 -2
View File
@@ -73,6 +73,7 @@ start:
CALL drawMoon
CALL putLander
CALL putGauge
CALL putOrbital
INIA 0x01
OUTA 0x02 ; Key mode.
@@ -99,6 +100,7 @@ everyFrame:
CALL showDrift
CALL showFall
CALL showFuel
CALL showHeight
SETD.0 Flying
LDA.0
BNA everyFrame
@@ -1505,6 +1507,223 @@ waitKeyDone:
; in the low half, and the answer needs both halves because a screen is taller than 255
; sixteenths.
restOnSurface:
CALL groundLevel
SETD.0 GroundLow
LDA.0
SETD.1 DownLow
STA.1
SETD.0 GroundHigh
LDA.0
SETD.1 DownHigh
STA.1
RET
; ---- How far above the ground, as a bar up the left edge ----
;
; The orbit put the lander OFF THE TOP OF THE SCREEN, and an instrument panel that only works
; while the ground is in sight is no use to a game whose best flying happens above it. Both
; other bars are rates: they say how fast, and neither of them says where.
;
; Height above the surface underneath rather than above some fixed line, so it reads NOUGHT
; the moment the lander is down - a bar that still showed a third of itself while sitting on a
; pad would be an altimeter nobody could trust. It moves as the moon does underneath, which is
; not noise: passing over a mountain really does leave less room below.
;
; Half a pixel of bar to a pixel of sky. The flyable band is about 256 pixels from the ceiling
; to the lowest ground and the screen is 200 tall, so a bar drawn pixel for pixel would run
; off the top of the very screen it is trying to describe.
showHeight:
CALL groundLevel
SETD.0 GroundLow
LDA.0
SETD.1 DownLow
LDB.1
CCF
SUB
SETD.0 HeightLow
STQ.0
SETD.0 GroundHigh
LDA.0
SETD.1 DownHigh
LDB.1
SUB ; And the borrow the half below left, which is the other half.
SETD.0 HeightHigh
STQ.0
LDA.0 ; DP0 is still HeightHigh, from the store above.
INIB 0x80
AND
BNQ showHeightNone ; Negative: the feet are under the surface, so there is no sky.
LDA.0 ; The AND left A alone, so it still holds the high half.
INIB 0d16
CCF
SUB
BNC showHeightFull ; 4,096 sixteenths or more, which is the whole bar and then some.
LDA.0 ; DP0 still names the high half, and the compare did not touch A.
SETD.0 HeightLow
LDB.0
SHL
SHL
SHL ; ---- Over thirty two, which comes out in A ----
;
; A is the HIGH half of the shift register, so three turns LEFT of
; the whole sixteen bits leaves bits five to twelve in A - which is
; the height over thirty two, in one instruction each and no
; division anywhere.
BRI showHeightReady
showHeightFull:
INIA 0d127
BRI showHeightReady
showHeightNone:
RSTA
showHeightReady:
SETD.1 HeightBar
STA.1
; ---- Grown upwards, from a fixed foot ----
;
; A sprite is placed by its TOP, so a bar that grows up is one whose top moves as its height
; changes. Both come out of the same number and the foot stays put.
INIA 0d180
SETD.0 HeightBar
LDB.0
CCF
SUB
SETD.1 HeightAt
STQ.1
; Nought is the off switch, and it is the SIZE that switches it: a target height of nought
; is the natural height, which would be a tile sitting on the ground pretending to be sky.
LDA.0 ; DP0 still names the bar, from working the top out above.
BRA showHeightEmpty
INIA 0x11
BRI showHeightSized
showHeightEmpty:
RSTA
showHeightSized:
SETD.1 HeightSize
STA.1
INIA 0d4
OUTA 0xE3
INIA 0xC0
OUTA 0xE4
INIA 0x30
OUTA 0xE5 ; Sprite three begins forty eight bytes in.
INIA 0xC8
OUTA 0xE9 ; The solid block.
INIA 0x05
OUTA 0xE9 ; ---- Scheme five, magenta ----
;
; Red and green are taken and they MEAN something here: how fast,
; and whether it can be landed with. Neither is a thing an altitude
; is, so magenta is the panel's other job - where the lander is
; rather than how it is going - and the marks below share it.
;
; Cyan was the first choice and it is the colour of a landing pad.
; The pads are checked as whole cells of it, so a three pixel bar
; in the same colour would have made that check count the panel.
INIA 0d8
OUTA 0xE9
RSTA
OUTA 0xE9 ; X, hard against the left edge and clear of the moon's middle.
SETD.0 HeightAt
LDA.0
OUTA 0xE9
RSTA
OUTA 0xE9 ; Y.
SETD.0 HeightSize
LDA.0
OUTA 0xE9
RSTA
OUTA 0xE9 ; No flags.
INIA 0d3
OUTA 0xE9
RSTA
OUTA 0xE9 ; Three pixels wide.
SETD.0 HeightBar
LDA.0
OUTA 0xE9
RSTA
OUTA 0xE9 ; The height, which is the altitude. NOUGHT DRAWS NOTHING.
OUTA 0xE9 ; And no depth, A being nought already.
RET
; ---- Where orbital speed is, marked on the drift bar ----
;
; The bar says how fast sideways and the physics says 64 sixteenths is the speed at which the
; swing outwards cancels the pull. Without a mark on it that number is FOLKLORE: a pilot can
; feel that somewhere around here the falling stops, and has no way to see where. With one,
; the bar reaching the mark IS circular orbit, under it is falling and past it is climbing,
; and the whole mechanic becomes something read at a glance instead of guessed at.
;
; One each way, because a moon that wraps can be gone round in either direction.
;
; Placed so the BAR'S EDGE MEETS THE MARK at exactly orbital speed. The rightward bar starts
; at the middle and runs 64 pixels to 223, so its mark begins at 224; the leftward one ends at
; the middle and starts at 96, so its mark is the two pixels before that. Adjacent rather than
; overlapping, or a bar at orbital speed would hide the thing it is being measured against.
;
; Written once. They never move, and a sprite table is a memory rather than a display list.
putOrbital:
INIA 0d4
OUTA 0xE3
INIA 0xC0
OUTA 0xE4
INIA 0x40
OUTA 0xE5 ; Sprite four begins sixty four bytes in.
INIA 0d94
CALL putMark
INIA 0d4
OUTA 0xE3
INIA 0xC0
OUTA 0xE4
INIA 0x50
OUTA 0xE5 ; And sprite five, sixteen bytes after it.
INIA 0d224
CALL putMark
RET
; One mark, at the screen column in A, straddling the drift bar so the bar meets it end on.
putMark:
SETD.1 MarkAt
STA.1
INIA 0xC8
OUTA 0xE9 ; The solid block, which is what every bar here is made of.
INIA 0x05
OUTA 0xE9 ; Magenta, the same as the height bar: both say where, not how fast.
; White was the first choice and white is what TEXT is, so the
; ceiling check - which counts white to find its warning - started
; counting these instead and read a warning that was never up.
LDA.1 ; DP1 still names it, from being handed it above.
OUTA 0xE9
RSTA
OUTA 0xE9 ; X.
INIA 0d184
OUTA 0xE9
RSTA
OUTA 0xE9 ; Y, four pixels above the bar it brackets.
INIA 0x11
OUTA 0xE9 ; One tile by one, however small it ends up drawn.
RSTA
OUTA 0xE9 ; No flags.
INIA 0d2
OUTA 0xE9
RSTA
OUTA 0xE9 ; Two pixels wide.
INIA 0d11
OUTA 0xE9
RSTA
OUTA 0xE9 ; And eleven tall, so it shows above and below a three pixel bar.
OUTA 0xE9 ; No depth, A being nought already.
RET
; ---- Where a lander standing on the ground below would have its top ----
;
; The same sum, wanted in two places: putting one down on the surface, and measuring how far
; above the surface one is. In sixteenths, because that is what a height is measured in.
groundLevel:
SETD.0 SurfaceAt
LDA.0
INIB 0d8
@@ -1516,13 +1735,13 @@ restOnSurface:
SHL
SHL
SHL ; Four turns, which is times sixteen.
SETD.0 DownHigh
SETD.0 GroundHigh
STA.0
RSTA
CCF
ADD
MVQA
SETD.0 DownLow
SETD.0 GroundLow
STA.0
RET
@@ -2020,6 +2239,24 @@ OrbitAt:
; which is the only thing here that gravity did not already need.
OrbitStep:
0x00
; Ground level under the lander, the height above it, and what the bar makes of that.
GroundLow:
0x00
GroundHigh:
0x00
HeightLow:
0x00
HeightHigh:
0x00
HeightBar:
0x00
HeightAt:
0x00
HeightSize:
0x00
MarkAt:
0x00
Outward:
0x00
Lift: