How to best handle big spritesets ?

Par Metalion

Paragon (1622)

Portrait de Metalion

20-12-2018, 12:52

Hello,

I'm working on a game in screen5 that will use a lot of sprite patterns : up to 256. They are mainly used for animation of the main character. And I'm wondering what is the best solution to handle them :

. Option A : Store them in VRAM and use HMMM to copy the patterns and colors in the SPT/SCT on the fly.

. Option B : Create different SPT/SCT and switch to a given SPT/SCT on the fly. The downside of that solution is that the SPT/SCT must store other useful sprites which may not change, and therefore I loose valuable space in VRAM duplicating parts of the SPT/SCT.

. Option C : Store them in RAM and copy them in VRAM to the SPT/SCT on the fly. I have put this option for discussion only, as I'm not sure it's a workable solution.

Is there any other option ?
What are your thoughts ?

!login ou Inscrivez-vous pour poster

Par Grauw

Ascended (10699)

Portrait de Grauw

20-12-2018, 13:51

All three are good solutions. It depends on your situation.

  • Option A is most practical if you combine it with a double buffered SPT, then you don’t need to time the copy exactly in the vertical blank, which can be difficult if other commands are executing as well. You can usually also do with YMMM. If you want to keep the number of copies down, which I’d recommend, it puts some constraints on the alignment of the patterns; groups of 4 in screen 5/6, and groups of 8 in the other modes. Note this one of course isn’t possible on MSX1.
  • Option B trades off VRAM for speed. Also it's easier to time the swap during vblank so you probably don't need a double buffer. If you have multiple independent big animations that don't fit in the SPT, that's harder to do though, as you then need copies of all permutations in VRAM. And on MSX1 you don’t have much VRAM so that may be problematic.
  • Option C is good when you have plenty of CPU time, but not enough VDP command processing time and VRAM. Like option A you probably also want to double buffer the SPT for this one. Note that you can distribute the CPU cost over multiple frames (depending on your animation framerate), so it may not actually cost that much if you consider that.

The beauty is, the choice is pretty flexible to change later in the development process. If you notice you're getting a lack of VRAM, VDP or CPU processing time as you progress, you can change the strategy and free up some time or space where you need it.

I would start out with option A though. Usually there should be enough spare time to do an YMMM, and it's a bit more space and CPU-efficient. And I think on MSX1 the best (only) practical option is C really.

In my game (wip) I use option A with YMMM for the double buffered pattern table, and in parallel I use option C for the colour table. Both are updated only every other frame (30 fps animation). The attribute table is updated every frame (60 fps) for fluid movement. The SAT is double buffered so I don’t have to time updates exactly during vblank, but since the SCT has the same base address, every second frame I copy it over from the back buffer with YMMM. Pretty happy with this set-up.

Par Metalion

Paragon (1622)

Portrait de Metalion

20-12-2018, 14:26

Thanks Grauw.

I had already started to work on the option A, but I wanted to have another educated point of view to see if I was missing something. Indeed, YMMM is a better solution than HMMM, even more as my main character uses 4 sprites at a time for a each single frame of its animation, which means that with an intelligent placement of the data in VRAM (and organization of the SPT), it's just a matter of moving with YMMM a single line of 256 pixels for the SPT.

The transfer of the SCT data is a little bit trickier, as it's half a line (128 pixels) but still manageable. Using option C for the SCT (as you do) and therefore mixing the solutions is indeed interesting. I'll think about it.

As for double buffering the SPT/SCT, I think I will start without it for now. I have other things going on after VBLANK, but I will wait to see how the game works as I build it, and then I'll use double buffering if I see a drop in framerate.

Par Grauw

Ascended (10699)

Portrait de Grauw

20-12-2018, 19:32

Metalion wrote:

The transfer of the SCT data is a little bit trickier, as it's half a line (128 pixels) but still manageable.

As long as it’s aligned you could still use HMMM or even YMMM. However since the SCT is tied to the sprite priorities in practice you probably need to re-write it often, best left to the CPU since it might as well do it directly rather than spend an almost equal amount of time issueing VDP commands. Unless you can get away with fixed sprite priorities, or using the same colours for all sprites.

Metalion wrote:

As for double buffering the SPT/SCT, I think I will start without it for now. I have other things going on after VBLANK, but I will wait to see how the game works as I build it, and then I'll use double buffering if I see a drop in framerate.

Yeah I think that’s a good idea, I also didn’t have double buffering at first. I added it when I changed the game engine to run at 30 fps to free up processor time. Not only animation updates, but also input processing, collision detection and sprite sorting only happens every other display frame. For the player it still looks smooth because I calculate two motion frames for the scroll and sprite positions.

The bit of latency that the lower framerate and double buffering introduces are not noticeable in my case (an RPG). However I can imagine it depends on the genre whether that’s suitable, e.g. for a high paced shooter which needs a lot of responsiveness it may be better to sacrifice features in order to keep the 60 fps framerate and single buffering for the lowest possible latency.