Skip to navigation


Start and end: DEATH

[NES version, Bank 0]

Name: DEATH [Show more] Type: Subroutine Category: Start and end Summary: Display the death screen Deep dive: Splitting the main loop in the NES version
Context: 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.
.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 game