The first customer for the player outside the program it was pulled out of, and the argument for doing it: a splash needs no resident player at all. Nothing else is happening while the logo is up, so Lander owns the timer and all four channels exactly as Play does. Music UNDER a running game is still deferred, and still the harder problem. It polls the timer rather than being interrupted by it. Lander has no vector segment and waits for the screen by reading port 0x30, so it waits for a beat by reading port 0x50 - the same shape, and it brings no handler that would have to be taken away before the game starts. The tune is read off the disk. A missing one means the logo and silence and the game starts anyway, the way a missing /lander.state means the defaults stand. FOUR THINGS THIS COST, each found by running it: A subroutine cannot answer in A. CALL saves and restores it, so splashSkip handed its caller back the A it already had - the channel number of the last stepVoice - and the splash ended on its first pass whatever anybody pressed. Q is what survives a RET, which nextRandom says twenty lines away and I did not read. Port 0x3D is how many window rows are SHOWN, and it is two once putGauge runs and nothing before. A line written to row eleven went somewhere real and was displayed nowhere. A nought is not a keypress. It is what a recorded keyboard file holds while nobody is typing, and a splash that took it for a key is one no test could ever watch. And skipping has to be free. Asked after blanking the window and reading the file, a skipped splash still cost a fifth of a second - enough to push the thruster test's early capture past the frame it looks at. Asked first, it costs a pad read. player.asm no longer asks a caller for Order0 to Order3: the voice records name NoOrder instead, so a program whose tune comes from a file does not have to define four order lists it never uses. That was the file case finding a wart in the contract. Every other Lander test now skips the splash with a space - a key the game itself ignores, since it answers to q, z and the arrows - so they go on testing what they tested. The one in sound.sh presses nothing, which is what makes it the one that hears the music. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
68 lines
914 B
Plaintext
68 lines
914 B
Plaintext
; Four bars, and the bass is the same one under two of them.
|
|
#Tick 0d125000 ; cycles a tick: a sixteenth note at 120 beats a minute
|
|
|
|
#Patch Oboe oboe.patch
|
|
|
|
#Voice 0d0 Oboe ; which instrument each voice starts on
|
|
#Voice 0d1 Oboe
|
|
#Voice 0d2 Oboe
|
|
#Voice 0d3 Oboe
|
|
|
|
#Sequence MotifA
|
|
0x30 0d2
|
|
0x00 0d2
|
|
0x3C 0d2
|
|
0x00 0d4
|
|
0x48 0d4
|
|
0x00 0d4
|
|
0x47 0d4
|
|
0x00 0d6
|
|
; 28 beats
|
|
|
|
#Sequence MotifB
|
|
0x00 0d2
|
|
0x35 0d2
|
|
0x00 0d2
|
|
0x40 0d4
|
|
0x00 0d4
|
|
0x45 0d4
|
|
0x00 0d4
|
|
0x43 0d6
|
|
|
|
|
|
#Sequence IntroQuiet
|
|
0x00 0d28
|
|
|
|
#Sequence ChordRoot
|
|
0x2C 0x4
|
|
0x2E 0x4
|
|
0x30 0x4
|
|
|
|
#Sequence ChordFifth
|
|
0x33 0x4
|
|
0x35 0x4
|
|
0x37 0x4
|
|
|
|
#Sequence ChordThird
|
|
0x3C 0x4
|
|
0x3E 0x4
|
|
0x40 0x4
|
|
|
|
#Sequence ChordQuiet
|
|
0x00 0d12
|
|
|
|
#Sequence Bass
|
|
0x24 0x8
|
|
|
|
#Order 0d0
|
|
MotifA ChordRoot
|
|
|
|
#Order 0d1
|
|
MotifB ChordFifth
|
|
|
|
#Order 0d2
|
|
IntroQuiet ChordThird
|
|
|
|
#Order 0d3
|
|
IntroQuiet ChordQuiet Bass
|