Thruster flames, so a watcher can see what the pilot is doing
Every reading on this screen is a number drawn as a bar - how fast sideways, how fast down, how much sky, how much tank - and all of it says what is happening TO the lander. None of it says what the pilot is doing about it, so somebody watching over a shoulder has to read gauges to work out that a thruster is even lit. A plume hangs off whichever side the engine is pushing from: under the lander to lift, over it to retro, and on the far side from the way it is being pushed sideways, since that is the side the gas leaves. One tile does up and down, because a vertical flip turns one into the other, and a second does the sides, because a flip cannot rotate a tile a quarter turn. Twenty four pixels each, on purpose, so a count of them means something. HELD, NOT FIRED. The engine fires one frame in ten, because that is the tick gravity is applied on, and a flame that honest would be one frame of light six times a second - a fault lamp, not a rocket. What is drawn is the button being down, which is the truthful answer to "is the pilot burning": the tick is how the sum gets done, not what is happening. An empty tank draws nothing, and nor does the retro thruster on the ground, because in both cases the button really is doing nothing. The second of those was a lie the first version told. Red, and that is by elimination again: white is the ceiling warning, cyan the landing pads, magenta the instruments, blue the station, yellow the lander itself - and the lander is counted as exactly forty pixels of yellow, so a yellow flame would have broken it. Three checks, each seen to fail on its own break. Two things the fixtures taught: a lander placed at the world's origin sits BEHIND the two row window, which reads exactly like a flame that is not drawn; and red has to be looked for in a box round the lander rather than a column, because the speed bars go red and one of the four pads is red too.
This commit is contained in:
@@ -2515,6 +2515,94 @@ grep -q "Wrecked against the station" "$BUILD/wreck.out" \
|
||||
&& result ok "and the same approach unmatched is a wreck" "64 sixteenths, eight times the limit" \
|
||||
|| result no "and the same approach unmatched is a wreck" "no wreck in the transcript"
|
||||
|
||||
# ---- Thruster flames ----
|
||||
#
|
||||
# Every other reading here is a number drawn as a bar: how fast sideways, how fast down, how
|
||||
# much sky, how much tank. All of it says what is happening TO the lander and none of it says
|
||||
# what the PILOT is doing, so somebody watching over a shoulder has to read gauges to work out
|
||||
# that a thruster is even lit.
|
||||
#
|
||||
# A plume hangs off whichever side the engine is pushing from - under the lander to go up,
|
||||
# over it to go down, and on the far side from the way it is being pushed sideways. Twenty
|
||||
# four pixels of it, which is the whole tile, so the count says it is not clipped.
|
||||
#
|
||||
# Held rather than fired. The engine fires one frame in ten, because that is the tick gravity
|
||||
# is applied on, and a flame that honest would be one frame of light six times a second - a
|
||||
# fault lamp, not a rocket. The button being down is the thing being shown.
|
||||
python3 -c "
|
||||
import struct
|
||||
# The same place every time, with an empty tank for the last of them. Down 512 sixteenths and
|
||||
# not nought: the world's origin is the top of the screen, and the two row window is drawn OVER
|
||||
# the map there, so a lander placed at the origin is behind the fuel gauge and its flame with
|
||||
# it - which reads exactly like a flame that is not being drawn.
|
||||
for name, fuel in (('flamefull', 255), ('flamedry', 0)):
|
||||
open('$BUILD/%s.state' % name, 'wb').write(struct.pack('<hhhhhhBBBB',
|
||||
0x14A0, 512, 0, 0, 0x14A0, 2600, fuel, 0, 0, 0))
|
||||
"
|
||||
for which in flamefull flamedry; do
|
||||
cp "$ROOT/Tests/build/disks/cosmos.img" "$BUILD/$which.img"
|
||||
"$ROOT/SplitDisk" put "$BUILD/$which.img" "$BUILD/$which.state" /lander.state > /dev/null
|
||||
done
|
||||
for held in none up down right left dry; do
|
||||
case "$held" in
|
||||
none) byte='\x00'; disk=flamefull ;;
|
||||
up) byte='\x08'; disk=flamefull ;;
|
||||
down) byte='\x04'; disk=flamefull ;;
|
||||
right) byte='\x01'; disk=flamefull ;;
|
||||
left) byte='\x02'; disk=flamefull ;;
|
||||
dry) byte='\x08'; disk=flamedry ;;
|
||||
esac
|
||||
python3 -c "open('$BUILD/flame$held.pad','wb').write(b'$byte' * 40000)"
|
||||
timeout 60 "$EMU" --fast --cycles 1500000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/flame$held.pad" --screen "$BUILD/flame$held.ppm" \
|
||||
--disk "$BUILD/$disk.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/flame$held.out" 2>&1 || true
|
||||
done
|
||||
read -r FNONE FUP FDOWN FRIGHT FLEFT FDRY <<EOT
|
||||
$(python3 -c "
|
||||
def flame(path):
|
||||
# Red, and IN A BOX ROUND THE LANDER. The speed bars go red when they say a landing would
|
||||
# not be survived, and one of the four landing pads is red as well - both of them turned
|
||||
# up inside a filter that only looked at the column.
|
||||
d = open(path, 'rb').read()
|
||||
width = int(d[:40].split()[1])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
def where(colour):
|
||||
c = bytes.fromhex(colour)
|
||||
return [(i % width, i // width) for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == c]
|
||||
ship = where('d8c048')
|
||||
if not ship:
|
||||
return 'noship'
|
||||
sx, sy = min(x for x, y in ship), min(y for x, y in ship)
|
||||
lit = [(x, y) for x, y in where('d04038')
|
||||
if sx - 12 <= x <= sx + 20 and sy - 12 <= y <= sy + 20]
|
||||
if not lit:
|
||||
return '0'
|
||||
# Which side of the lander it came out on, which is the half that matters.
|
||||
fx, fy = min(x for x, y in lit), min(y for x, y in lit)
|
||||
side = 'below' if fy > sy else 'above'
|
||||
if fx < sx: side = 'left'
|
||||
if fx > sx + 4: side = 'right'
|
||||
return '%d%s' % (len(lit), side)
|
||||
print(flame('$BUILD/flamenone.ppm'), flame('$BUILD/flameup.ppm'),
|
||||
flame('$BUILD/flamedown.ppm'), flame('$BUILD/flameright.ppm'),
|
||||
flame('$BUILD/flameleft.ppm'), flame('$BUILD/flamedry.ppm'))
|
||||
" 2>/dev/null || echo "x x x x x x")
|
||||
EOT
|
||||
[ "$FNONE" = "0" ] && [ "$FUP" = "24below" ] && [ "$FDOWN" = "24above" ] \
|
||||
&& result ok "a lifting thruster shows a flame under the lander" "none held draws none, up draws 24 below, down 24 above" \
|
||||
|| result no "a lifting thruster shows a flame under the lander" "none $FNONE, up $FUP, down $FDOWN"
|
||||
# Sideways is the one that is easy to get backwards: pushing RIGHT means the plume comes out
|
||||
# of the LEFT of the lander, because that is the side the gas leaves from.
|
||||
[ "$FRIGHT" = "24left" ] && [ "$FLEFT" = "24right" ] \
|
||||
&& result ok "and comes out the far side going sideways" "right draws left, left draws right" \
|
||||
|| result no "and comes out the far side going sideways" "right $FRIGHT, left $FLEFT"
|
||||
# An empty tank draws nothing, because then the button really is doing nothing.
|
||||
[ "$FDRY" = "0" ] \
|
||||
&& result ok "and an empty tank draws none at all" "the button is doing nothing, and shows it" \
|
||||
|| result no "and an empty tank draws none at all" "$FDRY with a dry tank"
|
||||
|
||||
# ---- Clearing puts the cursor back at the top ----
|
||||
#
|
||||
# A screen with nothing on it and a cursor half way down it is not a cleared screen. This
|
||||
|
||||
Reference in New Issue
Block a user