Page 1 of 1

How to duplicate sprites using VRAM tiles once?

Posted: Wed Sep 28, 2022 8:57 am
by masteries
Let me explain, using some images:

Image


Currently, we are searching for a way to create composed animated sprites,
where the second, third and fourth sprite use the graphical
data from the first sprite, using the same VRAM tiles, but
horizontally mirrored, vertically mirrored and hor. and vert. mirrored.

In order to save precious VRAM and reduce needed bandwidth
(currently there are many animated sprites at once,
while many of the explosion effects can be reduced
to a single quarter, in terms of number of tiles and DMA bandwidth).


The result we are searching is this:

Image


As you can see, your huge explosion,
can be decomposed into 4 parts,
being actually the first sprite the unique
that updates its tiles through the DMA.

Re: How to generate Horizontal & Vertical mirrored based sprites from a "father" sprite?

Posted: Fri Sep 30, 2022 12:15 pm
by masteries
The question can be simplified as:


How to share the graphical data for a set of sprites?

Where only one of the sprites update its tiles, and other ones only perform some flag changes, such H mirror and so on.

Re: How to duplicate sprites using VRAM tiles once?

Posted: Mon Oct 10, 2022 9:16 am
by Stef
You can do that by using

Code: Select all

SPR_setVRAMTileIndex(..)
so you define where the sprite tiles are located in VRAM.
You have this function

Code: Select all

SPR_loadAllFrames(..)
function which load all frames of a SpriteDefinition so you can easily share the tile indexes along several sprites then. The sonic sample show an usage example of SPR_loadAllFrames(..)
For your explosion i think the simplest is just to cut your big sprite in 4 small sprites and use

Code: Select all

SPR_setHFlip(..) / SPR_setVFlip(..)
with some offsets on position to build up your final sprite.

Re: How to duplicate sprites using VRAM tiles once?

Posted: Mon Oct 10, 2022 3:33 pm
by masteries
Stef wrote:
Mon Oct 10, 2022 9:16 am
You can do that by using

Code: Select all

SPR_setVRAMTileIndex(..)
so you define where the sprite tiles are located in VRAM.
You have this function

Code: Select all

SPR_loadAllFrames(..)
function which load all frames of a SpriteDefinition so you can easily share the tile indexes along several sprites then. The sonic sample show an usage example of SPR_loadAllFrames(..)
For your explosion i think the simplest is just to cut your big sprite in 4 small sprites and use

Code: Select all

SPR_setHFlip(..) / SPR_setVFlip(..)
with some offsets on position to build up your final sprite.

Code: Select all

SPR_loadAllFrames(..)
This couldn´t be used due to severe memory restrictions;
There is a 1000 tiles framebuffer in VRAM (some screens have more than 900 different tiles at once),
and around 700 free tiles for 20+ sprites...


If I execute this sentence:

Code: Select all

SPR_setVRAMTileIndex(entidad[aux].spr)


without this one:

Code: Select all

SPR_setAutoTileUpload(entidad[aux].spr, FALSE);

and without sharing the sprite data structure,
will the new duplicated sprites do not try to upload their tiles?



And yes, for the explosions, the idea is to spawn a single sprite that updates the animation frames (change the tiles);
and the other sprites of the composition using H-Flip and V-Flip.


I will test and report asap,

Thanks!

Re: How to duplicate sprites using VRAM tiles once?

Posted: Tue Oct 11, 2022 7:12 am
by Stef
masteries wrote:
Mon Oct 10, 2022 3:33 pm

Code: Select all

SPR_loadAllFrames(..)
This couldn´t be used due to severe memory restrictions;
There is a 1000 tiles framebuffer in VRAM (some screens have more than 900 different tiles at once),
and around 700 free tiles for 20+ sprites...


If I execute this sentence:

Code: Select all

SPR_setVRAMTileIndex(entidad[aux].spr)


without this one:

Code: Select all

SPR_setAutoTileUpload(entidad[aux].spr, FALSE);
and without sharing the sprite data structure,
will the new duplicated sprites do not try to upload their tiles?
If you can't preload all animation frame then yeah, what you need is to have kind of "master" sprite which handle the tile upload. You can use a dummy out of screen sprite with forced visibility (otherwise tile upload won't happen) to handle that, so you don't have to worry about which current visible sprite is the master one. Then all other sprites sharing the same current animation frame should be set in SPR_setAutoTileUpload(FALSE).
You can then use the SPR_setFrameChangeCallback(..) to handle special action when your master sprite change its current animation frame:

Code: Select all

SPR_setFrameChangeCallback(masterSprite, masterSpriteChanged);

...

void masterSpriteChanged(Sprite* master)
{
   u16 animInd = maser->animInd;
   u16 frameInd = maser->frameInd;
   u16 tileIndex = maser->attribut & TILE_INDEX_MASK;

   for(u16 i = 0; i < numSlave; i++)
   {
      Sprite* slave = slaveSprites[i];

      // set animation and frame
      SPR_setAnimAndFrame(slave, animInd, frameInd);
      // set tile index
      SPR_setVRAMTileIndex(slave, tileIndex);
   }
}
I think you should also set the master sprite in top priority by using SPR_setDepth(master, SPR_MIN_DEPTH) so it get updated before slaves which are then all properly updated in the same frame.
Hope that make sense for you.

Re: How to duplicate sprites using VRAM tiles once?

Posted: Tue Oct 11, 2022 11:11 am
by masteries
Thanks for the code sample, now it is clear!

This solution will be applied for debris and explosions.