Dust on landing, gas on letting go, and a lander that stays let go

One particle system, three uses now: a lander coming apart, dust kicked
up by a landing, and gas out of a docking port on release. Where they
start, how fast they go, what colour they are and how long they last are
arguments; everything else is shared.

Dust goes sideways and UP off the lander's feet, because that is where
kicked dust goes and there is ground in the way of the rest of it. Gas
goes evenly in every direction, because nothing is in the way of a
docking port. Neither happens on docking - a dock is a catch and not a
touchdown, and there is nothing under it to kick.

---- Ticked from the frame loop, not run in place ----

The explosion can afford to stop the world; there is nothing left to fly.
The undocking puff cannot, because it goes off on the frame a thruster is
pressed, and freezing a quarter of a second exactly then is felt as the
controls sticking. So a burst advances one frame at a time from the main
loop, and the two that can afford to wait just pump that same tick until
the air is clear.

---- And letting go did not let go ----

Which the puff is what found. A docked lander sits EXACTLY one tile under
the station, so releasing upwards moved it towards the station and it
docked again on the very next frame: took the fuel again, said so again,
and waited to be told the message had been read - which reads as the
controls locking up the instant they are used.

It has to get clear now before it can take hold again, and the two
distances have to differ: docking wants one tile, re-arming wants two.
A single distance re-armed on the frame it let go, because a tile is
exactly where it was sitting.

Three checks, each seen to fail on its own break. The last of them
measures HOW FAR the lander has got and not merely that it moved: a
sixteen frame pause on release still leaves it climbing, four rows short
of a free run, so "it moved" would pass for a stall that has been slept
through.
This commit is contained in:
Anachronaut
2026-09-04 12:23:31 -04:00
parent 115efa1fa1
commit 0264b19a3d
13 changed files with 310 additions and 53 deletions
+222 -42
View File
@@ -112,6 +112,7 @@ everyFrame:
CALL showFall
CALL showFuel
CALL showHeight
CALL burstTick ; Whatever is in the air, one frame on.
SETD.0 Flying
LDA.0
BNA everyFrame
@@ -1795,6 +1796,8 @@ touchdown:
SUB
BNC touchdownCrash
CALL landingDust ; Something to see for an arrival, as a crash has always had.
; ---- Down safely, which is not the end of anything ----
;
; The view settles, the arrival is dealt with, and the lander sits where it is until
@@ -1877,13 +1880,13 @@ dock:
CALL magnitude
SETD.0 DriftHigh
LDA.0
BNA dockDone
BNA dockAway ; 256 sixteenths or more, which is properly out of the way.
SETD.0 DriftLow
LDA.0
INIB 0d128
CCF
SUB
BNC dockDone ; A whole tile away or more, so there is nothing to touch.
BNC dockDone ; A tile away or more: too far to dock, not far enough to re-arm.
; ---- And close enough, up and down ----
SETD.0 StationDownLow
@@ -1905,7 +1908,7 @@ dock:
CALL magnitude
SETD.0 DriftHigh
LDA.0
BNA dockDone
BNA dockAway
SETD.0 DriftLow
LDA.0
INIB 0d128
@@ -1913,6 +1916,19 @@ dock:
SUB
BNC dockDone
; ---- Still in the doorway it just left by ----
;
; Letting go UPWARDS moves the lander towards the station, so without this it docked again on
; the very next frame - took the fuel again, said so again, and waited to be told the message
; had been read, which reads as the controls locking up the instant they are used.
;
; TWO DISTANCES, and they have to be different. Docking wants a tile; re-arming wants two,
; because a lander riding the station sits EXACTLY a tile under it - so a single distance
; re-armed on the very frame it let go, and the frame after that it was back on.
SETD.0 DockClear
LDA.0
BRA dockDone
; ---- Touching. Now, how fast, and RELATIVE TO WHAT ----
;
; The station is going at orbital speed, so a lander going at orbital speed is standing still
@@ -1966,6 +1982,12 @@ dock:
SETD.0 DockedText
CALL sayInWindow
CALL waitKey
RET
dockAway:
INIA 0x01
SETD.0 DockClear
STA.0 ; Two tiles off, so the next arrival counts as an arrival.
dockDone:
RET
@@ -2034,6 +2056,9 @@ dockLetGo:
RSTA
SETD.0 Docked
STA.0
SETD.0 DockClear
STA.0 ; A is still nought: not clear until it has actually got away.
CALL undockGas ; Started and left running: the pilot is mid-burn.
RET
; ---- Half a pixel of the way there, or the whole of it if that is nearer ----
@@ -2322,41 +2347,53 @@ putFlame:
OUTA 0xE9 ; And no depth.
RET
; ---- Coming apart, which is the only thing on this screen that is not a number ----
; ---- Six pieces of something, thrown out from somewhere ----
;
; A crash used to be a line of text and a lander still sitting there in one piece. The verdict
; was the whole of it, and somebody watching a recording had to read the words to know what had
; happened - the same problem the flames were for.
; One system, three uses: a lander coming apart, dust kicked up by a landing, and gas out of a
; docking port on release. What differs is where they start, how fast they go, what colour
; they are and how long they last, so all four of those are arguments and the rest is shared.
;
; The lander goes and six pieces of it leave in a rough hexagon, at its own colour, for half a
; second. The world is not running while this happens: it is a loop of its own, so nothing has
; to know how to be half destroyed.
explode:
RSTA
CALL hideSprite ; The lander itself.
INIA 0x70
CALL hideSprite
INIA 0x80
CALL hideSprite ; And both flames, which would otherwise hang in the air.
; ---- Ticked from the frame loop rather than run in place ----
;
; The explosion can afford to stop the world - there is nothing left to fly. The undocking puff
; CANNOT: it goes off on the frame a thruster is pressed, and freezing for a quarter of a
; second exactly then would be felt as the controls sticking. So the burst advances one frame
; at a time from the main loop, and the two that can afford to wait simply pump that same tick
; until it runs out.
startBurst:
; DP0 names six pairs of speeds; the origin, colour and length are already set.
SETD.1 BurstV
INIA 0d24
SETD.2 CopyLeft
STA.2
startBurstCopy:
LDA.0
STA.1
INCD.0
INCD.1
SETD.2 CopyLeft
LDA.2
DECA
STA.2
BNA startBurstCopy
; Every piece starts where the lander was.
RSTA
SETD.0 SparkAt
STA.0
INIA 0d6
SETD.0 SparkCount
STA.0
explodeStart:
; DP0 is what copyWord reads and DP1 what it writes, so the lander's place is DP0. Written
; the other way round first, which copied the empty sparks OVER ShipX - and since that is
; the view block, the lander's own column with it.
SETD.0 ShipX
startBurstPlace:
; DP0 is what copyWord reads and DP1 what it writes, so the origin is DP0. Written the other
; way round first, which copied the empty pieces OVER ShipX - and since that is in the view
; block, the lander's own column went with them.
SETD.0 BurstOXLow
SETD.1 Spark
SETD.2 SparkAt
LDA.2
DPUA.1
CALL copyWord
SETD.0 ShipTopLow
SETD.0 BurstOYLow
SETD.1 Spark
SETD.2 SparkAt
LDA.2
@@ -2374,13 +2411,14 @@ explodeStart:
LDA.0
DECA
STA.0
BNA explodeStart
BNA startBurstPlace
RET
INIA 0d48
SETD.0 SparkLeft
STA.0 ; Getting on for a second, which is long enough to watch.
explodeFrame:
CALL waitFrame
; One frame of whatever is in the air. Nothing at all when nothing is.
burstTick:
SETD.0 BurstLeft
LDA.0
BRA burstTickDone
RSTA
SETD.0 SparkAt
STA.0
@@ -2390,12 +2428,12 @@ explodeFrame:
INIA 0d6
SETD.0 SparkCount
STA.0
explodeOne:
burstOne:
SETD.0 Spark
SETD.2 SparkAt
LDA.2
DPUA.0
SETD.1 SparkV
SETD.1 BurstV
DPUA.1
CALL addWord ; Across, by however fast this piece is going.
SETD.0 Spark
@@ -2404,7 +2442,7 @@ explodeOne:
INCA
INCA
DPUA.0
SETD.1 SparkV
SETD.1 BurstV
DPUA.1
CALL addWord ; And down.
CALL putSpark
@@ -2425,22 +2463,26 @@ explodeOne:
LDA.0
DECA
STA.0
BNA explodeOne
BNA burstOne
SETD.0 SparkLeft
SETD.0 BurstLeft
LDA.0
DECA
STA.0
BNA explodeFrame
BNA burstTickDone
CALL hideBurst ; The last frame of it, so they go rather than hang there.
burstTickDone:
RET
; And away, or they would sit there under the verdict.
; Every piece off the screen, which is a size of nought six times.
hideBurst:
INIA 0x90
SETD.0 SparkSlot
STA.0
INIA 0d6
SETD.0 SparkCount
STA.0
explodeClear:
hideBurstOne:
SETD.0 SparkSlot
LDA.0
CALL hideSprite
@@ -2454,7 +2496,103 @@ explodeClear:
LDA.0
DECA
STA.0
BNA explodeClear
BNA hideBurstOne
RET
; For the two that can afford to wait: pump the tick until there is nothing left in the air.
runBurst:
CALL waitFrame
CALL burstTick
SETD.0 BurstLeft
LDA.0
BNA runBurst
RET
; ---- Coming apart, which is the only thing on this screen that is not a number ----
;
; A crash used to be a line of text and a lander still sitting there in one piece. The verdict
; was the whole of it, and somebody watching a recording had to read the words to know what had
; happened - the same problem the flames were for.
explode:
RSTA
CALL hideSprite ; The lander itself.
INIA 0x70
CALL hideSprite
INIA 0x80
CALL hideSprite ; And both flames, which would otherwise hang in the air.
SETD.0 ShipX
SETD.1 BurstOXLow
CALL copyWord
SETD.0 ShipTopLow
SETD.1 BurstOYLow
CALL copyWord
INIA 0x03
SETD.0 BurstColour
STA.0 ; Yellow: it is the lander that is coming apart.
INIA 0d48
SETD.0 BurstLeft
STA.0 ; Getting on for a second, which is long enough to watch.
SETD.0 SparkV
CALL startBurst
CALL runBurst
RET
; ---- Dust, for a landing that went right ----
;
; A crash has had something to watch since the pieces arrived, and an arrival did not. The
; puff comes off the LANDER'S FEET rather than its middle, which is where the ground is, and
; it goes sideways and up because that is where kicked dust goes.
;
; Not on docking. A dock is a catch and not a touchdown - there is nothing under it to kick.
landingDust:
SETD.0 ShipX
SETD.1 BurstOXLow
CALL copyWord
SETD.0 ShipTopLow
LDA.0
INIB 0d8
CCF
ADD
SETD.1 BurstOYLow
STQ.1
SETD.0 ShipTopHigh
LDA.0
RSTB
ADD ; A tile down from its top, which is where its feet are.
SETD.1 BurstOYHigh
STQ.1
INIA 0x07
SETD.0 BurstColour
STA.0 ; White, which is the one thing on this moon that is not grey.
INIA 0d16
SETD.0 BurstLeft
STA.0
SETD.0 DustV
CALL startBurst
CALL runBurst
RET
; ---- And gas, for letting go of a station ----
;
; Something has to come out of a docking port when it lets go, and this is a small symmetric
; puff of it. STARTED AND LEFT RUNNING, unlike the other two: it happens on the frame a
; thruster is pressed, and stopping the world exactly then would be felt as the controls
; sticking rather than as an effect.
undockGas:
SETD.0 ShipX
SETD.1 BurstOXLow
CALL copyWord
SETD.0 ShipTopLow
SETD.1 BurstOYLow
CALL copyWord
INIA 0x07
SETD.0 BurstColour
STA.0
INIA 0d16
SETD.0 BurstLeft
STA.0
SETD.0 GasV
CALL startBurst
RET
; One piece, where the pointers say it now is.
@@ -2468,8 +2606,9 @@ putSpark:
OUTA 0xE5
INIA 0xC8
OUTA 0xE9 ; The solid block, at two pixels by two.
INIA 0x03
OUTA 0xE9 ; Yellow: it is the lander that is coming apart.
SETD.0 BurstColour
LDA.0
OUTA 0xE9
SETD.0 Spark
SETD.2 SparkAt
LDA.2
@@ -3639,6 +3778,11 @@ ShipTopHigh:
; beside them are a rough hexagon, so it comes apart evenly rather than in a line.
Spark:
#Reserve 0d24
; The speeds in use this burst, copied over from one of the three below.
BurstV:
#Reserve 0d24
; A lander coming apart: a rough hexagon at two pixels a frame, so it goes evenly.
SparkV:
0x02 0x00 0x00 0x00
0x01 0x00 0x02 0x00
@@ -3646,13 +3790,45 @@ SparkV:
0xFE 0xFF 0x00 0x00
0xFF 0xFF 0xFE 0xFF
0x01 0x00 0xFE 0xFF
; Dust off a landing: sideways and UP, because that is where kicked dust goes, and none of it
; downwards because there is ground in the way.
DustV:
0x03 0x00 0x00 0x00
0xFD 0xFF 0x00 0x00
0x02 0x00 0xFF 0xFF
0xFE 0xFF 0xFF 0xFF
0x01 0x00 0xFE 0xFF
0xFF 0xFF 0xFE 0xFF
; Gas out of a docking port: small, even, and in every direction, because nothing is in the way.
GasV:
0x02 0x00 0x00 0x00
0xFE 0xFF 0x00 0x00
0x01 0x00 0x01 0x00
0xFF 0xFF 0x01 0x00
0x01 0x00 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF
SparkAt:
0x00
SparkSlot:
0x00
SparkCount:
0x00
SparkLeft:
BurstLeft:
0x00
BurstColour:
0x00
BurstOXLow:
0x00
BurstOXHigh:
0x00
BurstOYLow:
0x00
BurstOYHigh:
0x00
CopyLeft:
0x00
HideSlot:
0x00
@@ -3686,6 +3862,10 @@ FlameBack:
; Holding onto the station, which is the same kind of rest as sitting on the ground.
Docked:
0x00
; Whether it has been clear of the station since it last let go. It starts clear, having never
; been attached to anything.
DockClear:
0x01
; Where the lander is sliding to, and how far it has to go to get there.
DockTargetLow:
0x00
File diff suppressed because one or more lines are too long