The parallax effect




Nah, its just sprites. Ok —Nothing special😊


Background

Proper fullscreen parallax effect, for more than starfields on the MSX, has been a challenge lying the back of my head for a good while. When pondering about how to do Go Figure, it did strike me that the original game's background was very simplistic, and there had to be a way to create an illusion of this?

Well, it ended up as a lot of workjust for a small effect that you get for free on other systens. I think maybe two months passed before it was working. Would a sane person go about doing all this?

It is really, yet another PoC.

The core idea

  • The effect is built using sprites.
  • As sprites always are placed on top of the background, the sprite patterns will have the level's background tiles masked away, giving the illusion that the sprite is behind the tiles.
  • The number of variations in sprite appearance would be quite large.
    • We will use ROM files with ROM mappers for storage.
    • Constant update of VRAM sprite sprite definitions is needed.
  • Once a sprite is moved out on the left side of the screen, it reappears on the right side again.
  • The game's fit for this kind of solution would be perfect as the amount of sprites used elsewhere in the game is really small.

Challenges with this approach

Structure - clunky and limited:
  • An MSX sprite is a 8x8 pattern, which can be combined into 16x16
  • Colorwise, this 16x16 pattern can have one color per line, so 16 different vertically, but only 1 horizontally.
  • The Sprite Pattern Table (PAT) has 256 8x8 entries or 64 16x16 entries.
  • In the Sprite Attribute Table (SAT), we can only have only 32 sprites on screen at a time, and only 8 on a row, and some are used from the game mechanics already.
VRAM performance - writes are generally slow:
  • To have one of the 32 sprites change to another pattern (the pattern number in the SAT: SATpn) is fast as it is only one byte.
  • Updating the colors on a sprite is slow as it is 16 bytes per sprite.
  • Updating a pattern in the pattern table is slow (32 bytes per pattern).
This gives us some directions:
  • We need to place out sprites in smart way.
  • We need to find a way to limit the VRAM writes to a minimum.
  • Aestetically, with these primitives, how to make something convincing? We need to do some tradeoffs.
  • Doing masking at runtime for most of the SAT on a poor Z80 and a slow VDP would be an insane challenge, so this idea is discarded from the outset.

Solution ends up as

  • The sprite pattern (SATpn and/or PAT) is updated for each sprite every frame.
  • Sprite colors are shared and static - no updates needed here.
  • The game moves in one direction, one static path: Any update will be the diff from previous frame.
  • Consists of 2 major parts: The masker tool and the in-game runtime parallax code.
  • Runs at 60 FPS.
  • The speed is one pixel per frame or 50% of the foreground.
  • Optimized for low cpu cycle costs. Frame peak cycle costs comes in the range 5000 - 9000 cycles depending on the level complexity. Average is much lower.
  • Data size examples:
    • Level 5, Retrospective: 123 kB / 8 segments (norm)
    • Level 10, Blackout: 247 kB / 16 segments (highest)
  • Some chosen representations:

Benefitting from these technical features

  • Sprites - SAT (Sprite Attribution Table).
  • Sprites - PAT (Sprite Patterns).
  • Sprite size - 16x16 sprites.
  • Sprite mode 2 (up to 8 sprites per line).
  • We use multiple PATs.
  • 64 kB VRAM used for parallax sprite patterns alone.
  • Line interrupt (R#19) mid screen for PAT-split.
  • Using the EC-bit for clean sprite border-masking.
  • ROM segments to store multiple pages with SAT, PAT, and streams with changes.
  • 16 kB segments from the ASCII mapper.
  • The sprite data is precalculated using a custom tool written in python.
  • Notably, patterns are not compressed due to performance concerns, but efforts are put into storing as little data as possible.

How it is done

  • A specific design for the sprite behaviour is set up.
  • The masker tool creates the data needed according to the design.
  • In-game data consumption and rendering at runtime.

Continue your reading via the links in the footer below.


The parallax effect  |  Design of the system  |  The masker tool  |  In-game data consumption and rendering

Comments