True Vertical Parallax on the Commodore 64
First published on:
Ever since I released the first playable demos of my prototype Commodore 64 game, Colony (now known as
Parallaxian, back in the mid 1990s, I had mused on how
I could have enhanced the visual qualities of the game.
Specifically, I wondered if the parallaxed landscape could be given a vertical component, as a means of emphasising the sense of space and motion.
Obviously, such features are common in games for more modern platforms, but have never been seen in legacy machines such as the Commodore 64; Ocean's 1986 release, Parallax doesn't count because the entirety of its eponymous parallaxing doesn't extend beyond a simple pattern shift effect - as can be seen in the clip below.
Unremarkable though that parallax effect was by today's visual standards, it was nonetheless enough to build an entire game model around and even name the game after!
Another example from the C64's heyday would be Thunderblade, which demonstrated an extremely crude and somewhat ugly kind of vertical (and slight horizontal) parallax effect:
A much more recent example would be MAH, an unusual game featuring vertical parallax elements
using what appears to be a simple (correct me if I am wrong about that!) vertical pattern shift effect:
It's a slick effect but what I was seeking is something quite different.
With close to three decades of the demo scene expanding the Commodore 64's capability envelope, I felt maybe it's time to raise the bar on parallax effects too by working a vertical parallax scroll into Parallaxian's landscape so that it dips and rises as the plane climbs or dives.
In other words, let's make Parallaxian's parallax scroller a little more... "16-bit".
Hardware or Software?
Upon deciding I had to try to reduce the "console gap" through this innovation, the first methodology I thought of was the obvious go-to
hardware scroll feature of the VIC-II's notoriously tricky $D011 register.
After all, why bother concocting the charset graphics and associated handling routines for a bloaty software solution when the same effect could be achieved by tickling a register?
That said, I had to be wary of knocking the open top and bottom borders out of kilter, as they rely on $D011 tweaks from within the main game interrupt to stay open.
That initial concern was immediately allayed when I began to cut code; $D011 could be modified by the interrupt handlers managing the landscape layers between the top and bottom of the screen without losing the open borders effect.
But... the outcome was mostly hideous: landscape layers shunted out of place and system crashes for no immediately obvious reason; like I said, $D011 doesn't take kindly to being prodded.
However, through lengthy experimentation, I was able to use $D011 alone to vertically scroll the foreground's full-colour scrolling layer (that's the part that has the base and all the little men running around), but it required a sacrifice in the form of the panel below it being reduced by 8 pixels in height (later 16 pixels) to accommodate a buffer space for the vertical scrolling.
There was a snag, however.
The interrupt layering was such that there was only enough space for around 3-4 pixels of vertical scroll in that layer; any more and the machine would crash or the interrupt would stall.
That was never going to suffice; after all, we need the upper layers in the landscape to vertically parallax scroll as well if the effect is to be worthwhile, and that's not going to work if the foreground can only scroll a few pixels vertically.
The only solution for that was to alter the raster trigger values for each handler and to change the size of the foreground layer, making it eat into the distant trees layer above it.
That would mean I could now have a 6 pixel scroll vertical scroll on the foreground before it stalled the interrupt, which was enough to convey the vertical motion needed in that layer.
However, the foreground also required an additional interrupt handler, i.e., another raster interrupt layer to create the buffer zone mentioned above, bringing the total in the game engine to nine.
Or let me put it this way. The game's raster interrupt now does the following via its nine handlers:
- Multiplexes and updates the sprites across 3 screen regions;
- Animates the software sprites aka the little men running around the landscape;
- Sequences the toggleplexing and motions of Sprite #$02 (the afterburner and laser / bomb sprite);
- Polls the joystick for firing the selected weapon;
- Performs the collision detection for the plane's laser hitting enemy sprites;
- Opens the top and bottom borders;
- Dynamically chequerboards the colours (the best way to smoothly mix hues of diverse luminosity on the C64) on the radar display;
- Splits the screen into different zones for background colour, the two multicolours, character bank (using one of either two user-defined graphics sets available) and hi-res;
- Handles the bi-directional multispeed horizontal parallax scrolling and map-feeds, AND...
- Handles a large part of the new vertical parallax scrolling component.
However, after much "panel beating" - my term for any coding process that relies on many iterative trial-and-error sessions - I finally had to concede that the overall desired effect was not
going to happen via hardware scrolling alone; some other techniques would also be required because, very early on, it was obvious $D011's vertical hardware scroll was not going to play ball on
the other landscape layers.
For the more distant trees at low level (i.e. landscape layer 3) and for the reddish-coloured trees in the foothills (i.e. landscape layer 2), I thought that would entail multiple copies of the char data, offset vertically by one pixel in each iteration, using a fast routine - this time performed outside the game engine interrupt - to switch between the various definitions.
That worked okay (eventually) when I tried it for the low level trees, but I was out of char space for the wooded foothills.
Thankfully, the solution was staring me in the face: switch to another charset for that layer.
An Extra Charset?
Now, before you berate me for the lunacy of finding an extra 2K of RAM just for a non-critical game effect, let me explain that I am planning on doing so much more with that
It has to hold additional definitions for the foreground landscape to accommodate a major game feature, namely, the battle-damaged trees and other foreground objects that succumb to the rigours of the conflict raging above and around them.
Recall how I described this in the Parallaxian Game Concept post?
Well, this is the how to compliment the what of that game feature.
Another Technique Added
So much for the bottom 3 landscape layers; what of the not-so-small matter of vertically scrolling the distant mountains (landscape layer 1)?
For that, I was able to use another cool C64 trick, so beloved of the demo scene (and used in the "get ready" screen of Mayhem in Monsterland).
Gentlemen, I refer, of course, to FLD.
That's Flexible Line Distance, a simple technique that keeps the VIC-II from drawing what it's "supposed" to on-screen until the next raster line (or however many raster lines down the screen you want to delay the rendering process).
In Parallaxian, this is executed within the very first raster interrupt handler, way up above the visible part of the screen, and it affects landscape layers 1 (the mountains) and 2 (the wooded foothills).
So in actuality, the wooded foothills use two methods for their vertical scrolling: FLD + character bank switching.
Summary of the Methodologies
So, to recap, we now have 4 different techniques at play here:
- $D011 hardware scroll on the foreground layer (aka layer 4);
- User-defined graphics definition rotation on the distant low level trees layer (aka layer 3);
- Charset definition change via bank switching on the forested foothills layer (aka layer 2);
- FLD scroll on the distant mountains (aka layer 1) AND on layer 2.
A Little Problem: Those Non-Standard Colours
Remember in the Luma-Driven Graphics article how I said that when using ALM (the Alternating Line Method) to attain non-standard colours, the resultant new colour will exhibit
a bias in favour of the first constituent standard colour in the alternating lines?
Well, by vertically scrolling any screen region occupied by ALM, you inadvertently trigger an eye-jarring effect caused by this bias.
That meant, for example, the murky green of the grass behind the foreground trees was alternating between a much more pinkish green and said murky green with each vertical pixel the foreground scrolled.
Of course, the solution was to switch char banks with every vertical pixel scrolled, to maintain the integrity of the non-standard colours, which is what I ended up doing.
Laborious, fiddly, frustrating but utterly necessary to the final effect because, as I have said before, we're going for finesse here, something to make the game more "16-bit", so the inconvenience of the matter doesn't come into the equation.
Major Update: 22nd April 2020
With the recent Level 2 design preview, the entire vertical parallax system was rewritten almost from scratch to double its vertical range, so it now has 16 raster lines of travel in the foreground
as opposed to its previous 8.
This rewrite means a lot more FLD is now used than was the case up until this point... Hopefully a new article will expand on this, if I get the time to actually write it as I'm busy with Level 3 as I type these words!
Anyway, if you haven't yet seen the new and improved vertical parallax effect, it's in the video clip below:
Help Make Parallaxian Happen!
...and get special perks!
Progress on Parallaxian has slowed down since summer 2021 for several reasons, one of which has been the very low level of support from
the C64 scene which has made it difficult to continue justifying to my family the long hours of hard work a project as complex as this requires.
Now, I understand these are difficult times and I admit I am not entitled to any support at all, but it really does encourage me to continue developing this sensational game when you make a regular Paypal donation.
And as a special thank you, all who do this can enjoy the following perks:
- Your name credited in the game (unless you opt out of it if you have the same kind of incognito hermit tendencies I do).
- Access to the ongoing beta-testing of the game (unless you would prefer not to see it before its release date).
- The finished game on media (e.g. cartridge) for FREE one week before its release.