.DEATH JSR ResetMusicAfterNMI ; Wait for the next NMI before resetting the current ; tune to 0 (no tune) and stopping the music JSR EXNO3 ; Make the sound of us dying JSR RES2 ; Reset a number of flight variables and workspaces ASL DELTA ; Divide our speed in DELTA by 4 ASL DELTA LDA #0 ; Set the tile number for the left edge of the box to STA boxEdge1 ; the blank tile, so the box around the space view ; disappears STA boxEdge2 ; Set the tile number for the right edge of the box to ; the blank tile, so the box around the space view ; disappears STA autoPlayDemo ; Disable auto-play by setting autoPlayDemo to zero, in ; case we die during the auto-play combat demo LDA #$C4 ; Clear the screen and set the view type in QQ11 to $95 JSR TT66 ; (Game Over screen) JSR ClearDashEdge_b6 ; Clear the right edge of the dashboard JSR CopyNameBuffer0To1 ; Copy the contents of nametable buffer 0 to nametable ; buffer JSR SetScreenForUpdate ; Get the screen ready for updating by hiding all ; sprites, after fading the screen to black if we are ; changing view LDA #0 ; Set showIconBarPointer to 0 to indicate that we should STA showIconBarPointer ; hide the icon bar pointer LDA #$C4 ; Configure the PPU for view type $C4 (Game Over screen) JSR SendViewToPPU_b3 LDA #$00 ; Set the view type in QQ11 to $00 (Space view with no STA QQ11 ; font loaded) STA QQ11a ; Set the old view type in QQ11a to $00 (Space view with ; no fonts loaded) LDA firstFreePattern ; Tell the NMI handler to send pattern entries from the STA firstPattern ; first free pattern onwards, so we don't waste time ; resending the static patterns we have already sent LDA #116 ; Tell the NMI handler to only clear nametable entries STA maxNameTileToClear ; up to tile 116 * 8 = 800 (i.e. up to the end of tile ; row 28) LDX #8 ; Tell the NMI handler to send nametable entries from STX firstNameTile ; tile 8 * 8 = 64 onwards (i.e. from the start of tile ; row 2) LDA #104 ; Set the screen height variables for a screen height of JSR SetScreenHeight ; 208 (i.e. 2 * 104) ; Next we fill the scannerNumber table with non-zero ; entries so when we spawn ships for the death screen, ; they don't appear on the scanner because the scanner ; number table doesn't have any free slots LDY #8 ; Set an index in Y to work through the eight entries ; in the scannerNumber table LDA #1 ; Set A = 1 to use as the value for every ship in the ; scannerNumber table, which is non-zero so the NWSHP ; routine will skip the scanner configuration for any ; ships we spawn .deaf1 STA scannerNumber,Y ; Set the Y-th scannerNumber entry to 1 DEY ; Decrement the index in Y BNE deaf1 ; Loop back until we have set entries 1 to 8 in the ; table to 1, so nothing spawns on the scanner JSR nWq ; Create a cloud of stardust containing the correct ; number of dust particles (i.e. NOSTM of them) ; We now give our ship a random amount of roll by ; setting all the various alpha angle variables JSR DORND ; Set A and X to random numbers AND #%10000111 ; Set the roll angle in ALPHA to the random number, STA ALPHA ; reduced to the range 0 to 7, and with a random sign AND #7 ; Set the magnitude of roll angle alpha in ALP1 to the STA ALP1 ; same value, but with the sign bit cleared (so ALP1 ; contains the magnitude of the roll) LDA ALPHA ; Set the sign of the roll angle alpha in ALP2 to the AND #%10000000 ; sign of ALPHA (so ALP2 contains the sign of the roll) STA ALP2 EOR #%10000000 ; Set the sign of the roll angle alpha in ALP2+1 to the STA ALP2+1 ; flipped sign of ALPHA (so ALP2 contains the flipped ; sign of the roll) .D1 JSR Ze ; Call Ze to initialise INWK to a potentially hostile ; ship, and set A and X to random values LSR A ; Set A = A / 4, so A is now between 0 and 63, and LSR A ; store in byte #0 (x_lo) STA INWK LDY #$00 ; Set the view type in QQ11 to $00 (Space view with no STY QQ11 ; font loaded) STY INWK+1 ; Set the following to 0: x_hi, y_hi, z_hi and the AI STY INWK+4 ; flag (no AI or E.C.M. and not hostile) STY INWK+7 STY INWK+32 DEY ; Set Y = 255 STY MCNT ; Reset the main loop counter to 255, so all timer-based ; calls will be stopped EOR #%00101010 ; Flip bits 1, 3 and 5 in A (x_lo) to get another number STA INWK+3 ; between 48 and 63, and store in byte #3 (y_lo) ORA #%01010000 ; Set bits 4 and 6 of A to bump it up to between 112 and STA INWK+6 ; 127, and store in byte #6 (z_lo) TXA ; Set A to the random number in X and keep bits 0-3 and AND #%10001111 ; the sign in bit 7 to get a number between -15 and +15, STA INWK+29 ; and store in byte #29 (roll counter) to give our ship ; a gentle roll with damping LDY #64 ; Set the laser count to 64 to act as a counter in the STY LASCT ; D2 loop below, so this setting determines how long the ; death animation lasts (it's 64 * 2 iterations of the ; main flight loop) SEC ; Set the C flag ROR A ; This sets A to a number between 0 and +7, which we AND #%10000111 ; store in byte #30 (the pitch counter) to give our ship STA INWK+30 ; a very gentle downwards pitch with damping LDX #OIL ; Set X to #OIL, the ship type for a cargo canister LDA XX21-1+2*PLT ; Fetch the byte from location XX21 - 1 + 2 * PLT, which ; equates to XX21 + 7 (the high byte of the address of ; SHIP_PLATE), which seems a bit odd. It might make more ; sense to do LDA (XX21-2+2*PLT) as this would fetch the ; first byte of the alloy plate's blueprint (which ; determines what happens when alloys are destroyed), ; but there aren't any brackets, so instead this always ; returns $D0, which is never zero, so the following ; BEQ is never true. (If the brackets were there, then ; we could stop plates from spawning on death by setting ; byte #0 of the blueprint to 0... but then scooping ; plates wouldn't give us alloys, so who knows what this ; is all about?) BEQ D3 ; If A = 0, jump to D3 to skip the following instruction BCC D3 ; If the C flag is clear, which will be random following ; the above call to Ze, jump to D3 to skip the following ; instruction DEX ; Decrement X, which sets it to #PLT, the ship type for ; an alloy plate .D3 JSR fq1 ; Call fq1 with X set to #OIL or #PLT, which adds a new ; cargo canister or alloy plate to our local bubble of ; universe and points it away from us with double DELTA ; speed (i.e. 6, as DELTA was set to 3 by the call to ; RES2 above). INF is set to point to the new arrival's ; ship data block in K% JSR DORND ; Set A and X to random numbers and extract bit 7 from A AND #%10000000 LDY #31 ; Store this in byte #31 of the ship's data block, so it STA (INF),Y ; has a 50% chance of marking our new arrival as being ; killed (so it will explode) LDA FRIN+6 ; The call we made to RES2 before we entered the loop at BEQ D1 ; D1 will have reset all the ship slots at FRIN, so this ; checks to see if the seventh slot is empty, and if it ; is we loop back to D1 to add another canister, until ; we have added seven of them LDA #8 ; Set our speed in DELTA to 8, so the camera moves STA DELTA ; forward slowly LDA #12 ; Set the text row for in-flight messages in the space STA messYC ; view to row 12 LDA #146 ; Print recursive token 146 ("{all caps}GAME OVER") in LDY #120 ; the middle of the screen and leave it there for 120 JSR PrintMessage ; ticks of the DLY counter JSR HideMostSprites ; Hide all sprites except for sprite 0 and the icon bar ; pointer LDA #30 ; Set the laser count to 30 to act as a counter in the STA LASCT ; D2 loop below, so this setting determines how long the ; death animation lasts .D2 JSR FlipDrawingPlane ; Flip the drawing bitplane so we draw into the bitplane ; that isn't visible on-screen JSR FlightLoop4To16 ; Display in-flight messages, call parts 4 to 12 of the ; main flight loop for each ship slot, and finish off ; with parts 13 to 16 of the main flight loop JSR ClearDashEdge_b6 ; Clear the right edge of the dashboard LDA #%11001100 ; Set the bitplane flags for the drawing bitplane to the JSR SetDrawPlaneFlags ; following: ; ; * Bit 2 set = send tiles up to end of the buffer ; * Bit 3 set = clear buffers after sending data ; * Bit 4 clear = we've not started sending data yet ; * Bit 5 clear = we have not yet sent all the data ; * Bit 6 set = send both pattern and nametable data ; * Bit 7 set = send data to the PPU ; ; Bits 0 and 1 are ignored and are always clear ; ; This configures the NMI to send nametable and pattern ; data for the drawing bitplane to the PPU during VBlank DEC LASCT ; Decrement the counter in LASCT, which we set above, ; so for each loop around D2, we decrement LASCT by 5 ; (the main loop decrements it by 4, and this one makes ; it 5) BNE D2 ; Loop back to call the main flight loop again, until we ; have called it 127 times JMP DEATH2 ; Jump to DEATH2 to reset and restart the gameName: DEATH [Show more] Type: Subroutine Category: Start and end Summary: Display the death screen Deep dive: Splitting the main loop in the NES versionContext: See this subroutine in context in the source code References: This subroutine is called as follows: * CheckAltitude calls DEATH * Main flight loop (Part 9 of 16) calls DEATH * Main flight loop (Part 15 of 16) calls DEATH * OOPS calls DEATH
We have been killed, so display the chaos of our destruction above a "GAME OVER" sign, and clean up the mess ready for the next attempt.
[X]
Subroutine ClearDashEdge_b6 (category: Drawing the screen)
Call the ClearDashEdge routine in ROM bank 6
[X]
Subroutine CopyNameBuffer0To1 (category: Drawing the screen)
Copy the contents of nametable buffer 0 to nametable buffer 1
[X]
Label D1 is local to this routine
[X]
Label D2 is local to this routine
[X]
Label D3 is local to this routine
[X]
Subroutine DEATH2 (category: Start and end)
Reset most of the game and restart from the title screen
[X]
Subroutine DORND (category: Maths (Arithmetic))
Generate random numbers
[X]
Subroutine EXNO3 (category: Sound)
Make an explosion sound
[X]
Subroutine FlightLoop4To16 (category: Main loop)
Display in-flight messages, call parts 4 to 12 of the main flight loop for each slot, and fall through into parts 13 to 16
[X]
Subroutine FlipDrawingPlane (category: Drawing the screen)
Flip the drawing bitplane
[X]
Subroutine HideMostSprites (category: Drawing sprites)
Hide all sprites except for sprite 0 and the icon bar pointer
[X]
Configuration variable OIL = 5
Ship type for a cargo canister
[X]
Configuration variable PLT = 4
Ship type for an alloy plate
[X]
Subroutine PrintMessage (category: Text)
Print a message in the middle of the screen (used for "GAME OVER" and demo missile messages only)
[X]
Subroutine RES2 (category: Start and end)
Reset a number of flight variables and workspaces
[X]
Subroutine ResetMusicAfterNMI (category: Sound)
Wait for the next NMI before resetting the current tune to 0 and stopping the music
[X]
Subroutine SendViewToPPU_b3 (category: PPU)
Call the SendViewToPPU routine in ROM bank 3
[X]
Subroutine SetDrawPlaneFlags (category: Drawing the screen)
Set the drawing bitplane flags to the specified value, draw the box edges and set the next free tile number
[X]
Subroutine SetScreenForUpdate (category: Drawing sprites)
Get the screen ready for updating by hiding all sprites, after fading the screen to black if we are changing view
[X]
Subroutine SetScreenHeight (category: Drawing the screen)
Set the screen height variables to the specified height
[X]
Subroutine TT66 (category: Drawing the screen)
Clear the screen and set the new view type
[X]
Variable XX21 (category: Drawing ships)
Ship blueprints lookup table
[X]
Subroutine Ze (category: Universe)
Initialise the INWK workspace to a hostile ship
[X]
Variable autoPlayDemo in workspace WP
Controls whether to play the demo automatically (which happens after it is left idle for a while)
[X]
Label deaf1 is local to this routine
[X]
Variable firstFreePattern in workspace ZP
Contains the number of the first free pattern in the pattern buffer that we can draw into next (or 0 if there are no free patterns)
[X]
Variable firstNameTile in workspace ZP
The number of the first tile for which we send nametable data to the PPU in the NMI handler (potentially for both bitplanes, if both are configured to be sent)
[X]
Variable firstPattern in workspace ZP
The number of the first pattern for which we send data to the PPU in the NMI handler (potentially for both bitplanes, if both are configured to be sent)
[X]
Variable maxNameTileToClear in workspace ZP
The tile number at which the NMI handler should stop clearing tiles in the nametable buffers during its clearing cycle
[X]
Subroutine nWq (category: Stardust)
Create a random cloud of stardust
[X]
Variable scannerNumber in workspace WP
Details of which scanner numbers are allocated to ships on the scanner
[X]
Variable showIconBarPointer in workspace WP
Controls whether to show the icon bar pointer