gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Graphics > Rot/Scale Sprite Cycles

#118750 - kusma - Fri Feb 16, 2007 12:03 pm

I'm working on some code that require quite heavy rot/scale sprite-usage. I did some initial calculations on what I'd be able to display before I started implementing the routine, and found out I was pretty safe. Now, after implementing the routine this does not seem to be correct at all! ;)

What I'm suspecting is that I misunderstood the Gbatek documentation. I assumed that the cost per sprite per scanline was 10 + 2 * w, where w is the width of the sprite after scaling. Quick estimates reveal that I start loosing sprite pixels when i hit about 10 + 2 * w, where w is the width of the sprite BEFORE scaling. Can anyone verify this? If so, there's some optimizations I can do to get back on track...

What I have is a boat-load of 64x64 sprites, scaled downwards within the range 64x64 to ~16x16. My optimization would be creating pre-downscaled versions of the sprite, but it's a bit of work since the sprite tiles are drawn on the fly. Ohwell, if I can display more sprites due to not having to pay the penalty for empty borders, it should pay off.

#118773 - Ant6n - Fri Feb 16, 2007 5:22 pm

when you rotate/scale sprites, they are still 'drawn' within the same borders as nonrotated ones as far as i can see. One indication is that the coordinates are still the same, and the sprite is just rotated/scaled within the 'box' of the nonrotated version. Notice also that there is the double size flag which makes a box twice as big as the original sprite to display the scaled/rotated version bigger. (I hope I am getting this right)
It would probably be easiest to downscale, which can also be done on the fly. Especially if you display 64x64 sprites as 16x16 ones. I would suggest downsampling in the y-direction, i.e. 64x64->64x32, because that shouldnt use too much cpu, and might already be enough.
If you draw sprites 'on the fly', why dont you write your on the fly drawing routine to be able to draw different resolutions?

#118775 - kusma - Fri Feb 16, 2007 5:28 pm

Ant6n wrote:
If you draw sprites 'on the fly', why dont you write your on the fly drawing routine to be able to draw different resolutions?


That's the plan, but I'm already quite pressured on cpu-cycles. The sprites are redrawn every frame. However, a full downscale-set (down to 1x1) only means 133% of the dataset, so I guess it's not a total disaster. Another issue is of course the size of the tile-set, but yeah, the same applies there.

#118777 - Ant6n - Fri Feb 16, 2007 5:37 pm

if sprites being 64x32 would already be enough why not do that; here you'd besicly copy every second scanline of two tiles that sit above each other into one. it could propably done pretty fast because you could load one tile-scanline into 1 or two registers and just push it back at the right spot; the ordering should be a little mess but prob not so bad. the whole thing could also be done inplace.
with a 'set' supporting only 64x64 and 32x32 you'd have 125% of the 'original' data and time. how bad is your problem, i.e. how many sprites do you loose per line?

#118779 - kusma - Fri Feb 16, 2007 5:50 pm

Ant6n wrote:
if sprites being 64x32 would already be enough why not do that; here you'd besicly copy every second scanline of two tiles that sit above each other into one. it could propably done pretty fast because you could load one tile-scanline into 1 or two registers and just push it back at the right spot; the ordering should be a little mess but prob not so bad. the whole thing could also be done inplace.
with a 'set' supporting only 64x64 and 32x32 you'd have 125% of the 'original' data and time. how bad is your problem, i.e. how many sprites do you loose per line?


Ah, reducing the height is pretty much for free, since the tiles are already there. Good ide, i didn't think of that! :)

Edit: Uhm, no, damn. I already use all the rot/scale parameter sets, and that would require me to reduce my scaling precision, I guess. Back to the drawing-board.

#118781 - kusma - Fri Feb 16, 2007 5:57 pm

Ant6n wrote:
how bad is your problem, i.e. how many sprites do you loose per line?


Well, it's not like I'm loosing any sprites, it's more that I want to be able to extend the range of my effect ;)

So I'll basically end up doing all the not-too-difficult optimizations I can think of and that are within my cpu-budget.

#118782 - Ant6n - Fri Feb 16, 2007 6:01 pm

you can get more than 32 rotated,scaled sprites by updating the scaling parameters during hblank; as far as I know (calculated) about half of the OAM can by redrawn with hdma. So, if you dont use more than 64 sprites in strips of N pixels height, you could separate your screen into strips of N pixels, and create a oam-shadow for every strip; which you copy at the beginning of it becoming visible. (could also do that for 128 sprites, but its harder, or only update all 32 paramters during hblank which should be possible).
what are you doing with that, anyway?

#118785 - kusma - Fri Feb 16, 2007 6:33 pm

Ant6n wrote:
you can get more than 32 rotated,scaled sprites by updating the scaling parameters during hblank;


Don't I need the Hblank interval free bit set to do that? In that case, it makes me loose sprite cycles again ;)

Ant6n wrote:
as far as I know (calculated) about half of the OAM can by redrawn with hdma. So, if you dont use more than 64 sprites in strips of N pixels height, you could separate your screen into strips of N pixels, and create a oam-shadow for every strip; which you copy at the beginning of it becoming visible. (could also do that for 128 sprites, but its harder, or only update all 32 paramters during hblank which should be possible).

I would prefer not having to multiplex, because I don't have the sprites sorted by y-order. Yes, sorting them isn't that tricky, but I'd prefer not. So I'm currently looking at making down-scaled versions. I think I've got all the info I was looking for now though. Thanks a lot :)

Ant6n wrote:
what are you doing with that, anyway?

I don't want to reveal the effect, because it's for an upcoming demo ;)

#122731 - Master S - Wed Mar 21, 2007 4:13 pm

Hehe, looking forward to BP ;-)

#122742 - kusma - Wed Mar 21, 2007 5:18 pm

Master S wrote:
Hehe, looking forward to BP ;-)

You should.

#122745 - sgeos - Wed Mar 21, 2007 5:43 pm

This is the timing for rot/scale sprites:
Code:
10 + 2 * w

There is no before/after scaling. The sprite has one size that you register with hardware. If you use size double, the width is twice are large. If I recall correctly, OBJ window sprites count toward this limit.

I compiled this table, it may be a little cryptic:
Code:
   Size   !HFree   HFree   Remainder
---
Cycles per Line
..   ...   1210   954     0
---
Normal Sprites
 8     8    119   151     2
16    16     59    75    10
32    32     29    37    26
64    64     14    18    58
---
Rotated Sprites
 8    26     36    46    18/ 14
16    42     22    28    30/ 34
32    74     12    16    66/ 26
64   138      6     8   126/106
---
Size Double Sprites
 8    42     22    28    30/ 34
16    74     12    16    66/ 26
32   138      6     8   126/106
64   266      3     4   156/146

-16 pixel wide rot/scale sprite exampe- (works for 8 pixel wide rot/scale size double as well)
Timing: 42
Max per line: 22 or 28
Remaing cycles if max sprites are on one line: 30 or 43

-Brendan

#122761 - kusma - Wed Mar 21, 2007 10:31 pm

the issue has been resolved a long time ago, but thanks for the effort anyway.

#122798 - Ant6n - Thu Mar 22, 2007 7:15 am

soo, is there going to be a demo with some sprite effect?