Scrolling and Layers in BASIC

One of the main benefits of the powerful graphic capabilities of the VERA chip in Commander X16 is hardware scrolling. If we add to this that we have two independent layers that can also be independently scrolled in four directions we have a very powerful tool to make BASIC programs and especially games look very slick.

The actual scrolling is done by a simple poke into a correct VERA register. Just POKE $9F39,1 and the whole screen will move up by one pixel and we are done. However, to take full advantage of it, let's make it a bit more complicated interesting. 

The Goal

The goal is to make a starry background that scrolls in four directions. We will scroll Layer 0 and keep Layer 1 static and draw some text and PETSCII lunar lander on it. To move it around we will give it a couple of thrusters and a main engine. Of course there will be gravity that will pull the lander down.

We will break up the project in following steps:

  • We will keep the default layer 1 unchanged so it could be used HUD or in our case text and lander.
  • We will turn on Layer 0, which sits under Layer 1 so the Layer 1 will have to become transparent.
  • Layer 0 will display stars in an infinite way, meaning we have to define tiles in such a way to be able to wrap it around. Let’s also use 4 (2 bpp) color mode for layer 0 so our stars can have multicolor designs.
  • At the end for better illusion, let’s create a lander out of PETSCII characters in the middle of the screen that we will animate and create a main loop to fly it around the starry background.
  • We will also design a few more custom characters to represent the thrusters and main engine exhausts. 

Layers

After initializing that we will look at later we need to turn on both layers and set the visible screen to 40 x 30 characters or tiles which translates to 320 x 240 pixels. It is very important to understand that this does not change the actual memory representation of the content we see on display.

Of course both layers will be shown at the same resolution however internally they can have different setup.

We will leave Layer 1 at the default settings:

  • 8x8 pixel tiles
  • 1 bit per pixel color resolution out of standard 16 color from the beginning of the palette (replicating C-64 colors)
  • 128 tiles wide, 64 tiles high

Layer 0 will be set to:

  • 8x8 pixel tiles
  • 2 bits per pixel color resolution so any pixel can have 4 different colors out of default palette of 256 colors
  • 64 tiles wide, 32 tiles high

Source code to achieve that is simple:


After configuration we make both layers visible.

Setup Tiles

Since we will not use any sprites we have to define few custom tiles to display stars as well as some details on a lander. Below is a drawing of the special characters we will create:



Three on the left are different intensity stars that are drawn in 2 bpp mode and will be displayed and scrolled on Layer 0. In addition to these three we will also define empty space to fill the space between the stars (no pun intended).

Three special characters on the right are drawn in 1 bpp mode and will replace some of the standard characters that are used by default on Layer 1. To two are exhaust for the left and right thruster and the bottom one is the flame for the main engine.


Since the grays in default Palette are not in the ideal position for our stars we will also redefine Palette with gray colors at the correct position like this:


Infinite Starfield

Let’s finally tackle the main topic of this article. If we check the VERA registers we see that we have 12 bits available for scrolling. That translates to values 0 - 4095 which means that we can scroll the area of 4096 x 4096 pixels or in 8x8 tiles a screen of 512 x 512 tiles which would occupy more than twice the Video RAM available. This is not only impossible but also extremely wasteful so for the simple scrolling background we can implement an infinite starfield that wraps around. That is achieved by repeating patterns. For most convincing illusion the scrolled screen would be as large as possible but that of course is not always possible, besides there should be things happening in foreground so the repetitive nature of background is much less noticeable.

For our little demo we will draw our starry background in 8 x 8 tiles pattern and repeat it over the whole background. This is going to be our pattern:



The above image will occupy 64 x 64 pixels ( 8 times x 8 times of 8 pixel by 8 pixel tiles) so every 65th pixel will be repeat of pixel 1 so in order to create a smooth appearance we will have to scroll 64 times by one pixel and then we can reset our scroll register back to 0. This means that we will have to create two scroll counters in our program that will go from 0 to 63 and then again to 0 when scrolling up or left and in the opposite direction when scrolling down and right. We will also only need to poke one byte for each direction because we only use 6 bits for scrolling offset.

We have to calculate one more thing. Since our display in the chosen mode will display 40 tiles horizontally and 30 tiles vertically we need to draw some extra data into Video RAM so VERA has something to display when we move beyond the initially visible tiles. Horizontally 40 tiles divided by 8 comes to exactly 5 repeats of 8x8 pattern. To allow for scrolling another 64 bits horizontally we have to add one more repetition for a total of 6.

Vertically 30 tiles divided by 8 comes to a bit under 4 repeats so we have to draw the pattern 5 times. So starfield drawing function looks like this:


To illustrate all this let’s look at the animation of how the video memory looks like during the vertical animation cycle:



Here we clearly see why we had to draw to a larger area than is shown at frame 0 by VERA. Also let's emphasize again that all that is needed to make screen background like this is to poke one value like above to register $9F32 for Vertical scroll for Layer 0 and pretty much does not take any CPU time which can be used to take care of actual game.

The Lander

Finally we draw the lander using PETSCII characters to Layer 1 like this:


Main Loop

After all these preparations the main loop is very straightforward. To make it more interesting and to simulate gravity we use the Vertical Acceleration VA variable instead of directly changing the vertical scroll.



And here is short video of the end result looks like:





All that is missing for the full game now is some land and collision control, which might be an interesting task for you to add.


Link to full Source Code

Comments

Popular posts from this blog

Commander X16 Premium Keyboard

Hello VERA (BASIC vs C vs Assembly)

Default Palette