A quarter-tank warning that says it once, and a gauge that keeps saying it
Two halves of the same number. The warning is the moment it happened and the colour is how things stand: it fires on the way down through a quarter of a tank and then holds its peace, and the gauge stays red until a base fills the lander up, which also allows the warning again. Once, because a lander is at its most careful in the last few seconds before it touches, and something repeating in its ear through that is not a warning, it is a distraction. Checked where the fuel actually moves rather than once a frame - the tank only changes in takeFuel and payFuel, so there is nowhere else it can cross a threshold. Channel two, with the crash on three. Separate channels rather than one reused, because a crash while the warning is still sounding should not cut it off, and on a machine with four voices there is no reason to be clever. Half and a tenth are the obvious next thresholds and are deliberately not here: one is enough to find out whether being told at all is welcome. ---- And the crash sound is the one that was designed for it ---- Crash.json, which carries voice_gate itself, so the program's own trigger write is gone - it would have masked a deliberate choice rather than backing one up. The note moved from 24 to 60 by ear, and the comment saying it was low went with it. ---- A check that could not tell a beep from a nag ---- Counting bursts of sound cannot: without the latch the warning fires every tick the tank drops, far faster than the sound decays, so the beeps run into each other and a burst counter sees one long burst either way. It measures the LENGTH now - 26,944 samples against 490,348 - which is the difference between six tenths of a second and ten seconds of it.
This commit is contained in:
@@ -80,7 +80,8 @@ start:
|
|||||||
CALL putLander
|
CALL putLander
|
||||||
CALL putGauge
|
CALL putGauge
|
||||||
CALL putOrbital
|
CALL putOrbital
|
||||||
CALL putBoom ; The instrument, once, the way the tiles are.
|
CALL putBoom ; The instruments, once, the way the tiles are.
|
||||||
|
CALL putAlarm
|
||||||
|
|
||||||
INIA 0x01
|
INIA 0x01
|
||||||
OUTA 0x02 ; Key mode.
|
OUTA 0x02 ; Key mode.
|
||||||
@@ -602,6 +603,25 @@ putGauge:
|
|||||||
; Redrawn whole every frame. Thirty five cells is seventy bytes out of one port with the
|
; Redrawn whole every frame. Thirty five cells is seventy bytes out of one port with the
|
||||||
; address named once, which is cheaper than working out which of them changed.
|
; address named once, which is cheaper than working out which of them changed.
|
||||||
showFuel:
|
showFuel:
|
||||||
|
; ---- Green above a quarter, red below it ----
|
||||||
|
;
|
||||||
|
; The same number the alarm goes off at, so the sound and the picture agree. The sound is
|
||||||
|
; said once and this stays said, which is the division of labour: one of them is the moment
|
||||||
|
; it happened and the other is how things stand.
|
||||||
|
SETD.1 Fuel
|
||||||
|
LDA.1
|
||||||
|
INIB 0d64
|
||||||
|
CCF
|
||||||
|
SUB
|
||||||
|
BNC showFuelGreen
|
||||||
|
INIA 0x01
|
||||||
|
BRI showFuelColoured
|
||||||
|
showFuelGreen:
|
||||||
|
INIA 0x02
|
||||||
|
showFuelColoured:
|
||||||
|
SETD.1 GaugeColour
|
||||||
|
STA.1
|
||||||
|
|
||||||
RSTA
|
RSTA
|
||||||
SETD.1 Fuel
|
SETD.1 Fuel
|
||||||
LDB.1
|
LDB.1
|
||||||
@@ -629,8 +649,9 @@ gaugeCell:
|
|||||||
STA.1
|
STA.1
|
||||||
INIA 0xC8
|
INIA 0xC8
|
||||||
OUTA 0xE9 ; The solid block, which is the ground's tile.
|
OUTA 0xE9 ; The solid block, which is the ground's tile.
|
||||||
INIA 0x02
|
SETD.1 GaugeColour
|
||||||
OUTA 0xE9 ; Scheme two, so the bar is not the colour of the moon.
|
LDA.1
|
||||||
|
OUTA 0xE9 ; Green, or red once a quarter is all that is left.
|
||||||
BRI gaugeNext
|
BRI gaugeNext
|
||||||
gaugeEmpty:
|
gaugeEmpty:
|
||||||
OUTA 0xE9
|
OUTA 0xE9
|
||||||
@@ -1140,6 +1161,7 @@ takeFuel:
|
|||||||
BRA takeFuelNone
|
BRA takeFuelNone
|
||||||
DECA
|
DECA
|
||||||
STA.1
|
STA.1
|
||||||
|
CALL watchFuel ; Checked where the tank actually moves, not once a frame.
|
||||||
INIA 0x01
|
INIA 0x01
|
||||||
RSTB
|
RSTB
|
||||||
CCF
|
CCF
|
||||||
@@ -2682,20 +2704,6 @@ putBoom:
|
|||||||
OUTA 0x41 ; Channel three. Every parameter write below lands on it.
|
OUTA 0x41 ; Channel three. Every parameter write below lands on it.
|
||||||
SETD.0 BoomPatch
|
SETD.0 BoomPatch
|
||||||
CALL playPatch
|
CALL playPatch
|
||||||
|
|
||||||
; ---- Struck, not held ----
|
|
||||||
;
|
|
||||||
; A gated voice lasts as long as something keeps hold of it, and the gate coming up is what
|
|
||||||
; starts its release - which is what a keyboard is. A crash is not a keyboard. It is struck
|
|
||||||
; once and then plays its own length, and nothing should have to remember to end it.
|
|
||||||
;
|
|
||||||
; Said here rather than left to the patch because it is the PROGRAM that knows this is a
|
|
||||||
; one-shot: the patch decides what the bang sounds like, and this decides that it is a bang.
|
|
||||||
; A patch designed in soundThing carries a gate of its own, and this overrides it on purpose.
|
|
||||||
INIA 0x51
|
|
||||||
OUTA 0x42
|
|
||||||
INIA 0x01 ; Triggered.
|
|
||||||
OUTA 0x43
|
|
||||||
RET
|
RET
|
||||||
|
|
||||||
; ---- A whole patch, out of a table ----
|
; ---- A whole patch, out of a table ----
|
||||||
@@ -2725,10 +2733,56 @@ playPatchOne:
|
|||||||
boom:
|
boom:
|
||||||
INIA 0x03
|
INIA 0x03
|
||||||
OUTA 0x41
|
OUTA 0x41
|
||||||
INIA 0d24 ; Low: the filter is doing the work and this is only the body.
|
INIA 0d60 ; Middle C. The noise is not really pitched, but the filter is
|
||||||
|
; tuned off the note and this is where it was found by ear.
|
||||||
OUTA 0x44 ; Writing the note is what starts it.
|
OUTA 0x44 ; Writing the note is what starts it.
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
; ---- A quarter of a tank, said once ----
|
||||||
|
;
|
||||||
|
; ONCE, and that is the whole design of it. A lander is at its most careful in the last few
|
||||||
|
; seconds before it touches, and something repeating in its ear through that is not a warning,
|
||||||
|
; it is a distraction - so this fires on the way DOWN through a quarter and then holds its
|
||||||
|
; peace. Filling up at a base allows it again.
|
||||||
|
;
|
||||||
|
; A quarter is 64 of 255. Half and a tenth are the obvious next two and are not here yet: one
|
||||||
|
; threshold is enough to find out whether being told at all is welcome.
|
||||||
|
watchFuel:
|
||||||
|
SETD.0 AlarmSaid
|
||||||
|
LDA.0
|
||||||
|
BNA watchFuelDone ; Already said. Saying it again is what this exists to avoid.
|
||||||
|
SETD.0 Fuel
|
||||||
|
LDA.0
|
||||||
|
INIB 0d64
|
||||||
|
CCF
|
||||||
|
SUB
|
||||||
|
BNC watchFuelDone ; No borrow: a quarter or more, so there is nothing to say.
|
||||||
|
INIA 0x01
|
||||||
|
SETD.0 AlarmSaid
|
||||||
|
STA.0
|
||||||
|
CALL alarm
|
||||||
|
watchFuelDone:
|
||||||
|
RET
|
||||||
|
|
||||||
|
; ---- The alarm, on channel two ----
|
||||||
|
;
|
||||||
|
; Effects count down from the top: the bang has three and this has two. They are separate
|
||||||
|
; channels rather than one reused, because a crash while the warning is still sounding should
|
||||||
|
; not cut it off - and on a machine with four voices there is no reason to be clever about it.
|
||||||
|
putAlarm:
|
||||||
|
INIA 0x02
|
||||||
|
OUTA 0x41
|
||||||
|
SETD.0 AlarmPatch
|
||||||
|
CALL playPatch
|
||||||
|
RET
|
||||||
|
|
||||||
|
alarm:
|
||||||
|
INIA 0x02
|
||||||
|
OUTA 0x41
|
||||||
|
INIA 0d72 ; An octave over middle C, which is where a warning lives.
|
||||||
|
OUTA 0x44
|
||||||
|
RET
|
||||||
|
|
||||||
; ---- A key, or a button ----
|
; ---- A key, or a button ----
|
||||||
;
|
;
|
||||||
; Somebody flying on a controller should not have to reach for the keyboard to say "yes, I
|
; Somebody flying on a controller should not have to reach for the keyboard to say "yes, I
|
||||||
@@ -3309,6 +3363,11 @@ arriveNowhere:
|
|||||||
; worth of adding is what says it went past, which is the same flag a sixteen bit sum uses to
|
; worth of adding is what says it went past, which is the same flag a sixteen bit sum uses to
|
||||||
; run one half into the other.
|
; run one half into the other.
|
||||||
payFuel:
|
payFuel:
|
||||||
|
; Filled up, so the warning is allowed to come again. Eighty units always clears a quarter
|
||||||
|
; tank, so this needs no test of its own.
|
||||||
|
RSTA
|
||||||
|
SETD.0 AlarmSaid
|
||||||
|
STA.0
|
||||||
SETD.0 Fuel
|
SETD.0 Fuel
|
||||||
LDA.0
|
LDA.0
|
||||||
INIB 0d80
|
INIB 0d80
|
||||||
@@ -3613,6 +3672,11 @@ FallAt:
|
|||||||
; more arithmetic for a number nobody reads to the unit.
|
; more arithmetic for a number nobody reads to the unit.
|
||||||
Fuel:
|
Fuel:
|
||||||
0xFF
|
0xFF
|
||||||
|
GaugeColour:
|
||||||
|
0x00
|
||||||
|
; Whether the quarter tank warning has been given since the last time it was filled.
|
||||||
|
AlarmSaid:
|
||||||
|
0x00
|
||||||
GaugeLeft:
|
GaugeLeft:
|
||||||
0x00
|
0x00
|
||||||
GaugeAt:
|
GaugeAt:
|
||||||
@@ -4093,3 +4157,5 @@ LanderArtAt:
|
|||||||
#Include math.asm
|
#Include math.asm
|
||||||
|
|
||||||
#Include boom.asm
|
#Include boom.asm
|
||||||
|
|
||||||
|
#Include alarm.asm
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -34,9 +34,11 @@
|
|||||||
"lfo0_rate": 8.796101,
|
"lfo0_rate": 8.796101,
|
||||||
"lfo0_waveform": 0,
|
"lfo0_waveform": 0,
|
||||||
"lfo0_active": 0,
|
"lfo0_active": 0,
|
||||||
|
"lfo0_mode": 0,
|
||||||
"lfo1_rate": 1.000000,
|
"lfo1_rate": 1.000000,
|
||||||
"lfo1_waveform": 0,
|
"lfo1_waveform": 0,
|
||||||
"lfo1_active": 0,
|
"lfo1_active": 0,
|
||||||
|
"lfo1_mode": 0,
|
||||||
"filter_cutoff": 13294.700195,
|
"filter_cutoff": 13294.700195,
|
||||||
"filter_resonance": 0.574200,
|
"filter_resonance": 0.574200,
|
||||||
"filter_type": 0,
|
"filter_type": 0,
|
||||||
@@ -46,6 +48,7 @@
|
|||||||
"filter_resModRouting": 0,
|
"filter_resModRouting": 0,
|
||||||
"filter_resModDepth": 0.000000,
|
"filter_resModDepth": 0.000000,
|
||||||
"voice_levelSource": 2,
|
"voice_levelSource": 2,
|
||||||
|
"voice_gate": 1,
|
||||||
"master_volume": 1.000000,
|
"master_volume": 1.000000,
|
||||||
"master_pitchBendRange": 2.000000
|
"master_pitchBendRange": 2.000000
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
; AlarmPatch, converted from Programs/Sounds/LowFuel.json by SoundPatch.
|
||||||
|
; Designed in soundThing, where it can be heard. Do not edit the numbers
|
||||||
|
; here: change the patch and convert it again.
|
||||||
|
|
||||||
|
#Data
|
||||||
|
|
||||||
|
AlarmPatch:
|
||||||
|
0d50 ; how many pairs follow
|
||||||
|
0x00 0d1 ; oscillator 0, waveform
|
||||||
|
0x01 0d255 ; gain
|
||||||
|
0x02 0d128 ; duty
|
||||||
|
0x03 0d128 ; detune, in cents
|
||||||
|
0x04 0d130 ; octave
|
||||||
|
0x05 0d1 ; on
|
||||||
|
0x06 0d0 ; what moves its width
|
||||||
|
0x07 0d128 ; and how far
|
||||||
|
0x08 0d3 ; what moves its pitch
|
||||||
|
0x09 0d83 ; and how far
|
||||||
|
0x0A 0d1 ; what moves its gain
|
||||||
|
0x0B 0d255 ; and how far
|
||||||
|
0x10 0d1 ; oscillator 1, waveform
|
||||||
|
0x11 0d255 ; gain
|
||||||
|
0x12 0d128 ; duty
|
||||||
|
0x13 0d128 ; detune, in cents
|
||||||
|
0x14 0d128 ; octave
|
||||||
|
0x15 0d1 ; on
|
||||||
|
0x16 0d0 ; what moves its width
|
||||||
|
0x17 0d128 ; and how far
|
||||||
|
0x18 0d3 ; what moves its pitch
|
||||||
|
0x19 0d83 ; and how far
|
||||||
|
0x1A 0d1 ; what moves its gain
|
||||||
|
0x1B 0d255 ; and how far
|
||||||
|
0x20 0d4 ; amplitude envelope, attack
|
||||||
|
0x21 0d97 ; decay
|
||||||
|
0x22 0d255 ; sustain
|
||||||
|
0x23 0d33 ; release
|
||||||
|
0x30 0d9 ; modulation envelope, attack
|
||||||
|
0x31 0d90 ; decay
|
||||||
|
0x32 0d0 ; sustain
|
||||||
|
0x33 0d40 ; release
|
||||||
|
0x40 0d0 ; filter, on
|
||||||
|
0x41 0d0 ; type: 0 low, 1 high, 2 band
|
||||||
|
0x42 0d221 ; cutoff, in hertz
|
||||||
|
0x43 0d0 ; resonance
|
||||||
|
0x44 0d0 ; what moves the cutoff
|
||||||
|
0x45 0d128 ; and how far, in hertz
|
||||||
|
0x46 0d0 ; what moves the resonance
|
||||||
|
0x47 0d128 ; and how far
|
||||||
|
0x60 0d1 ; LFO 0, on
|
||||||
|
0x61 0d2 ; waveform
|
||||||
|
0x62 0d180 ; rate, in hertz
|
||||||
|
0x63 0d1 ; 0 free, 1 starts with a voice
|
||||||
|
0x70 0d0 ; LFO 1, on
|
||||||
|
0x71 0d0 ; waveform
|
||||||
|
0x72 0d127 ; rate, in hertz
|
||||||
|
0x73 0d0 ; 0 free, 1 starts with a voice
|
||||||
|
0x50 0d1 ; what shapes the level
|
||||||
|
0x51 0d1 ; 0 gated, 1 triggered
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
; BoomPatch, converted from Programs/Sounds/Crash1.json by SoundPatch.
|
; BoomPatch, converted from Programs/Sounds/Crash.json by SoundPatch.
|
||||||
; Designed in soundThing, where it can be heard. Do not edit the numbers
|
; Designed in soundThing, where it can be heard. Do not edit the numbers
|
||||||
; here: change the patch and convert it again.
|
; here: change the patch and convert it again.
|
||||||
|
|
||||||
#Data
|
#Data
|
||||||
|
|
||||||
BoomPatch:
|
BoomPatch:
|
||||||
0d47 ; how many pairs follow
|
0d50 ; how many pairs follow
|
||||||
0x00 0d5 ; oscillator 0, waveform
|
0x00 0d5 ; oscillator 0, waveform
|
||||||
0x01 0d255 ; gain
|
0x01 0d255 ; gain
|
||||||
0x02 0d128 ; duty
|
0x02 0d128 ; duty
|
||||||
@@ -49,7 +49,10 @@ BoomPatch:
|
|||||||
0x60 0d0 ; LFO 0, on
|
0x60 0d0 ; LFO 0, on
|
||||||
0x61 0d0 ; waveform
|
0x61 0d0 ; waveform
|
||||||
0x62 0d220 ; rate, in hertz
|
0x62 0d220 ; rate, in hertz
|
||||||
|
0x63 0d0 ; 0 free, 1 starts with a voice
|
||||||
0x70 0d0 ; LFO 1, on
|
0x70 0d0 ; LFO 1, on
|
||||||
0x71 0d0 ; waveform
|
0x71 0d0 ; waveform
|
||||||
0x72 0d127 ; rate, in hertz
|
0x72 0d127 ; rate, in hertz
|
||||||
|
0x73 0d0 ; 0 free, 1 starts with a voice
|
||||||
0x50 0d2 ; what shapes the level
|
0x50 0d2 ; what shapes the level
|
||||||
|
0x51 0d1 ; 0 gated, 1 triggered
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Mode.sbx 48
|
|||||||
Flip.sbx 173
|
Flip.sbx 173
|
||||||
Sprite.sbx 442
|
Sprite.sbx 442
|
||||||
Depth.sbx 672
|
Depth.sbx 672
|
||||||
Lander.sbx 8409
|
Lander.sbx 8608
|
||||||
Pad.sbx 264
|
Pad.sbx 264
|
||||||
Crash.sbx 632
|
Crash.sbx 632
|
||||||
vars.script 50
|
vars.script 50
|
||||||
|
|||||||
@@ -2714,6 +2714,70 @@ EOT
|
|||||||
&& result ok "and it is loudest at the front" "which is what makes it a bang" \
|
&& result ok "and it is loudest at the front" "which is what makes it a bang" \
|
||||||
|| result no "and it is loudest at the front" "louder in the second half than the first"
|
|| result no "and it is loudest at the front" "louder in the second half than the first"
|
||||||
|
|
||||||
|
# ---- A quarter of a tank, said once ----
|
||||||
|
#
|
||||||
|
# ONCE is the whole design of it. A lander is at its most careful in the last few seconds
|
||||||
|
# before it touches, and something repeating in its ear through that is not a warning, it is a
|
||||||
|
# distraction. So it fires on the way DOWN through a quarter tank and then holds its peace,
|
||||||
|
# and filling up at a base allows it again.
|
||||||
|
#
|
||||||
|
# The gauge says the same thing the other way round: the sound is the moment it happened, the
|
||||||
|
# colour is how things stand. Both off the same number, so they cannot disagree.
|
||||||
|
python3 -c "
|
||||||
|
import struct
|
||||||
|
# Seventy of two hundred and fifty five, which is a few ticks of thruster above the quarter.
|
||||||
|
open('$BUILD/lowfuel.state','wb').write(struct.pack('<hhhhhhBBBB',
|
||||||
|
0x14A0, 0, 0, 0, 0x14A0, 2600, 70, 0, 0, 0))
|
||||||
|
"
|
||||||
|
cp "$ROOT/Tests/build/disks/cosmos.img" "$BUILD/lowfuel.img"
|
||||||
|
"$ROOT/SplitDisk" put "$BUILD/lowfuel.img" "$BUILD/lowfuel.state" /lander.state > /dev/null
|
||||||
|
python3 -c "open('$BUILD/burn.pad','wb').write(b'\x08' * 40000)"
|
||||||
|
for when in 1700000 2400000; do
|
||||||
|
timeout 60 "$EMU" --fast --cycles $when --keyboard "$BUILD/fly.keys" \
|
||||||
|
--pad "$BUILD/burn.pad" --screen "$BUILD/fuel$when.ppm" \
|
||||||
|
--disk "$BUILD/lowfuel.img" --ram-disk 2048 \
|
||||||
|
"$BUILD/cosmos.bin" > "$BUILD/fuel.out" 2>&1 || true
|
||||||
|
done
|
||||||
|
timeout 60 "$EMU" --fast --cycles 12000000 --keyboard "$BUILD/fly.keys" \
|
||||||
|
--pad "$BUILD/burn.pad" --sound "$BUILD/warn.raw" \
|
||||||
|
--disk "$BUILD/lowfuel.img" --ram-disk 2048 \
|
||||||
|
"$BUILD/cosmos.bin" > "$BUILD/warn.out" 2>&1 || true
|
||||||
|
read -r ABOVE BELOW WARNINGS <<EOT
|
||||||
|
$(python3 -c "
|
||||||
|
def gauge(path):
|
||||||
|
d = open(path, 'rb').read()
|
||||||
|
width = int(d[:40].split()[1])
|
||||||
|
px = d[d.index(b'255\n') + 4:]
|
||||||
|
def cells(colour):
|
||||||
|
c = bytes.fromhex(colour)
|
||||||
|
# The top row of the window, which is where the gauge is drawn.
|
||||||
|
return sum(1 for i in range(len(px) // 3)
|
||||||
|
if px[i * 3:i * 3 + 3] == c and i // width < 8) // 64
|
||||||
|
return '%d,%d' % (cells('50c050'), cells('d04038'))
|
||||||
|
import struct
|
||||||
|
raw = open('$BUILD/warn.raw', 'rb').read()
|
||||||
|
s = struct.unpack('<%dh' % (len(raw) // 2), raw)
|
||||||
|
# ---- HOW LONG it sounds for, not how many times it starts ----
|
||||||
|
#
|
||||||
|
# Counting bursts cannot tell one beep from a nag. Without the latch the warning fires on
|
||||||
|
# every tick the tank goes down, which is once every ten frames - far faster than the sound
|
||||||
|
# decays, so the beeps run into each other and a burst counter sees ONE long burst either way.
|
||||||
|
# The length is what differs: six tenths of a second against ten seconds of it.
|
||||||
|
loud = [i for i, x in enumerate(s) if abs(x) > 300]
|
||||||
|
span = (loud[-1] - loud[0]) if loud else 0
|
||||||
|
print(gauge('$BUILD/fuel1700000.ppm'), gauge('$BUILD/fuel2400000.ppm'), span)
|
||||||
|
" 2>/dev/null || echo "none none -1")
|
||||||
|
EOT
|
||||||
|
# Green cells then red cells, and none of the other colour either time.
|
||||||
|
[ "$ABOVE" = "8,0" ] && [ "$BELOW" = "0,7" ] \
|
||||||
|
&& result ok "the fuel gauge goes red at a quarter" "eight green became seven red" \
|
||||||
|
|| result no "the fuel gauge goes red at a quarter" "$ABOVE above, $BELOW below"
|
||||||
|
# Twelve seconds of holding the thruster, which empties the tank entirely and keeps it empty.
|
||||||
|
# The warning is under a second of that, or it is a nag rather than a warning.
|
||||||
|
[ "$WARNINGS" -gt 0 ] && [ "$WARNINGS" -lt 48000 ] \
|
||||||
|
&& result ok "and the warning sounds once, not once a tick" "$WARNINGS samples of it in twelve seconds of running dry" \
|
||||||
|
|| result no "and the warning sounds once, not once a tick" "$WARNINGS samples of warning"
|
||||||
|
|
||||||
# ---- Dust on landing, and gas on letting go ----
|
# ---- Dust on landing, and gas on letting go ----
|
||||||
#
|
#
|
||||||
# The same six pieces as the explosion, thrown differently: dust goes sideways and UP off the
|
# The same six pieces as the explosion, thrown differently: dust goes sideways and UP off the
|
||||||
|
|||||||
Reference in New Issue
Block a user