.MainGameLoop \ If we get here then we have either started a brand new \ game or we jumped here from game11 below when one of \ the following occurred: \ \ * The Sentinel has won \ \ * The player has moved to a new tile \ \ * The player has pressed the quit game key JSR FlushSoundBuffers \ Flush all four sound channel buffers LDA quitGame \ If bit 7 of quitGame is clear then the player has not BPL game1 \ pressed function key f1 to quit the game, so jump to \ game 1 to keep playing the game JMP MainTitleLoop \ The player has pressed function key f1 to quit the \ game, so jump to MainTitleLoop to restart the game .game1 \ If we get here then we have either started a brand new \ landscape or we jumped to MainGameLoop from game11 \ below when one of the following occurred: \ \ * The Sentinel has won \ \ * The player has moved to a new tile LDA sentinelHasWon \ If bit 7 of sentinelHasWon is set then the player has BMI game6 \ run out of energy either by trying to hyperspace or by \ being absorbed, so jump to game6 to restart the \ landscape \ If we get here then we have either started a brand new \ landscape or we jumped to MainGameLoop from game11 \ below when the player moved to a new tile \ \ In both cases we need to generate a brand new \ landscape view LDA #4 \ Set all four logical colours to physical colour 4 JSR SetColourPalette \ (blue), so this blanks the entire screen to blue LDA #0 \ Set screenOrBuffer = 0 to configure the drawing STA screenOrBuffer \ routines to draw directly onto the screen (as opposed \ to drawing into the screen buffer) STA lastPanKeyPressed \ Zero lastPanKeyPressed so that when we draw the whole \ landscape view onto the screen below, we draw it in \ character columns, working from left to right, in the \ same order as we would for a pan to the right (which \ is what a zero value of lastPanKeyPressed usually \ represents) STA sightsByteCount \ Set sightsByteCount to zero to reset the sights pixel \ byte stash STA sightsAreVisible \ Clear bit 7 of sightsAreVisible to indicate that the \ sights are not visible JSR SetScannerAndPause \ Set scannerUpdate to zero to prevent scanner updates \ \ This routine also performs a delay of 40 empty loops \ of 256 iterations each (i.e. 10,240 loops) LDA playerObject \ Set viewingObject to the object number of the player, STA viewingObject \ so the landscape view gets drawn from the perspective \ of the player BIT hyperspaceEndsGame \ If bit 7 of hyperspaceEndsGame is clear then the game BPL game2 \ has not ended because of a hyperspace, so jump to \ game2 to draw the landscape \ If we get here then the game has ended because the \ player performed a hyperspace BVS game7 \ If bit 6 of hyperspaceEndsGame is set then the game \ has ended because the player has hyperspaced from the \ Sentinel's tower, thus winning the game, so jump to \ game7 to process winning the landscape \ If we get here then bit 6 of hyperspaceEndsGame is \ clear and the player has run out of energy by trying \ to hyperspace without being able to create a robot \ into which they can hyperspace JSR ClearScreen \ Clear the screen JMP game4 \ Jump to game4 to skip drawing the landscape view, as \ the game has ended .game2 LDA uTurnStatus \ If bit 7 of uTurnStatus is set then we just performed BMI game3 \ a U-turn in the ProcessActionKeys routine, so jump to \ game3 to skip the following instruction, as we don't \ need to recalculate tile visibility if we are turning \ around (as the player hasn't moved) JSR GetTileVisibility \ For each tile in the landscape, calculate whether the \ player can see that tile, to speed up the process of \ drawing the landscape .game3 JSR ClearScreen \ Clear the screen JSR DrawLandscapeView \ Draw the landscape view JSR UpdateIconsScanner \ Update the icons in the top-left corner of the screen \ to show the player's current energy level and redraw \ the scanner box .game4 LDA #25 \ Set screenOrBuffer = 25 to configure the drawing STA screenOrBuffer \ routines to draw into the screen buffer (as opposed \ to drawing directly onto the screen) LDA #2 \ Call ConfigureBuffer with A = 2 to set up the screen JSR ConfigureBuffer \ buffer for use as a column buffer .game5 JSR ProcessSound \ Process any sounds or music that are being made in the \ background LDA musicCounter \ Loop back to keep calling ProcessSound until bit 7 of BPL game5 \ musicCounter is clear, so if any music is being \ played, we wait until it has finished LDA #&83 \ Set the palette to the first set of colours from the JSR SetColourPalette \ colourPalettes table, which the SpawnEnemies routine \ set to the correct palette for playing the game (so \ for landscape 0000 that would be blue, black, white \ and green, for example) LDA hyperspaceEndsGame \ Set A to the hyperspace status flag BPL game11 \ If bit 7 of hyperspaceEndsGame is clear then the game \ has not ended because of a hyperspace, so jump to \ game11 to keep going \ If we get here then the game has ended because of a \ hyperspace, and it must be because the player ran out \ of energy, as otherwise we would have taken the branch \ to game7 above STA sentinelHasWon \ Set bit 7 of sentinelHasWon to indicate that the \ player has run out of energy and the Sentinel has won LDA #6 \ Set soundEffect = 6 so the sound is processed as the STA soundEffect \ game over sound LDA #5 \ The Sentinel has won, so display the game over screen JSR ShowGameOverScreen \ with A = 5, so we decay the screen to black with a \ mass of 5 * 2400 = 12,000 randomly placed black dots .game6 \ If we get here then we restart the landscape by \ resetting all the game variables, initialising the \ the seed number generator and jumping into the main \ title loop to preview the landscape and play the game JSR ResetVariables \ Reset all the game's main variables LDY landscapeNumberHi \ Set (Y X) = landscapeNumber(Hi Lo) LDX landscapeNumberLo JSR InitialiseSeeds \ Initialise the seed number generator to generate the \ sequence of seed numbers for the landscape number in \ (Y X) and set maxNumberOfEnemies and the landscapeZero \ flag accordingly JMP main4 \ Jump to main4 in the main title loop to restart the \ landscape without having to enter the landscape's \ secret code again .game7 \ If we get here then we have successfully completed \ the landscape, so we display the secret code for the \ next landscape and go back to the title screen LDA #4 \ Set all four logical colours to physical colour 4 JSR SetColourPalette \ (blue), so this blanks the entire screen to blue \ In order to display the secret code for the next \ landscape we need to generate it, so we now reset the \ landscape seed generator, the tile visibility table \ and the object flags, to get ready for the generation \ process in the FinishLandscape routine LDX #3 \ We now zero bits 8 to 40 of the five-byte linear \ feedback shift landscape register, so set a byte \ counter in X to count four bytes LDA #0 \ Set A = 0 so we can zero the four bytes STA soundEffect \ Set soundEffect = 0 to disable sound effect processing \ in the ProcessSound routine .game8 STA seedNumberLFSR+1,X \ Zero byte X+1 of seedNumberLFSR(4 3 2 1 0) DEX \ Decrement the byte counter BPL game8 \ Loop back until we have reset all four bytes JSR ResetTilesObjects \ Reset the tile visibility table and deallocate all \ object numbers JSR FinishLandscape \ Add the player's energy to the landscape number to get \ the number of the next landscape and display that \ landscape's secret code as a title screen LDA #&87 \ Set the palette to the second set of colours from the JSR SetColourPalette \ colourPalettes table, which contains the fixed palette \ for the title screens (blue, black, red, yellow) LDA #10 \ Set soundCounter = 10 to count down while the next STA soundCounter \ sound is made LDA #66 \ Call the PlayMusic routine with A = 66 to play the JSR PlayMusic \ music for when the player finishes a landscape .game9 JSR ProcessSound \ Process any sounds or music that are being made in the \ background LDA musicCounter \ Loop back to keep calling ProcessSound until bit 7 of BPL game9 \ musicCounter is clear, so if any music is being \ played, we wait until it has finished LDX #6 \ Print text token 6: Print "PRESS ANY KEY" at (64, 100) JSR PrintTextToken JSR ReadKeyboard \ Enable the keyboard, flush the keyboard buffer and \ read a character from it (so this waits for a key \ press) .game10 JMP MainTitleLoop \ Jump to MainTitleLoop to restart the game from the \ title screen .game11 \ If we get here then the game is still in progress, so \ we progress the gameplay JSR ProcessGameplay \ Run the gameplay loop that processes all game key \ presses, returning here when the player moves, quits, \ loses or pans BCC game12 \ The ProcessGameplay routine will return with the C \ flag clear if we just finished a landscape pan and the \ player is still holding down a pan key, in which case \ jump to game12 to process the pan JMP MainGameLoop \ Otherwise the ProcessGameplay routine returned because \ one of the following is true: \ \ * The Sentinel has won \ \ * The player has moved to a new tile \ \ * The player has pressed the quit game key \ \ so jump to MainGameLoop to process these actions .game12 \ If we get here then the player is holding down a pan \ key and wants to pan the screen, so we need to process \ the pan LDA panKeyBeingPressed \ Update lastPanKeyPressed with the details of the pan STA lastPanKeyPressed \ key being pressed, so we can check later on whether it \ is still being held down LDA #0 \ Set numberOfScrolls = 0 to reset the scroll counter STA numberOfScrolls \ so the interrupt handler will not scroll the screen \ while we set up the new pan STA doNotDitherObject \ Clear bit 7 of doNotDitherObject to enable objects to \ be updated on the screen with a dithered effect BIT sightsAreVisible \ If bit 7 of sightsAreVisible is set then the sights BMI game13 \ are being shown, so jump to game13 to skip the \ following two instructions \ \ This ensures that when we pan the screen as a result \ of the sights moving off the edge of the screen, the \ panning process completes and doesn't get aborted if \ the player releases the pan key SEC \ The sights are not visible so we are panning the ROR keepCheckingPanKey \ screen because the player has pressed a pan key, so \ set bit 7 of keepCheckingPanKey so DrawLandscapeView \ will abort the drawing process if the player releases \ the pan key before the drawing process has finished .game13 JSR PanLandscapeView \ Pan the landscape and update the landscape view LSR keepCheckingPanKey \ Clear bit 7 of keepCheckingPanKey so DrawLandscapeView \ will keep drawing the landscape irrespective of the \ pan keys being held down (so this takes the routine \ back to its default behaviour) JSR UpdateIconsScanner \ Update the icons in the top-left corner of the screen \ to show the player's current energy level and redraw \ the scanner box LDA numberOfScrolls \ Set scrollCounter to the number of scrolls required, STA scrollCounter \ so the interrupt handler will scroll the screen by \ this many steps in the background .game14 LDA scrollCounter \ Loop around until scrollCounter is zero, so this waits BNE game14 \ until the interrupt handler has finished scrolling the \ landscape view, thus implementing the pan on-screen BEQ game11 \ Jump to game11 to continue progressing the gameplay \ (this BEQ is effectively a JMP as we just passed \ through a BNE)Name: MainGameLoop [Show more] Type: Subroutine Category: Main game loop Summary: The main game loop for playing a landscapeContext: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTileAltitudes calls via game10
Other entry points: game10 Jump to MainTitleLoop to restart the game
[X]
Subroutine ClearScreen (category: Graphics)
Clear the screen to a specified background
[X]
Subroutine ConfigureBuffer (category: Screen buffer)
Set up the variables required to configure the screen buffer to a specific buffer type
[X]
Subroutine DrawLandscapeView (Part 1 of 3) (category: Drawing the landscape)
Set up a number of variables for drawing the landscape view
[X]
Subroutine FinishLandscape (category: Main game loop)
Add the player's energy to the landscape number to get the number of the next landscape and display that landscape's secret code
[X]
Subroutine FlushSoundBuffers (category: Sound)
Flush all four sound channel buffers
[X]
Subroutine GetTileVisibility (category: Drawing the landscape)
For each tile in the landscape, calculate whether the player can see that tile, to speed up the process of drawing the landscape
[X]
Subroutine InitialiseSeeds (category: Landscape)
Initialise the seed number generator so it generates the sequence of seed numbers for a specific landscape number
[X]
Subroutine MainGameLoop (category: Main game loop)
The main game loop for playing a landscape
[X]
Subroutine MainTitleLoop (category: Main title loop)
The main title loop: display the title screen, fetch the landscape number/code, preview the landscape and jump to the main game loop
[X]
Subroutine PanLandscapeView (category: Drawing the landscape)
Pan the landscape and update the landscape view
[X]
Subroutine PlayMusic (category: Sound)
Play a piece of music
[X]
Subroutine PrintTextToken (category: Text)
Print a recursive text token
[X]
Subroutine ProcessGameplay (category: Gameplay)
A gameplay loop that processes all game key presses, returning to the main game loop when the player moves, quits, loses or pans
[X]
Subroutine ProcessSound (category: Sound)
Process any sound effects that have been configured so they play in the background (this is called regularly throughout gameplay)
[X]
Subroutine ReadKeyboard (category: Keyboard)
Enable the keyboard and read a character from it
[X]
Subroutine ResetTilesObjects (category: Main title Loop)
Reset the tile visibility table and deallocate all object numbers
[X]
Subroutine ResetVariables (category: Main title Loop)
Reset all the game's main variables
[X]
Subroutine SetColourPalette (category: Graphics)
Set the logical colours for each of the four physical colours in screen mode 5
[X]
Subroutine SetScannerAndPause (category: Main game loop)
Set the scanner update status and delay for 40 empty loops of 256 iterations each (i.e. 10,240 loops)
[X]
Subroutine ShowGameOverScreen (category: Title screen)
Display the game over screen
[X]
Subroutine UpdateIconsScanner (category: Scanner/energy row)
Update the icons in the top-left corner of the screen to show the player's current energy level and redraw the scanner box
[X]
Variable doNotDitherObject in workspace Main variable workspace
Controls whether the DitherScreenBuffer routine can update an object on the screen using a dithered effect
[X]
Label game1 is local to this routine
[X]
Label game11 is local to this routine
[X]
Label game12 is local to this routine
[X]
Label game13 is local to this routine
[X]
Label game14 is local to this routine
[X]
Label game2 is local to this routine
[X]
Label game3 is local to this routine
[X]
Label game4 is local to this routine
[X]
Label game5 is local to this routine
[X]
Label game6 is local to this routine
[X]
Label game7 is local to this routine
[X]
Label game8 is local to this routine
[X]
Label game9 is local to this routine
[X]
Variable hyperspaceEndsGame in workspace Main variable workspace
Records whether the player performing a hyperspace has just ended the game
[X]
Variable keepCheckingPanKey in workspace Main variable workspace
Controls whether the DrawLandscapeView routine aborts drawing if the pan key is released before it has finished
[X]
Variable landscapeNumberHi in workspace Main variable workspace
The high byte of the four-digit binary coded decimal landscape number (0000 to 9999)
[X]
Variable landscapeNumberLo in workspace Main variable workspace
The low byte of the four-digit binary coded decimal landscape number (0000 to 9999)
[X]
Variable lastPanKeyPressed in workspace Zero page
The direction of the last pan key that was pressed (which may not still be held down)
[X]
Entry point main4 in subroutine MainTitleLoop (category: Main title loop)
The entry point for restarting a landscape after dying, so the player doesn't have to enter the landscape's secret code again
[X]
Variable musicCounter in workspace Main variable workspace
A counter for the music currently being made, which counts up in the ProcessMusic routine while the music is being played
[X]
Variable numberOfScrolls in workspace Main variable workspace
The total number of scrolls that we need to perform for the current panning operation
[X]
Variable panKeyBeingPressed in workspace Zero page
The direction in which the player is currently panning
[X]
Variable playerObject in workspace Zero page
The number of the player object
[X]
Variable quitGame in workspace Main variable workspace
A flag to record whether the player has pressed function key f1 to quit the game
[X]
Variable screenOrBuffer in workspace Zero page
Controls whether the graphics routines draw directly onto the screen, or into the screen buffer
[X]
Variable scrollCounter in workspace Main variable workspace
A counter for the number of columns or rows we still need to scroll in the player's scrolling landscape view when the player pans
[X]
Variable seedNumberLFSR in workspace Main variable workspace
A five-byte linear feedback shift register for
[X]
Variable sentinelHasWon in workspace Main variable workspace
A flag to record when the player runs out of energy (i.e. the energy level goes negative), at which point the Sentinel wins
[X]
Variable sightsAreVisible in workspace Main variable workspace
Controls whether the sights are being shown
[X]
Variable sightsByteCount in workspace Main variable workspace
The number of screen bytes in the sights pixel byte stash that contain the contents of the screen behind the sights (so they can be restored to remove the sights)
[X]
Variable soundCounter in workspace Main variable workspace
A counter for the sound currently being made, which counts down in the IRQHandler routine at a rate of 50 times a second
[X]
Variable soundEffect in workspace Main variable workspace
Determines how the current sound is processed by the ProcessSound routine
[X]
Variable uTurnStatus in workspace Main variable workspace
A flag to record whether we are performing or have just performed a U-turn
[X]
Variable viewingObject in workspace Zero page
The number of the viewing object