How to duplicate sprites using VRAM tiles once?

SGDK only sub forum

Moderator: Stef

Post Reply
masteries
Very interested
Posts: 53
Joined: Thu Jul 30, 2020 3:33 pm

How to duplicate sprites using VRAM tiles once?

Post by masteries » Wed Sep 28, 2022 8:57 am

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.
Last edited by masteries on Sun Oct 09, 2022 11:56 am, edited 1 time in total.

masteries
Very interested
Posts: 53
Joined: Thu Jul 30, 2020 3:33 pm

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

Post by masteries » Fri Sep 30, 2022 12:15 pm

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.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: How to duplicate sprites using VRAM tiles once?

Post by Stef » 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.

masteries
Very interested
Posts: 53
Joined: Thu Jul 30, 2020 3:33 pm

Re: How to duplicate sprites using VRAM tiles once?

Post by masteries » Mon Oct 10, 2022 3:33 pm

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!

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: How to duplicate sprites using VRAM tiles once?

Post by Stef » Tue Oct 11, 2022 7:12 am

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.

masteries
Very interested
Posts: 53
Joined: Thu Jul 30, 2020 3:33 pm

Re: How to duplicate sprites using VRAM tiles once?

Post by masteries » Tue Oct 11, 2022 11:11 am

Thanks for the code sample, now it is clear!

This solution will be applied for debris and explosions.

Post Reply