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 work—just 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.
- 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
Post a Comment