A station in orbit, going round and not yet dockable
S1 of the station: it exists, it orbits, it wraps, it is drawn. Docking is deliberately not here - the point of stopping at this rung is to fly up and find out whether matching a four pixel a frame target feels good before any rules are written about what happens when you reach it. IT NEEDS NO PHYSICS OF ITS OWN. A body at 64 sixteenths is exactly what a circular orbit is under the rules already here: the pull and the swing cancel at that speed at ANY height, because gravity never falls off and the moon is a cylinder that does not rotate. So the station is a position, a constant, and the same fourteen bit wrap the lander uses. That also means there is no prograde or retrograde to choose - nothing privileges a direction, which is what makes a second station going the other way a thing that can exist later. Four rows above the world's origin: off the top of a forty column screen and comfortably inside a wide one, so it is somewhere to go that the zoom is needed to see. It starts half a moon away and a lap is 256 frames, a little over four seconds, so it has to be found but will not stay lost. Its column is the middle of the screen plus how far round it is from the lander, wrapped to fourteen bits - which measures the long way round whenever it is behind, so anything past the half way point becomes a negative offset instead. Off the edge needs no test at all: a sprite's X is signed and sixteen bits, so a station three hundred pixels to the left is asked for at minus a hundred and forty and the device declines. Blue, and that is not taste. White is counted to find the ceiling warning, cyan to find the landing pads, magenta is the instruments and yellow is the lander. Blue is the one ink no check measures, and picking a measured one has broken a test twice already. toPixelsSigned is factored out of showLander, since the station wants the same sign-extended conversion. Four checks, each seen to fail on its own break. Measured going round at 244 pixels in sixty frames, off the far side of the moon, and back on the other edge.
This commit is contained in:
+220
-12
@@ -100,9 +100,11 @@ everyFrame:
|
||||
CALL zoomButton
|
||||
CALL fall
|
||||
CALL move
|
||||
CALL moveStation
|
||||
CALL follow
|
||||
CALL touchdown
|
||||
CALL showLander
|
||||
CALL showStation
|
||||
CALL showDrift
|
||||
CALL showFall
|
||||
CALL showFuel
|
||||
@@ -158,6 +160,28 @@ putTiles:
|
||||
OUTA 0xE7
|
||||
INIA 0x01
|
||||
OUTA 0xE8 ; Blit.
|
||||
|
||||
OUTA 0xE0 ; Bank one again, A still holding the one the blit above wanted.
|
||||
SETD.1 StationArtAt
|
||||
SETD.0 StationArt
|
||||
STD.0.1
|
||||
LDA.1
|
||||
OUTA 0xE1
|
||||
INCD.1
|
||||
LDA.1
|
||||
OUTA 0xE2
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0x32
|
||||
OUTA 0xE4
|
||||
INIA 0x80
|
||||
OUTA 0xE5 ; Tile 202, one tile on again.
|
||||
RSTA
|
||||
OUTA 0xE6
|
||||
INIA 0x40
|
||||
OUTA 0xE7
|
||||
INIA 0x01
|
||||
OUTA 0xE8 ; Blit.
|
||||
RET
|
||||
|
||||
; ---- A moon, one column at a time ----
|
||||
@@ -1183,27 +1207,164 @@ follow:
|
||||
RET
|
||||
|
||||
; ---- The lander, put where it now is ----
|
||||
showLander:
|
||||
SETD.0 DownLow
|
||||
CALL toPixels
|
||||
; ---- Round it goes, one orbital speed a frame ----
|
||||
moveStation:
|
||||
SETD.0 StationLow
|
||||
SETD.1 StationSpeed
|
||||
CALL addWord
|
||||
SETD.0 StationHigh
|
||||
LDA.0
|
||||
INIB 0x3F
|
||||
AND
|
||||
STQ.0 ; The same wrap the lander has: 2^14 sixteenths round.
|
||||
RET
|
||||
|
||||
; ---- Signed, which it did not have to be while the view never moved ----
|
||||
;
|
||||
; toPixels shifts a sixteen bit position down four and masks what is left to twelve bits, so
|
||||
; a lander above the world's origin comes back as a large POSITIVE number rather than a small
|
||||
; negative one. That was harmless while the top of the screen was the origin: such a lander
|
||||
; was off the picture either way. Now that the wide view starts twenty four rows higher it is
|
||||
; on the picture, and it has to be on the right part of it.
|
||||
; ---- Where that puts it on the screen ----
|
||||
;
|
||||
; The lander is always at the middle, so the station's column is the middle plus HOW FAR ROUND
|
||||
; IT IS FROM THE LANDER. That difference is taken in the moon's own arithmetic and wrapped to
|
||||
; fourteen bits, which measures it the long way round whenever the station is behind: over
|
||||
; half a moon ahead IS under half a moon behind, so anything past the half way point is turned
|
||||
; into a negative offset instead.
|
||||
;
|
||||
; Off the edge needs no test. A sprite's X is signed and sixteen bits, so a station three
|
||||
; hundred pixels to the left is asked for at minus a hundred and forty and the device declines
|
||||
; to draw it, which is a comparison this does not have to make.
|
||||
showStation:
|
||||
SETD.0 StationLow
|
||||
LDA.0
|
||||
SETD.1 AcrossLow
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
SETD.1 GapLow
|
||||
STQ.1
|
||||
SETD.0 StationHigh
|
||||
LDA.0
|
||||
SETD.1 AcrossHigh
|
||||
LDB.1
|
||||
SUB ; And the borrow the half below left.
|
||||
MVQA
|
||||
INIB 0x3F
|
||||
AND
|
||||
SETD.1 GapHigh
|
||||
STQ.1
|
||||
|
||||
SETD.0 GapLow
|
||||
CALL toPixels ; Nought to 1023 pixels, which is the whole moon.
|
||||
SETD.0 PixelHigh
|
||||
LDA.0
|
||||
INIB 0x02
|
||||
AND
|
||||
BRQ stationAhead ; Under 512, so it is ahead and the offset stands.
|
||||
LDA.0
|
||||
INIB 0d4
|
||||
CCF
|
||||
SUB
|
||||
STQ.0 ; Less a whole moon, which makes it a distance backwards.
|
||||
stationAhead:
|
||||
|
||||
SETD.0 PixelLow
|
||||
LDA.0
|
||||
SETD.1 HalfScreen
|
||||
LDB.1
|
||||
CCF
|
||||
ADD
|
||||
SETD.1 StationAt
|
||||
STQ.1
|
||||
SETD.0 PixelHigh
|
||||
LDA.0
|
||||
SETD.1 HalfScreen
|
||||
INCD.1
|
||||
LDB.1
|
||||
ADD
|
||||
SETD.1 StationAt
|
||||
INCD.1
|
||||
STQ.1
|
||||
|
||||
; And its row, which moves with the view exactly as the lander's does.
|
||||
SETD.0 StationDownLow
|
||||
CALL toPixelsSigned
|
||||
SETD.0 PixelLow
|
||||
LDA.0
|
||||
SETD.1 ShipYAdd
|
||||
LDB.1
|
||||
CCF
|
||||
ADD
|
||||
SETD.1 StationTop
|
||||
STQ.1
|
||||
SETD.0 PixelHigh
|
||||
LDA.0
|
||||
SETD.1 ShipYAdd
|
||||
INCD.1
|
||||
LDB.1
|
||||
ADD
|
||||
SETD.1 StationTop
|
||||
INCD.1
|
||||
STQ.1
|
||||
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0xC0
|
||||
OUTA 0xE4
|
||||
INIA 0x60
|
||||
OUTA 0xE5 ; Sprite six begins ninety six bytes in.
|
||||
INIA 0xCA
|
||||
OUTA 0xE9 ; Tile 202.
|
||||
INIA 0x04
|
||||
OUTA 0xE9 ; ---- Attribute four, blue ----
|
||||
;
|
||||
; Not taste. White is what the ceiling warning is counted in, cyan
|
||||
; is what a landing pad is counted in, magenta is the instruments
|
||||
; and yellow is the lander. Blue is the one ink no check measures,
|
||||
; and picking a measured one has broken a test twice already.
|
||||
SETD.0 StationAt
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; X.
|
||||
SETD.0 StationTop
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; Y.
|
||||
INIA 0x11
|
||||
OUTA 0xE9 ; One tile by one.
|
||||
RSTA
|
||||
OUTA 0xE9 ; No flags.
|
||||
OUTA 0xE9
|
||||
OUTA 0xE9
|
||||
OUTA 0xE9
|
||||
OUTA 0xE9 ; No target size, which HERE means its natural one.
|
||||
OUTA 0xE9 ; And no depth.
|
||||
RET
|
||||
|
||||
; ---- A world position in pixels, with its sign kept ----
|
||||
;
|
||||
; toPixels shifts a sixteen bit position down four and masks what is left to twelve bits, so a
|
||||
; position above the world's origin comes back as a large POSITIVE number rather than a small
|
||||
; negative one. That was harmless while the top of the screen WAS the origin: anything up
|
||||
; there was off the picture either way. Now that the wide view starts twenty four rows higher
|
||||
; it is on the picture, and it has to be on the right part of it.
|
||||
toPixelsSigned:
|
||||
CALL toPixels
|
||||
SETD.0 PixelHigh
|
||||
LDA.0
|
||||
INIB 0x08
|
||||
AND
|
||||
BRQ showLanderDown
|
||||
BRQ toPixelsSignedDone
|
||||
LDA.0
|
||||
INIB 0xF0
|
||||
OR
|
||||
STQ.0 ; The twelfth bit was the sign, so the top nibble is too.
|
||||
showLanderDown:
|
||||
toPixelsSignedDone:
|
||||
RET
|
||||
|
||||
showLander:
|
||||
SETD.0 DownLow
|
||||
CALL toPixelsSigned
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0xC0
|
||||
@@ -2592,6 +2753,53 @@ EmptyText:
|
||||
CrashedText:
|
||||
"Crashed."
|
||||
|
||||
; ---- The station, which is a body and not a special case ----
|
||||
;
|
||||
; A circular orbit is exactly what a thing at orbital speed DOES under the rules already here:
|
||||
; the pull and the swing cancel at 64 sixteenths, at any height, because gravity never falls
|
||||
; off and the moon wraps. So the station needs no physics of its own - a position, a constant,
|
||||
; and the same wrap the lander uses.
|
||||
;
|
||||
; Four rows above the world's origin, which is off the top of a forty column screen and
|
||||
; comfortably inside a wide one. That is deliberate: it makes the station a reason to use the
|
||||
; zoom rather than something that can be flown to without it.
|
||||
;
|
||||
; It starts half a moon away, so it has to be found. At four pixels a frame a lap is 256
|
||||
; frames, a little over four seconds, so it will not stay lost for long.
|
||||
StationLow:
|
||||
0xA0
|
||||
StationHigh:
|
||||
0x34
|
||||
StationDownLow:
|
||||
0x00
|
||||
StationDownHigh:
|
||||
0xFE ; Minus 512 sixteenths, which is four rows up.
|
||||
StationSpeed:
|
||||
0x40 0x00 ; Orbital speed, and the whole of its behaviour.
|
||||
|
||||
; How far round the moon the station is from the lander, and where that puts it on the screen.
|
||||
GapLow:
|
||||
0x00
|
||||
GapHigh:
|
||||
0x00
|
||||
StationAt:
|
||||
0x00 0x00
|
||||
StationTop:
|
||||
0x00 0x00
|
||||
|
||||
StationArt:
|
||||
0x00 0x00 0x01 0x01 0x01 0x01 0x00 0x00
|
||||
0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x00
|
||||
0x01 0x01 0x00 0x01 0x01 0x00 0x01 0x01
|
||||
0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
|
||||
0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
|
||||
0x01 0x01 0x00 0x01 0x01 0x00 0x01 0x01
|
||||
0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x00
|
||||
0x00 0x00 0x01 0x01 0x01 0x01 0x00 0x00
|
||||
|
||||
StationArtAt:
|
||||
#Reserve 0d2
|
||||
|
||||
LanderArt:
|
||||
0x00 0x00 0x01 0x01 0x01 0x01 0x00 0x00
|
||||
0x00 0x01 0x01 0x01 0x01 0x01 0x01 0x00
|
||||
|
||||
@@ -727,7 +727,7 @@ from every assembly file in it. Several are old programs written for the bare ma
|
||||
| Grid | The first program to use the screen as a screen. Redefines a tile above the font, fills all 128 map rows, and scrolls it diagonally a pixel at a time. |
|
||||
| Sprite | Moves a ball across the shell's own text, writing not one byte of the map to do it. It leaves the sprite in the table on the way out, because clearing them is the system's job - see below. |
|
||||
| Pad | Says what the controllers are doing, printing a line whenever one changes. It tells apart the three things that look identical from inside a game that is not responding: a pad nobody noticed, a pad mapped to nothing, and a mapping that is wrong. |
|
||||
| Lander | Lunar Porter, rung one: a lander over a moon that wraps. Flown with a controller if there is one - a held thruster burns every tick it is held for - and with the arrow keys if there is not, where one press is one burn and that is the most the console can say. A bar at the bottom is the sideways drift, drawn as a sprite stretched to the speed - a moon has no air, so a drift never stops by itself and stopping one means cancelling it exactly, which is hard to do blind. It lands or crashes on arrival, and what decides is the speed at the moment it touches: gentler than three quarters of a pixel a frame downwards and half of one sideways, or it is a lander on its side. A fuel gauge sits in the window layer, where the moon turning underneath cannot scroll it away, and every thruster costs a unit of fuel every tick it fires. An empty tank is not an ending: it is a lander still flying that can no longer do anything about where. Four landing pads are carved into the moon after it is generated, levelled to whatever height their first column happened to have, and marked in cyan by an attribute rather than a tile of their own. The lander starts above one, because that is where a porter's day begins. Each pad is a base, told apart by the colour it is drawn in, and landing at one either loads cargo for the base across the moon or delivers what is aboard and pays eighty units of fuel. A landing is not an ending: the lander rests where it is until the throttle opens again, and A or Start says "read it" as readily as a key does. What a base says goes in the window rather than out of the console: the console draws into the map, so a message printed while flying is one the lander then flies over, and printing scrolls the whole world up a row. Opening the throttle wipes the line. Two bars read the speeds and are green while a landing would survive and red while it would not, so "can I put down" is a glance rather than a sum. A third runs up the left edge and is how much sky is under the lander, half a pixel of bar to a pixel of it; it reads nought the moment the lander is down, and it exists because the orbit takes the lander off the top of the screen and a panel that only works while the ground is in sight is no use above it. And gravity here is the pull MINUS the swing outwards, which is what makes an orbit rather than a one way trip: under four pixels a frame sideways the pull wins and the lander falls, over it the swing wins and the lander climbs, and at it they cancel and it circles. Falling buys sideways speed and climbing spends it - at a rate set by the product of the two, so the trade stops by itself as the sideways speed runs out - and that is the cycle: a fall carries the lander past orbital speed and becomes a climb, the climb pays it back and becomes a fall, periapse and apoapse, round and round. Orbital speed is marked on the drift bar, sixty four pixels either side of the middle, because a number nothing points at is folklore. Gravity never falls off and the moon wraps, so a circular orbit is the same length at any height and one orbital speed serves everywhere. There is a ceiling sixty four pixels above the screen, which pins rather than ends: leaving upward is recoverable, so the lander is held there and told so, and one sideways is spent every tick it tries to climb - without that the pin wiped the climb, the trade saw neither fall nor climb, and the speed pushing it up never changed. What kills you out here is running dry a long way from the ground. B, or z on the keyboard, swaps the screen between forty columns and eighty, which is the same map, the same cells and the same engine at half the size: nearly two thirds of the moon at once for the orbit, and twice as big for the landing. The twenty extra rows that buys go to the SKY and not to the moon - the wide view starts twenty four rows above the world's origin rather than at it, so the ground sits near the bottom and the whole flyable band is on the screen. Drawn down from the origin instead it was 71 per cent rock, which is a zoom that shows you more of the thing you cannot fly through. 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 in the picture. |
|
||||
| Lander | Lunar Porter, rung one: a lander over a moon that wraps. Flown with a controller if there is one - a held thruster burns every tick it is held for - and with the arrow keys if there is not, where one press is one burn and that is the most the console can say. A bar at the bottom is the sideways drift, drawn as a sprite stretched to the speed - a moon has no air, so a drift never stops by itself and stopping one means cancelling it exactly, which is hard to do blind. It lands or crashes on arrival, and what decides is the speed at the moment it touches: gentler than three quarters of a pixel a frame downwards and half of one sideways, or it is a lander on its side. A fuel gauge sits in the window layer, where the moon turning underneath cannot scroll it away, and every thruster costs a unit of fuel every tick it fires. An empty tank is not an ending: it is a lander still flying that can no longer do anything about where. Four landing pads are carved into the moon after it is generated, levelled to whatever height their first column happened to have, and marked in cyan by an attribute rather than a tile of their own. The lander starts above one, because that is where a porter's day begins. Each pad is a base, told apart by the colour it is drawn in, and landing at one either loads cargo for the base across the moon or delivers what is aboard and pays eighty units of fuel. A landing is not an ending: the lander rests where it is until the throttle opens again, and A or Start says "read it" as readily as a key does. What a base says goes in the window rather than out of the console: the console draws into the map, so a message printed while flying is one the lander then flies over, and printing scrolls the whole world up a row. Opening the throttle wipes the line. Two bars read the speeds and are green while a landing would survive and red while it would not, so "can I put down" is a glance rather than a sum. A third runs up the left edge and is how much sky is under the lander, half a pixel of bar to a pixel of it; it reads nought the moment the lander is down, and it exists because the orbit takes the lander off the top of the screen and a panel that only works while the ground is in sight is no use above it. And gravity here is the pull MINUS the swing outwards, which is what makes an orbit rather than a one way trip: under four pixels a frame sideways the pull wins and the lander falls, over it the swing wins and the lander climbs, and at it they cancel and it circles. Falling buys sideways speed and climbing spends it - at a rate set by the product of the two, so the trade stops by itself as the sideways speed runs out - and that is the cycle: a fall carries the lander past orbital speed and becomes a climb, the climb pays it back and becomes a fall, periapse and apoapse, round and round. Orbital speed is marked on the drift bar, sixty four pixels either side of the middle, because a number nothing points at is folklore. Gravity never falls off and the moon wraps, so a circular orbit is the same length at any height and one orbital speed serves everywhere. There is a ceiling sixty four pixels above the screen, which pins rather than ends: leaving upward is recoverable, so the lander is held there and told so, and one sideways is spent every tick it tries to climb - without that the pin wiped the climb, the trade saw neither fall nor climb, and the speed pushing it up never changed. What kills you out here is running dry a long way from the ground. B, or z on the keyboard, swaps the screen between forty columns and eighty, which is the same map, the same cells and the same engine at half the size: nearly two thirds of the moon at once for the orbit, and twice as big for the landing. The twenty extra rows that buys go to the SKY and not to the moon - the wide view starts twenty four rows above the world's origin rather than at it, so the ground sits near the bottom and the whole flyable band is on the screen. Drawn down from the origin instead it was 71 per cent rock, which is a zoom that shows you more of the thing you cannot fly through. 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 in the picture. And there is a station up there, four rows above the world's origin, going round at orbital speed - which needs no physics of its own, because a body at 64 sixteenths is exactly what a circular orbit IS under these rules, at any height, since gravity never falls off and the moon wraps. It is off the top of a forty column screen too, so it is somewhere to go that the zoom is needed to see. It cannot be docked with yet: it goes round, and that is all. |
|
||||
| Depth | Four pillars at four distances and a ball walking past them, behind the near ones and in front of the far ones. The ball is sprite nought and every pillar is numbered after it, so table order puts it in front of all four - what actually decides is the depth buffer, asked a column at a time. |
|
||||
| Flip | Draws a whole screen into the bank that is not being shown, waits, and then shows it in one byte out of one port. It writes nothing else at all - not a tile, not a colour - so it does not ask for the screen to be saved, and the line it printed is still there when it comes back. It deliberately does not put the displayed screen back either, because that is the system's to restore: a program that faulted while flipped could not have. |
|
||||
| Edit | A line editor. |
|
||||
|
||||
@@ -25,7 +25,7 @@ Mode.sbx 48
|
||||
Flip.sbx 173
|
||||
Sprite.sbx 442
|
||||
Depth.sbx 672
|
||||
Lander.sbx 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
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 5365
|
||||
Lander.sbx 5751
|
||||
Pad.sbx 264
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
|
||||
@@ -2212,6 +2212,70 @@ 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 orbiting station ----
|
||||
#
|
||||
# A body at orbital speed, which under the rules already here is all a circular orbit IS: the
|
||||
# pull and the swing cancel at 64 sixteenths at any height, because gravity never falls off
|
||||
# and the moon wraps. So the station has no physics of its own - a position, a constant, and
|
||||
# the same fourteen bit wrap the lander uses.
|
||||
#
|
||||
# Four rows above the world's origin, which puts it OFF THE TOP of a forty column screen and
|
||||
# inside a wide one. That is the point of it: somewhere to go that the zoom is needed to see.
|
||||
python3 -c "open('$BUILD/hovernarrow.pad','wb').write(b'\x08' * 3000 + b'\x00' * 20000)"
|
||||
python3 -c "
|
||||
pad = bytearray(b'\x08' * 3000)
|
||||
pad[100:108] = b'\x28' * 8 # Up and B together, so the climb is not interrupted.
|
||||
open('$BUILD/hoverwide.pad','wb').write(bytes(pad) + b'\x00' * 20000)"
|
||||
for when in 2000000 3000000 5000000 7000000; do
|
||||
timeout 60 "$EMU" --fast --cycles $when --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/hoverwide.pad" --screen "$BUILD/station$when.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/station.out" 2>&1 || true
|
||||
done
|
||||
timeout 60 "$EMU" --fast --cycles 3000000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/hovernarrow.pad" --screen "$BUILD/stationnarrow.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/stationnarrow.out" 2>&1 || true
|
||||
read -r ONNARROW SEEN X2 X3 X5 X7 <<EOT
|
||||
$(python3 -c "
|
||||
def station(path, band):
|
||||
# Blue, and ABOVE THE TERRAIN, because one of the four landing pads is blue too and it is
|
||||
# always somewhere on the picture. Nothing else is up in that band.
|
||||
d = open(path, 'rb').read()
|
||||
width = int(d[:40].split()[1])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
blue = bytes.fromhex('5880e0')
|
||||
at = [(i % width, i // width) for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == blue and i // width < band]
|
||||
return len(at), (min(x for x, y in at) if at else -1)
|
||||
narrow = station('$BUILD/stationnarrow.ppm', 70)
|
||||
seen, x3 = station('$BUILD/station3000000.ppm', 200)
|
||||
print(narrow[0], seen,
|
||||
station('$BUILD/station2000000.ppm', 200)[1], x3,
|
||||
station('$BUILD/station5000000.ppm', 200)[1],
|
||||
station('$BUILD/station7000000.ppm', 200)[1])
|
||||
" 2>/dev/null || echo "0 0 -1 -1 -1 -1")
|
||||
EOT
|
||||
# Forty pixels is the whole of the art, so none of it is clipped and it is the tile meant.
|
||||
[ "$SEEN" = "40" ] \
|
||||
&& result ok "a station is up there, zoomed out" "all forty pixels of it" \
|
||||
|| result no "a station is up there, zoomed out" "$SEEN pixels of station"
|
||||
[ "$ONNARROW" = "0" ] \
|
||||
&& result ok "and off the top of a forty column screen" "which is what the zoom is for" \
|
||||
|| result no "and off the top of a forty column screen" "$ONNARROW pixels of it in the narrow view"
|
||||
# Sixty frames apart, at four pixels a frame, is about 240 - and it has to be MOVING RIGHT,
|
||||
# because a station drawn from a position nothing advances would sit still and still pass a
|
||||
# check that only asked whether it was there.
|
||||
MOVED=$(( X3 - X2 ))
|
||||
[ "$MOVED" -gt 200 ] && [ "$MOVED" -lt 280 ] \
|
||||
&& result ok "and it goes round at orbital speed" "$MOVED pixels in sixty frames" \
|
||||
|| result no "and it goes round at orbital speed" "$X2 then $X3, which is $MOVED"
|
||||
# Off the far side of the moon and back on the other edge. The screen shows 640 of the moon's
|
||||
# 1024 pixels, so there is a stretch where it is genuinely not on the picture at all.
|
||||
[ "$X5" = "-1" ] && [ "$X7" -gt 0 ] \
|
||||
&& result ok "and round the back of the moon and out again" "gone, then back at $X7" \
|
||||
|| result no "and round the back of the moon and out again" "$X5 at five million, $X7 at seven"
|
||||
|
||||
# ---- 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