The room a zoom buys goes to the sky, not to the moon
Zooming out drew fifty rows DOWN from the world's origin, which put exactly the same sky on the screen as before with twice as much moon under it. Measured: 47 per cent rock zoomed in and 71 per cent zoomed out. A zoom that shows you more of the thing you cannot fly through is not worth a button. The eighty column screen is fifty rows and the flyable band is thirty - the ceiling is eight rows above the origin and the deepest valley is twenty two below it - so the twenty rows a zoom buys have to go somewhere. They go above. The wide view starts twenty four rows over the origin, the ground sits near the bottom, and the whole band is on the screen: 23 per cent rock instead of 71. Which needed three things. The moon is drawn from row minus twenty four rather than from nought, because rows above the origin are sky by definition and because whatever the shell left in them is otherwise still there. The row origin comes out of the view block like every other screen number. And the lander's own Y moves with the view, which meant making toPixels' answer SIGNED at last: it masks to twelve bits, so a lander above the origin came back as a large positive number rather than a small negative one - harmless while such a lander was off the picture either way, and wrong the moment the view moved up to include it. That is the point of the button. A lander at the ceiling is off the top of a forty column screen, which is where the orbit lives and why the altitude bar had to exist; zoomed out it is at row 149 and you can watch the whole orbit. Four checks, and the proportion is deliberately not on its own: measured alone it passes for a moon floating over a void, because pointing the view back at the origin leaves the rows under the terrain simply never drawn, and black counts as sky. Both breaks that matter went straight through it. What catches them is that the ground has to reach the bottom of the screen and the sky has to be empty - the latter only on a shell scrolled a hundred and eighteen lines deep, since that is what it takes to get anything into the rows the wide view moves into. The tap fixture also moved to frame 100. Fifty rows of moon take longer to draw than twenty five, and a six frame tap at frame thirty now lands before the program is reading a controller at all, which reads exactly like a button that has stopped working.
This commit is contained in:
@@ -25,7 +25,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
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 5304
|
||||
Lander.sbx 5365
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
+98
-3
@@ -2050,10 +2050,14 @@ EOT
|
||||
# is not only the mode it lands on but the TIME it costs, because each swap redraws the whole
|
||||
# moon. Holding is checked to land in the same place as tapping, which a strobe cannot do.
|
||||
python3 -c "open('$BUILD/narrow.pad','wb').write(b'\x00' * 8000)"
|
||||
python3 -c "open('$BUILD/tap.pad','wb').write(b'\x00' * 30 + b'\x20' * 6 + b'\x00' * 8000)"
|
||||
python3 -c "open('$BUILD/hold.pad','wb').write(b'\x00' * 30 + b'\x20' * 300 + b'\x00' * 8000)"
|
||||
# A hundred frames before the button, because the program spends the first sixty or so
|
||||
# drawing fifty rows of moon and is not reading a controller yet. A six frame tap at frame
|
||||
# thirty used to work and stopped the day the moon got deeper, which reads exactly like a
|
||||
# button that no longer does anything.
|
||||
python3 -c "open('$BUILD/tap.pad','wb').write(b'\x00' * 100 + b'\x20' * 8 + b'\x00' * 8000)"
|
||||
python3 -c "open('$BUILD/hold.pad','wb').write(b'\x00' * 100 + b'\x20' * 300 + b'\x00' * 8000)"
|
||||
for view in narrow tap hold; do
|
||||
timeout 60 "$EMU" --fast --cycles 2200000 --keyboard "$BUILD/fly.keys" \
|
||||
timeout 60 "$EMU" --fast --cycles 3500000 --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
|
||||
@@ -2117,6 +2121,97 @@ print(int(d[:40].split()[1]))
|
||||
&& result ok "and holding it swaps once, not sixty times a second" "held lands where tapped did" \
|
||||
|| result no "and holding it swaps once, not sixty times a second" "tapped $TAPY, held $HELDY at $HELD across"
|
||||
|
||||
# ---- And the room the zoom buys goes to the sky, not to the rock ----
|
||||
#
|
||||
# The first version of this drew fifty rows DOWN from the world's origin, which put exactly
|
||||
# the same sky on the screen as before with twice as much moon under it: 47 per cent moon
|
||||
# zoomed in and 71 per cent zoomed out. A zoom that shows you more of the thing you cannot fly
|
||||
# through is not worth a button. The rows go above instead, so the wide view starts twenty
|
||||
# four rows over the origin and the ground sits near the bottom of it.
|
||||
#
|
||||
# THREE CHECKS, and the proportion alone is not one of them. Measured on its own it passes for
|
||||
# a moon floating over a void: point the view at the world's origin again and the rows below
|
||||
# the terrain are simply never drawn, which is black, which counts as sky. Both breaks that
|
||||
# matter went straight through a proportion check and are caught by the two beside it - the
|
||||
# ground has to REACH THE BOTTOM of the screen, and the sky above the world has to be empty
|
||||
# rather than holding whatever the shell left in those rows.
|
||||
#
|
||||
# THE SHELL HAS TO BE SCROLLED DEEP for the second of those to mean anything, and that took
|
||||
# finding out. The map is a ring of 128 rows and the wide view moves into rows 104 to 127; a
|
||||
# shell that has only printed a few lines has never written up there, so leaving those rows
|
||||
# alone looks exactly like clearing them. A hundred and eighteen returns first, which puts the
|
||||
# prompt in that band, and then the difference appears: 136 pixels of somebody else's text
|
||||
# hanging in the sky.
|
||||
python3 -c "open('$BUILD/deep.keys','wb').write(b'\n' * 118 + b'Lander\n' + b'\x00' * 8000)"
|
||||
timeout 60 "$EMU" --fast --cycles 8000000 --keyboard "$BUILD/deep.keys" \
|
||||
--pad "$BUILD/tap.pad" --screen "$BUILD/deep.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/deep.out" 2>&1 || true
|
||||
read -r NARROWMOON WIDEMOON NARROWFLOOR WIDEFLOOR WIDESKY <<EOT
|
||||
$(python3 -c "
|
||||
def look(path):
|
||||
d = open(path, 'rb').read()
|
||||
head = d[:40].split()
|
||||
width, height = int(head[1]), int(head[2])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
moon = bytes.fromhex('d8d8d8')
|
||||
at = [(i % width, i // width) for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == moon]
|
||||
rock = 100 * len(at) // (width * height)
|
||||
floor = sum(1 for x, y in at if y == height - 1)
|
||||
# Below the two row window and above the highest ground a terrain row can reach.
|
||||
sky = sum(1 for x, y in at if 16 <= y < 260)
|
||||
return rock, floor, sky, width
|
||||
n = look('$BUILD/narrow.ppm'); w = look('$BUILD/hold.ppm')
|
||||
print(n[0], w[0], '%d/%d' % (n[1], n[3]), '%d/%d' % (w[1], w[3]),
|
||||
look('$BUILD/deep.ppm')[2])
|
||||
" 2>/dev/null || echo "0 100 0/1 0/1 999")
|
||||
EOT
|
||||
[ "$WIDEMOON" -lt "$NARROWMOON" ] && [ "$WIDEMOON" -lt 35 ] \
|
||||
&& result ok "and zooming out buys sky, not moon" "$NARROWMOON per cent rock became $WIDEMOON" \
|
||||
|| result no "and zooming out buys sky, not moon" "$NARROWMOON per cent rock became $WIDEMOON"
|
||||
# A whole scanline of moon along the bottom in both. Without it the terrain is a band with
|
||||
# nothing underneath, which is what pointing the wide view at the origin actually produces.
|
||||
[ "$NARROWFLOOR" = "320/320" ] && [ "$WIDEFLOOR" = "640/640" ] \
|
||||
&& result ok "and the ground still reaches the bottom" "a full scanline of moon in both" \
|
||||
|| result no "and the ground still reaches the bottom" "$NARROWFLOOR then $WIDEFLOOR"
|
||||
# The rows above the world's origin are drawn as sky rather than left alone, so nothing the
|
||||
# shell wrote up there is still sitting in the part of the map the wide view has moved into.
|
||||
# Read off the deeply scrolled run, which is the only one that has anything up there to leave.
|
||||
[ "$WIDESKY" = "0" ] \
|
||||
&& result ok "and the sky over the world is empty" "nothing left in the rows the view moved into" \
|
||||
|| result no "and the sky over the world is empty" "$WIDESKY pixels of moon up in the sky"
|
||||
|
||||
# ---- Which is the whole reason for the button ----
|
||||
#
|
||||
# A lander at the ceiling is OFF THE TOP of a forty column screen - that is where the orbit
|
||||
# lives, and it is why the altitude bar had to exist at all. Zoomed out it is on the picture,
|
||||
# because the wide view starts above the ceiling rather than at the world's origin. Same
|
||||
# flight, same nine hundred frames of thruster; the only difference is the button.
|
||||
python3 -c "open('$BUILD/ceilingin.pad','wb').write(b'\x00' * 20 + b'\x08' * 900 + b'\x00' * 8000)"
|
||||
python3 -c "open('$BUILD/ceilingout.pad','wb').write(b'\x00' * 20 + b'\x08' * 900 + b'\x20' * 8 + b'\x00' * 8000)"
|
||||
for view in ceilingin ceilingout; do
|
||||
timeout 60 "$EMU" --fast --cycles 17000000 --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 INSHIP OUTSHIP <<EOT
|
||||
$(python3 -c "
|
||||
def shipRow(path):
|
||||
d = open(path, 'rb').read()
|
||||
width = int(d[:40].split()[1])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
ship = bytes.fromhex('d8c048')
|
||||
rows = [i // width for i in range(len(px) // 3) if px[i * 3:i * 3 + 3] == ship]
|
||||
return min(rows) if rows else -1
|
||||
print(shipRow('$BUILD/ceilingin.ppm'), shipRow('$BUILD/ceilingout.ppm'))
|
||||
" 2>/dev/null || echo "-1 -1")
|
||||
EOT
|
||||
[ "$INSHIP" = "-1" ] && [ "$OUTSHIP" -gt 0 ] \
|
||||
&& 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"
|
||||
|
||||
# ---- 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