Skip to navigation

Main game loop: MainGameLoop

Name: MainGameLoop [Show more] Type: Subroutine Category: Main game loop Summary: The main game loop for playing a landscape
Context: 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
.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)