Two zoom levels on a button, which the device already had
Forty columns and eighty are the same map, the same 8x8 cells and the same engine; only how many of them fit differs. The map is 128 by 128 either way and the moon is exactly 128 columns of it. And the front end scales whatever it is handed by the largest whole number that fits, so 320 by 200 at four times and 640 by 400 at twice fill the same glass. So the two modes ARE two zoom levels and nothing in the video device had to change to get them: forty columns shows under a third of the moon at twice the size, eighty shows nearly two thirds. Out for the orbit, in for the landing, and B says which. What did have to change is every screen coordinate in Lander, because the middle of the screen is 160 on one and 320 on the other. They now live in one block that setView copies over from whichever of two tables matches the mode, so a gauge reads a variable and never has to know which screen it is on. Several coordinates became sixteen bit on the way, since 620 will not go in a byte. follow already read HalfScreen and showLander already writes the world position straight through, so the lander itself needed nothing but its resting column. The moon is redrawn on a swap because it is filled as many rows deep as the mode shows, and a moon drawn 25 deep on a screen showing 50 floats over nothing. The swap is edge triggered. A pad is LEVEL and not an event, so a view that swapped while B was down would swap sixty times a second - which is not a zoom, it is a strobe, and it redraws the whole moon each time. The check for that holds the button for three hundred frames and requires the lander to land where a six frame tap left it; with the edge dropped it ends seventeen pixels adrift, which is the strobe costing it frames. Four checks, each seen to fail on its own break. The README's Lander entry also still described the relief orbit that the previous commit replaced, and now describes the one that is there.
This commit is contained in:
+253
-45
@@ -48,8 +48,11 @@ start:
|
||||
; floor the system gives every program does not.
|
||||
SWI osTakeScreen
|
||||
|
||||
CALL setView ; The block every gauge below reads its screen numbers out of.
|
||||
SETD.0 Wide
|
||||
LDA.0
|
||||
OUTA 0x31 ; Forty columns to start in. B swaps to eighty and back.
|
||||
RSTA
|
||||
OUTA 0x31 ; Forty columns. A moon 320 pixels across reads better than 640.
|
||||
|
||||
; ---- And the view put back to the top of the map ----
|
||||
;
|
||||
@@ -92,6 +95,7 @@ everyFrame:
|
||||
CALL waitFrame
|
||||
CALL readPad
|
||||
CALL readControls
|
||||
CALL zoomButton
|
||||
CALL fall
|
||||
CALL move
|
||||
CALL follow
|
||||
@@ -418,7 +422,8 @@ drawNextCell:
|
||||
LDA.1
|
||||
INCA
|
||||
STA.1
|
||||
INIB 0d25
|
||||
SETD.2 MoonRows
|
||||
LDB.2
|
||||
CCF
|
||||
SUB
|
||||
BNQ drawRow
|
||||
@@ -440,10 +445,12 @@ putLander:
|
||||
OUTA 0xE9 ; Tile 201.
|
||||
INIA 0x03
|
||||
OUTA 0xE9 ; Attribute three, so it is yellow against a grey moon.
|
||||
INIA 0d156
|
||||
SETD.0 ShipX
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
OUTA 0xE9 ; X: the middle of a 320 pixel screen, less half a tile.
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; X: the middle of the screen, less half a tile. Never moves.
|
||||
OUTA 0xE9
|
||||
OUTA 0xE9 ; Y, which every frame overwrites.
|
||||
INIA 0x11
|
||||
@@ -1269,20 +1276,35 @@ driftSized2:
|
||||
SETD.1 DriftSize
|
||||
STA.1
|
||||
|
||||
; Where it starts: the middle for a rightward drift, and that much back for a leftward one.
|
||||
INIA 0d160
|
||||
SETD.0 DriftLeftward
|
||||
LDB.0
|
||||
BRB driftAt ; Nought is rightward, so the bar starts at the middle.
|
||||
SETD.0 DriftLow
|
||||
LDB.0
|
||||
CCF
|
||||
SUB
|
||||
MVQA
|
||||
|
||||
driftAt:
|
||||
; ---- Where it starts, in sixteen bits ----
|
||||
;
|
||||
; The middle for a rightward drift and that much back for a leftward one, and it is a WORD
|
||||
; now because the middle of an eighty column screen is 320 and will not go in a byte.
|
||||
SETD.0 MiddleX
|
||||
LDA.0
|
||||
SETD.1 DriftAt
|
||||
STA.1
|
||||
INCD.0
|
||||
LDA.0
|
||||
INCD.1
|
||||
STA.1
|
||||
SETD.0 DriftLeftward
|
||||
LDA.0
|
||||
BRA driftAt ; Nought is rightward, so the bar starts at the middle.
|
||||
SETD.0 DriftAt
|
||||
LDA.0
|
||||
SETD.1 DriftLow
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
SETD.1 DriftAt
|
||||
STQ.1
|
||||
INCD.0
|
||||
LDA.0
|
||||
RSTB
|
||||
SUB ; And the borrow, which is the other half of the step back.
|
||||
STQ.0
|
||||
driftAt:
|
||||
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
@@ -1298,11 +1320,14 @@ driftAt:
|
||||
SETD.0 DriftAt
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; X.
|
||||
INIA 0d188
|
||||
SETD.0 BarY
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; Y, near the bottom and clear of the ground most places.
|
||||
SETD.0 DriftSize
|
||||
LDA.0
|
||||
@@ -1585,17 +1610,24 @@ showHeightReady:
|
||||
;
|
||||
; A sprite is placed by its TOP, so a bar that grows up is one whose top moves as its height
|
||||
; changes. Both come out of the same number and the foot stays put.
|
||||
INIA 0d180
|
||||
SETD.0 HeightBar
|
||||
LDB.0
|
||||
SETD.0 HeightFoot
|
||||
LDA.0
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
SETD.1 HeightAt
|
||||
STQ.1
|
||||
INCD.0
|
||||
LDA.0
|
||||
RSTB
|
||||
SUB ; And the borrow, which is the other half of the foot.
|
||||
INCD.1
|
||||
STQ.1
|
||||
|
||||
; Nought is the off switch, and it is the SIZE that switches it: a target height of nought
|
||||
; is the natural height, which would be a tile sitting on the ground pretending to be sky.
|
||||
LDA.0 ; DP0 still names the bar, from working the top out above.
|
||||
SETD.0 HeightBar
|
||||
LDA.0
|
||||
BRA showHeightEmpty
|
||||
INIA 0x11
|
||||
BRI showHeightSized
|
||||
@@ -1631,7 +1663,8 @@ showHeightSized:
|
||||
SETD.0 HeightAt
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; Y.
|
||||
SETD.0 HeightSize
|
||||
LDA.0
|
||||
@@ -1650,6 +1683,85 @@ showHeightSized:
|
||||
OUTA 0xE9 ; And no depth, A being nought already.
|
||||
RET
|
||||
|
||||
; ---- Two zoom levels, which the device turns out to have already had ----
|
||||
;
|
||||
; Forty columns and eighty are the same map, the same 8x8 cells and the same engine; only how
|
||||
; many of them fit on the screen differs. The map is 128 by 128 either way and the moon is
|
||||
; exactly 128 columns of it, so forty shows under a third of the moon and eighty shows nearly
|
||||
; two thirds - and the front end scales whatever it is handed up to the same window, so 320 by
|
||||
; 200 at four times and 640 by 400 at twice fill the same glass.
|
||||
;
|
||||
; THAT IS A ZOOM, and nothing in the video device had to change to get it. What has to change
|
||||
; is every screen coordinate in this program, because the middle of the screen is 160 on one
|
||||
; and 320 on the other. They all live in one block.
|
||||
setView:
|
||||
SETD.0 ViewNarrow
|
||||
SETD.1 Wide
|
||||
LDA.1
|
||||
BRA setViewFrom
|
||||
SETD.0 ViewWide
|
||||
setViewFrom:
|
||||
SETD.1 View
|
||||
INIA 0d15
|
||||
SETD.2 ViewLeft
|
||||
STA.2
|
||||
setViewByte:
|
||||
LDA.0
|
||||
STA.1
|
||||
INCD.0
|
||||
INCD.1
|
||||
SETD.2 ViewLeft
|
||||
LDA.2
|
||||
DECA
|
||||
STA.2
|
||||
BNA setViewByte
|
||||
RET
|
||||
|
||||
; ---- Out for the orbit, in for the landing ----
|
||||
;
|
||||
; The moon is redrawn because it is filled as many rows deep as the mode shows, and a moon
|
||||
; drawn 25 deep on a screen showing 50 is a moon floating over nothing. The fixed sprites go
|
||||
; again because their places moved with the middle.
|
||||
toggleView:
|
||||
SETD.0 Wide
|
||||
LDA.0
|
||||
INIB 0x01
|
||||
XOR
|
||||
STQ.0
|
||||
CALL setView
|
||||
SETD.0 Wide
|
||||
LDA.0
|
||||
OUTA 0x31
|
||||
CALL drawMoon
|
||||
CALL putLander
|
||||
CALL putGauge
|
||||
CALL putOrbital
|
||||
RET
|
||||
|
||||
; ---- One press, one swap ----
|
||||
;
|
||||
; A pad is LEVEL and not an event: it says what is held NOW, sixty times a second. A view that
|
||||
; swapped whenever B was down would swap sixty times a second, which is not a zoom, it is a
|
||||
; strobe. So the swap happens on the frame the button goes down, and the frame it comes up is
|
||||
; remembered for the comparison rather than acted on.
|
||||
zoomButton:
|
||||
SETD.0 Held
|
||||
LDA.0
|
||||
INIB 0x20 ; B.
|
||||
AND
|
||||
MVQA
|
||||
SETD.1 ZoomWas
|
||||
LDB.1
|
||||
STA.1 ; Now becomes what "last frame" means next time round.
|
||||
CCF
|
||||
SUB
|
||||
BRQ zoomDone ; The same as last frame, so nothing has been pressed or let go.
|
||||
LDA.1 ; DP1 still names it, and it now holds this frame's answer.
|
||||
BRA zoomDone ; It changed to NOT held, which is the release and not the press.
|
||||
CALL toggleView
|
||||
zoomDone:
|
||||
RET
|
||||
|
||||
; ---- Where orbital speed is, marked on the drift bar ----
|
||||
;
|
||||
; The bar says how fast sideways and the physics says 64 sixteenths is the speed at which the
|
||||
@@ -1667,28 +1779,54 @@ showHeightSized:
|
||||
;
|
||||
; Written once. They never move, and a sprite table is a memory rather than a display list.
|
||||
putOrbital:
|
||||
; The leftward mark: sixty four back from the middle, and two more for its own width, so the
|
||||
; bar's leading edge meets it rather than the bar covering it up.
|
||||
SETD.0 MiddleX
|
||||
LDA.0
|
||||
INIB 0d66
|
||||
CCF
|
||||
SUB
|
||||
SETD.1 MarkAt
|
||||
STQ.1
|
||||
INCD.0
|
||||
LDA.0
|
||||
RSTB
|
||||
SUB ; And the borrow, because the middle can be 320.
|
||||
INCD.1
|
||||
STQ.1
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0xC0
|
||||
OUTA 0xE4
|
||||
INIA 0x40
|
||||
OUTA 0xE5 ; Sprite four begins sixty four bytes in.
|
||||
INIA 0d94
|
||||
CALL putMark
|
||||
|
||||
; And the rightward one, sixty four on from it.
|
||||
SETD.0 MiddleX
|
||||
LDA.0
|
||||
INIB 0d64
|
||||
CCF
|
||||
ADD
|
||||
SETD.1 MarkAt
|
||||
STQ.1
|
||||
INCD.0
|
||||
LDA.0
|
||||
RSTB
|
||||
ADD
|
||||
INCD.1
|
||||
STQ.1
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0xC0
|
||||
OUTA 0xE4
|
||||
INIA 0x50
|
||||
OUTA 0xE5 ; And sprite five, sixteen bytes after it.
|
||||
INIA 0d224
|
||||
CALL putMark
|
||||
RET
|
||||
|
||||
; One mark, at the screen column in A, straddling the drift bar so the bar meets it end on.
|
||||
; One mark, at the column in MarkAt, straddling the drift bar so the bar meets it end on.
|
||||
putMark:
|
||||
SETD.1 MarkAt
|
||||
STA.1
|
||||
INIA 0xC8
|
||||
OUTA 0xE9 ; The solid block, which is what every bar here is made of.
|
||||
INIA 0x05
|
||||
@@ -1696,14 +1834,23 @@ putMark:
|
||||
; White was the first choice and white is what TEXT is, so the
|
||||
; ceiling check - which counts white to find its warning - started
|
||||
; counting these instead and read a warning that was never up.
|
||||
LDA.1 ; DP1 still names it, from being handed it above.
|
||||
SETD.1 MarkAt
|
||||
LDA.1
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
INCD.1
|
||||
LDA.1
|
||||
OUTA 0xE9 ; X.
|
||||
INIA 0d184
|
||||
OUTA 0xE9
|
||||
RSTA
|
||||
OUTA 0xE9 ; Y, four pixels above the bar it brackets.
|
||||
SETD.0 BarY
|
||||
LDA.0
|
||||
INIB 0d4
|
||||
CCF
|
||||
SUB
|
||||
OUTQ 0xE9
|
||||
INCD.0
|
||||
LDA.0
|
||||
RSTB
|
||||
SUB
|
||||
OUTQ 0xE9 ; Y, four pixels above the bar it brackets.
|
||||
INIA 0x11
|
||||
OUTA 0xE9 ; One tile by one, however small it ends up drawn.
|
||||
RSTA
|
||||
@@ -1786,7 +1933,8 @@ sayNext:
|
||||
LDA.1
|
||||
INCA
|
||||
STA.1
|
||||
INIB 0d40
|
||||
SETD.2 RowCells
|
||||
LDB.2
|
||||
CCF
|
||||
SUB
|
||||
BNQ sayCell
|
||||
@@ -1920,7 +2068,8 @@ fallBarSized:
|
||||
STA.1
|
||||
|
||||
; Where it starts: the middle going down, and that much back going up.
|
||||
INIA 0d100
|
||||
SETD.0 MiddleY
|
||||
LDA.0
|
||||
SETD.0 DriftLeftward
|
||||
LDB.0
|
||||
BRB fallBarAt ; Nought is downward, so it starts at the middle.
|
||||
@@ -1944,10 +2093,12 @@ fallBarAt:
|
||||
SETD.0 FallColour
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
INIA 0x2C
|
||||
SETD.0 FallX
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
INIA 0x01
|
||||
OUTA 0xE9 ; X is 300, which is two bytes: the screen is wider than one.
|
||||
INCD.0
|
||||
LDA.0
|
||||
OUTA 0xE9 ; X, in two bytes, because the screen is wider than one.
|
||||
SETD.0 FallAt
|
||||
LDA.0
|
||||
OUTA 0xE9
|
||||
@@ -2139,7 +2290,7 @@ DriftHigh:
|
||||
DriftLeftward:
|
||||
0x00
|
||||
DriftAt:
|
||||
0x00
|
||||
0x00 0x00
|
||||
DriftSize:
|
||||
0x00
|
||||
DriftColour:
|
||||
@@ -2175,8 +2326,65 @@ GentleDown:
|
||||
0d12
|
||||
GentleAcross:
|
||||
0d8
|
||||
; ---- The numbers that change when the screen does ----
|
||||
;
|
||||
; Copied over from whichever table below matches the mode, so a gauge reads a variable and
|
||||
; never has to know which screen it is drawing on. The order here and in both tables is the
|
||||
; same order and has to stay that way: setView copies the block straight across.
|
||||
View:
|
||||
HalfScreen:
|
||||
0xA0 0x00 ; 160 pixels, which is half of a forty column screen.
|
||||
0xA0 0x00
|
||||
ShipX:
|
||||
0x9C 0x00
|
||||
MiddleX:
|
||||
0xA0 0x00
|
||||
BarY:
|
||||
0xBC 0x00
|
||||
FallX:
|
||||
0x2C 0x01
|
||||
MiddleY:
|
||||
0d100
|
||||
HeightFoot:
|
||||
0xB4 0x00
|
||||
RowCells:
|
||||
0d40
|
||||
MoonRows:
|
||||
0d25
|
||||
ViewLeft:
|
||||
0x00 ; How much of the block is still to copy.
|
||||
|
||||
; Forty columns: 320 by 200, and the moon 25 rows deep because that is all there is to see.
|
||||
ViewNarrow:
|
||||
0xA0 0x00 ; Half a screen, which is where the lander is held.
|
||||
0x9C 0x00 ; And the lander itself, half a tile back from it.
|
||||
0xA0 0x00 ; The middle, where both bars start.
|
||||
0xBC 0x00 ; The drift bar's row, twelve pixels off the bottom.
|
||||
0x2C 0x01 ; The fall bar's column, twenty pixels in from the right.
|
||||
0d100 ; Half the height, which is where the fall bar starts.
|
||||
0xB4 0x00 ; The height bar's foot.
|
||||
0d40 ; Cells to a window row.
|
||||
0d25 ; Rows of moon to draw.
|
||||
|
||||
; Eighty columns: 640 by 400, the same cells at half the size, so twice as much moon either
|
||||
; way. Every screen number doubles except the ones measured from an edge, which are the edge
|
||||
; less the same margin - a panel should sit the same distance in whichever screen it is on.
|
||||
ViewWide:
|
||||
0x40 0x01 ; 320.
|
||||
0x3C 0x01 ; 316.
|
||||
0x40 0x01 ; 320.
|
||||
0x84 0x01 ; 388, which is twelve off the bottom of four hundred.
|
||||
0x6C 0x02 ; 620, twenty in from the right of six hundred and forty.
|
||||
0d200
|
||||
0x7C 0x01 ; 380.
|
||||
0d80
|
||||
0d50
|
||||
|
||||
; Which of the two is up. Nought is forty columns, which is what the program starts in.
|
||||
Wide:
|
||||
0x00
|
||||
; What B was doing last frame, because a pad says what is held and not what was pressed.
|
||||
ZoomWas:
|
||||
0x00
|
||||
|
||||
PixelLow:
|
||||
0x00
|
||||
@@ -2252,11 +2460,11 @@ HeightHigh:
|
||||
HeightBar:
|
||||
0x00
|
||||
HeightAt:
|
||||
0x00
|
||||
0x00 0x00
|
||||
HeightSize:
|
||||
0x00
|
||||
MarkAt:
|
||||
0x00
|
||||
0x00 0x00
|
||||
Outward:
|
||||
0x00
|
||||
Lift:
|
||||
|
||||
Reference in New Issue
Block a user