A retro thruster, at half the strength of the one that lifts
Arresting a rise meant a sideways burn and a wait for the orbit to come back round. That is how a rendezvous really is flown and it is a lot to ask of somebody who has not flown one before, so down now makes the correction directly. HALF THE STRENGTH, deliberately: one sixteenth a tick against two, which is exactly gravity's own step. So it can stop a climb and it can hurry a descent, and it can never turn a landing approach into a crash faster than simply letting go would - the cheap way out of a mistake stays the expensive one. Four against eight on a keyboard, which is the same ratio. It does NOTHING to a lander on the ground, and that guard is load bearing rather than tidy. touchdown has already had its say and returns early once a lander is down, so there is nothing underneath to stop it and no crash to say it happened: measured without the guard, holding it drives the lander clean off the picture and spends a fifth of the tank doing it. ---- And the fixture that hid all of that ---- The first version of the landed check passed just as happily with the guard deleted, and the reason is worth writing down. A lander that has landed WAITS to be told its message has been read, and the keyboard fixture pads with NULs, which are not keys. So the program sat in that loop for ever and the picture was frozen at the moment of touchdown - every thruster held afterwards did nothing, which reads exactly like a working guard. The pad now presses A to get past the wait before the check tests anything, and both the row AND the fuel are read, because an engine that fired and moved nothing would keep the row and one that moved the lander for free would keep the fuel. The altitude bar check upstream leans on that same freeze for its stable end, and its comment said "stays landed" when what it means is "is not running any more". Corrected, because that is the sort of comment that sends the next person looking in the wrong place.
This commit is contained in:
@@ -25,7 +25,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -32,7 +32,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -108,7 +108,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -27,7 +27,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -13,7 +13,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5751
|
||||
Lander.sbx 5823
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
+75
-4
@@ -1978,10 +1978,12 @@ EOT
|
||||
# while landed" - it is the two together that say the thing is measuring something.
|
||||
#
|
||||
# Two flights, because no one flight holds both ends well. The climb reaches a bar of two
|
||||
# hundred pixels and is nowhere near the edge of the claim; the descent lands and then STAYS
|
||||
# landed, so its end of it cannot drift with the boot time the way the deleted orbit check
|
||||
# did. One flight that did both spent four seconds airborne and read thirty pixels, which is a
|
||||
# margin thin enough to be luck.
|
||||
# hundred pixels and is nowhere near the edge of the claim; the descent lands, and a landed
|
||||
# lander then WAITS to be told its message has been read, so the picture is frozen at the
|
||||
# moment of touchdown and that end cannot drift with the boot time the way the deleted orbit
|
||||
# check did. (Frozen, not merely still - the retro thruster check below had to press A to get
|
||||
# past that wait before it could test anything at all.) One flight that did both spent four
|
||||
# seconds airborne and read thirty pixels, a margin thin enough to be luck.
|
||||
#
|
||||
# The marks are checked BY POSITION rather than by counting, because position is the whole
|
||||
# claim: 64 sixteenths is orbital speed, the bar is a pixel a sixteenth from the middle at
|
||||
@@ -2212,6 +2214,75 @@ EOT
|
||||
&& result ok "and a lander at the ceiling is only on screen zoomed out" "off the top, then at row $OUTSHIP" \
|
||||
|| result no "and a lander at the ceiling is only on screen zoomed out" "row $INSHIP zoomed in, row $OUTSHIP out"
|
||||
|
||||
# ---- The retro thruster ----
|
||||
#
|
||||
# Arresting a rise used to take a sideways burn and a wait for the orbit to come round, which
|
||||
# is how a rendezvous really is flown and is a lot to ask of somebody who has not flown one
|
||||
# before. Down makes the correction directly, at HALF the strength of up - one sixteenth a
|
||||
# tick against two, which is exactly gravity's own step, so it can hurry a descent and can
|
||||
# never turn a landing approach into a crash faster than simply letting go would.
|
||||
#
|
||||
# The same four hundred frames of climb in both, so the two pictures are identical up to the
|
||||
# moment the retro fires and the only difference measured is the thing being tested. Read off
|
||||
# the ALTITUDE BAR rather than the lander, because at this point in the flight the lander is
|
||||
# off the top of the screen - which is what that bar is for.
|
||||
python3 -c "open('$BUILD/coast.pad','wb').write(b'\x08' * 400 + b'\x00' * 20000)"
|
||||
python3 -c "open('$BUILD/retro.pad','wb').write(b'\x08' * 400 + b'\x04' * 600 + b'\x00' * 20000)"
|
||||
# ---- The A press matters, and it took a while to find out why ----
|
||||
#
|
||||
# A lander that has just landed WAITS to be told the message has been read - waitKey, which
|
||||
# spins until A or Start or a key. The keyboard fixture pads with NULs and a NUL is not a key,
|
||||
# so without the press here the program sits in that loop for ever and the picture is frozen
|
||||
# at the moment of landing. Every thruster held afterwards did nothing, which reads exactly
|
||||
# like a working guard and is nothing of the sort: the first version of this check passed just
|
||||
# as happily with the guard deleted.
|
||||
python3 -c "open('$BUILD/sit.pad','wb').write(b'\x00' * 150 + b'\x08' * 90 + b'\x00' * 100 + b'\x10' * 8 + b'\x00' * 8000)"
|
||||
python3 -c "open('$BUILD/sitdown.pad','wb').write(b'\x00' * 150 + b'\x08' * 90 + b'\x00' * 100 + b'\x10' * 8 + b'\x04' * 2000 + b'\x00' * 8000)"
|
||||
for view in coast retro; do
|
||||
timeout 60 "$EMU" --fast --cycles 8600000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/$view.pad" --screen "$BUILD/$view.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/$view.out" 2>&1 || true
|
||||
done
|
||||
for view in sit sitdown; do
|
||||
timeout 60 "$EMU" --fast --cycles 14000000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/$view.pad" --screen "$BUILD/$view.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/$view.out" 2>&1 || true
|
||||
done
|
||||
read -r COASTALT RETROALT SITROW DOWNROW <<EOT
|
||||
$(python3 -c "
|
||||
def look(path):
|
||||
d = open(path, 'rb').read()
|
||||
width = int(d[:40].split()[1])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
bar = sum(1 for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == bytes.fromhex('c860c0') and i % width < 25)
|
||||
ship = [i // width for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == bytes.fromhex('d8c048')]
|
||||
# The fuel gauge, which says whether the engine fired at all.
|
||||
fuel = sum(1 for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == bytes.fromhex('50c050') and i // width < 16)
|
||||
return bar // 3, (min(ship) if ship else -1), fuel
|
||||
print(look('$BUILD/coast.ppm')[0], look('$BUILD/retro.ppm')[0],
|
||||
'%d,%d' % look('$BUILD/sit.ppm')[1:], '%d,%d' % look('$BUILD/sitdown.ppm')[1:])
|
||||
" 2>/dev/null || echo "0 0 -1 -2")
|
||||
EOT
|
||||
[ "$RETROALT" -lt "$COASTALT" ] \
|
||||
&& result ok "the retro thruster hurries a descent" "$COASTALT of sky coasting, $RETROALT under thrust" \
|
||||
|| result no "the retro thruster hurries a descent" "$COASTALT coasting, $RETROALT under thrust"
|
||||
# And it does NOTHING on the ground. Without that guard a landed lander holding it sinks
|
||||
# straight through the moon - touchdown has already had its say and will not speak again, so
|
||||
# there is nothing underneath to stop it and no crash to say it happened.
|
||||
# Both the row AND the fuel, because either alone is soft: an engine that fired and moved
|
||||
# nothing would keep the row, and one that moved the lander without charging for it would keep
|
||||
# the fuel. With the guard deleted this reads "off screen" and a fifth of the tank gone - it
|
||||
# goes straight through the moon, because touchdown has already had its say and will not speak
|
||||
# again, so there is nothing underneath to stop it and no crash to say it happened.
|
||||
[ "$DOWNROW" = "$SITROW" ] && [ "$SITROW" != "-1,0" ] \
|
||||
&& result ok "and does nothing to a lander on the ground" "$SITROW unchanged after two thousand frames of it" \
|
||||
|| result no "and does nothing to a lander on the ground" "$SITROW sitting, $DOWNROW holding it down"
|
||||
|
||||
# ---- The orbiting station ----
|
||||
#
|
||||
# A body at orbital speed, which under the rules already here is all a circular orbit IS: the
|
||||
|
||||
Reference in New Issue
Block a user