spritesort reduces spriteflicker
The result looks a lot nicer!
How much more CPU does this use than the traditional method? That might be an issue.
Also some people believe you should flicker entire characters (when they use multiple overlapping or combined sprites), that also might make things a bit more complicated.
How much more CPU does this use than the traditional method? That might be an issue.
Also some people believe you should flicker entire characters (when they use multiple overlapping or combined sprites), that also might make things a bit more complicated.
Thanks for sharing !
Could you give more details or overview of the sorting ?
Would you say it is a bit like in konami games where the planes are changed continiously ?
Could you give more details or overview of the sorting ?
Would you say it is a bit like in konami games where the planes are changed continiously ?
Leo, everything you need to know is in the readme.
hit9918, interesting way to make a first post. Looks like a good algorithm. The ability to use with more than 32 sprites makes it especially nice. However, you do need to have the cpu time available since it's quite a bit slow than just splitting the sprite attribute table upload into two pieces.
About the ring buffer approach. You can improve its look by choosing an offset 5 or 7. This way you will increase the repeat of the flicker pattern from 8 frames to 32 frames.
hit9918, interesting way to make a first post. Looks like a good algorithm. The ability to use with more than 32 sprites makes it especially nice. However, you do need to have the cpu time available since it's quite a bit slow than just splitting the sprite attribute table upload into two pieces.
About the ring buffer approach. You can improve its look by choosing an offset 5 or 7. This way you will increase the repeat of the flicker pattern from 8 frames to 32 frames.
Hello,
I made a spritesort that does reduce flicker!
interesting, would be nice to have the same for msx2. however there is a problem. swapping sprites priority causes also the need to move sprite attribute table for colors. each sprite is 16 bytes long. so this solution does not work so well on msx2.
I made a spritesort that does reduce flicker!
interesting, would be nice to have the same for msx2. however there is a problem. swapping sprites priority causes also the need to move sprite attribute table for colors. each sprite is 16 bytes long. so this solution does not work so well on msx2.
PingPong: That's one of those horrible pieces of design that more problems than it should. I guess they just expanded the sprite colour attribute and never thought about whether it was practical. It would have been very little trouble to make colours per sprite pattern or even make it selectable through the unused byte in the SAT. This is probably proof that the chip designers aren't normally doing much game programming.
@hit9918
Good work, the idea gives good results, but seems very CPU expensive.
There is a lighter way to rotate sprites in an optimal way: using the S0 info.
The source is here
http://msxbr-mensa.googlegroups.com/web/spriterotation.asm?gda=w9mw6UUAAAABkWRJzrBz-60xfGzM9RFduj1Ql1gTRl5ThlN5W0c8Y4omvV85r9x_capiu-AemaoQYZAtvN_G4dVzKS_oSrMLGu1iLHeqhw4ZZRj3RjJ_-A
but I posted the code in this forume some time ago too.
The idea is simple:
If the 5th sprite bit in S0 is set, its plane is in S0 too.
All you need to do is to move it (and all the seguent sprites) on top of the SAT.
In this way it (and some other sprite that was hidden in the previous frame) will appear in the next frame
eg. assume all sprites on the same lines
frame0 = 0,1,2,3,4,5,6,endsat ; here 4,5,6 are hidden
frame1 = 4,5,6,0,1,2,3,endsat ; here 4,5,6 are shown and 1,2,3 disappear
frame2 = 1,2,3,4,5,6,0,endsat ; here 1,2,3,4 are shown and 5,6,9 disappear
etc
rotation is "optimal" if the 5th sprite problem ocuurs only once
as S0 holds only the last occurrence of 5th sprite condition
anyway the CPU use is very small and the result is the same of yours (when the the 5th sprite condition occurs once)
Good work, the idea gives good results, but seems very CPU expensive.
There is a lighter way to rotate sprites in an optimal way: using the S0 info.
The source is here
http://msxbr-mensa.googlegroups.com/web/spriterotation.asm?gda=w9mw6UUAAAABkWRJzrBz-60xfGzM9RFduj1Ql1gTRl5ThlN5W0c8Y4omvV85r9x_capiu-AemaoQYZAtvN_G4dVzKS_oSrMLGu1iLHeqhw4ZZRj3RjJ_-A
but I posted the code in this forume some time ago too.
The idea is simple:
If the 5th sprite bit in S0 is set, its plane is in S0 too.
All you need to do is to move it (and all the seguent sprites) on top of the SAT.
In this way it (and some other sprite that was hidden in the previous frame) will appear in the next frame
eg. assume all sprites on the same lines
frame0 = 0,1,2,3,4,5,6,endsat ; here 4,5,6 are hidden
frame1 = 4,5,6,0,1,2,3,endsat ; here 4,5,6 are shown and 1,2,3 disappear
frame2 = 1,2,3,4,5,6,0,endsat ; here 1,2,3,4 are shown and 5,6,9 disappear
etc
rotation is "optimal" if the 5th sprite problem ocuurs only once
as S0 holds only the last occurrence of 5th sprite condition
anyway the CPU use is very small and the result is the same of yours (when the the 5th sprite condition occurs once)
The result looks a lot nicer!
How much more CPU does this use than the traditional method? That might be an issue.
The "konami attack cascade" sketch takes something like 32 rasterlines.
I noticed that the typical C64 multiplexor game got always MAX 5 sprites
per scanline: 8 sprites hardware, 3 sprites reserved for player, shield, bullet.
And the top enemy row of the 9918 spritesort sketch got 6 colored sprites,
so it goes beyond C64
Also some people believe you should flicker entire characters (when they use multiple overlapping or combined sprites), that also might make things a bit more complicated.
oh, I have not thought about that! it is nicer when the whole character is flickering instead of parts.
it would need another byte in the struct to store chain info.
but the required checks might slow the engine much.
How much more CPU does this use than the traditional method? That might be an issue.
The "konami attack cascade" sketch takes something like 32 rasterlines.
I noticed that the typical C64 multiplexor game got always MAX 5 sprites
per scanline: 8 sprites hardware, 3 sprites reserved for player, shield, bullet.
And the top enemy row of the 9918 spritesort sketch got 6 colored sprites,
so it goes beyond C64

Also some people believe you should flicker entire characters (when they use multiple overlapping or combined sprites), that also might make things a bit more complicated.
oh, I have not thought about that! it is nicer when the whole character is flickering instead of parts.
it would need another byte in the struct to store chain info.
but the required checks might slow the engine much.
Leo, everything you need to know is in the readme.
hit9918, interesting way to make a first post. Looks like a good algorithm. The ability to use with more than 32 sprites makes it especially nice.
Thank you! The demo can be hacked easy by fiddeling the BASIC code,
maybe you want to play a bit with the sketch:
adjust amount of sprites N=foo around line 160.
then for every sprite add DATA Y,X,C,P (it is 9918 layout order).
For example, add 12 more sprites, set N=39 (the demo was N=27).
then duplicate the first 12 data lines and add 100 to the first value in the DATA, the Y values.
now you got 39 sprites, hehe
Then you can see the top sprite row was not degraded by the action going on below.
But when you press cursor key, you can see that the top row has gotten worse
with ringbuffer, because the action below makes the ringbuffer longer and though
the flicker roundtrip longer.
btw if e.g. bluemsx set to "500% speed", then one cannot see it, need 100%
and best is 100% speed and PC Hz same as MSX Hz.
About the ring buffer approach. You can improve its look by choosing an offset 5 or 7. This way you will increase the repeat of the flicker pattern from 8 frames to 32 frames.
Have not tried these, maybe it makes the look more "organic", break up groups.
But I doubt it can do much about the worst case sprite disappearance?
32 sprites, ringbuffer start addresses per frame:
0, 7, 14, 21, 28, 35->35 AND 32 = 3, 10, ...
"3,10,..." means: display 3,4,5,6 in a frame and then 10,11,12,13 in the next frame.
(imagine 32 sprites in a row, worst scenario).
so I found a case where sprite 7,8,9 are missing in TWO roundtrips!
you got the roundtrip down to something like 5 steps, but missing
two roundtrips means a worst case of 2 * 5 = 10 frames:
so for some sprites things got even worse than
the worst case of 7 sprites per frame.
So it looks like a simple ringbuffer aproach can never go beyond the
number "the average worst case with 32 sprites is disappearing for 7 frames".
trying to change the offset from 4 will make things better for some lucky sprites,
and make things worse for some unlucky sprites.
hit9918, interesting way to make a first post. Looks like a good algorithm. The ability to use with more than 32 sprites makes it especially nice.
Thank you! The demo can be hacked easy by fiddeling the BASIC code,
maybe you want to play a bit with the sketch:
adjust amount of sprites N=foo around line 160.
then for every sprite add DATA Y,X,C,P (it is 9918 layout order).
For example, add 12 more sprites, set N=39 (the demo was N=27).
then duplicate the first 12 data lines and add 100 to the first value in the DATA, the Y values.
now you got 39 sprites, hehe

Then you can see the top sprite row was not degraded by the action going on below.
But when you press cursor key, you can see that the top row has gotten worse
with ringbuffer, because the action below makes the ringbuffer longer and though
the flicker roundtrip longer.
btw if e.g. bluemsx set to "500% speed", then one cannot see it, need 100%
and best is 100% speed and PC Hz same as MSX Hz.
About the ring buffer approach. You can improve its look by choosing an offset 5 or 7. This way you will increase the repeat of the flicker pattern from 8 frames to 32 frames.
Have not tried these, maybe it makes the look more "organic", break up groups.
But I doubt it can do much about the worst case sprite disappearance?
32 sprites, ringbuffer start addresses per frame:
0, 7, 14, 21, 28, 35->35 AND 32 = 3, 10, ...
"3,10,..." means: display 3,4,5,6 in a frame and then 10,11,12,13 in the next frame.
(imagine 32 sprites in a row, worst scenario).
so I found a case where sprite 7,8,9 are missing in TWO roundtrips!
you got the roundtrip down to something like 5 steps, but missing
two roundtrips means a worst case of 2 * 5 = 10 frames:
so for some sprites things got even worse than
the worst case of 7 sprites per frame.
So it looks like a simple ringbuffer aproach can never go beyond the
number "the average worst case with 32 sprites is disappearing for 7 frames".
trying to change the offset from 4 will make things better for some lucky sprites,
and make things worse for some unlucky sprites.
interesting, would be nice to have the same for msx2. however there is a problem. swapping sprites priority causes also the need to move sprite attribute table for colors. each sprite is 16 bytes long. so this solution does not work so well on msx2.
this sounds like the MSX2 sprite color table is not adressed same way as sprite pattern
table, by 4th byte in sprite attribute table?
@ARTRAG
@hit9918
Good work, the idea gives good results, but seems very CPU expensive.
That is the problem. In readme I mention further tradeoffs. Also maybe
the whole thing can be rewritten to snip IX IY and stuff them to the
EXX registerset.
In my first version I did not dare to trade too much accuracy.
The trade towards full speed is one scanline buffer entry is for
16 scanlines. Then spritesort only needs to touch 2 cells with
the DEC (HL) OR (HL) INC L cascade.
The idea is simple:
If the 5th sprite bit in S0 is set, its plane is in S0 too.
All you need to do is to move it (and all the seguent sprites) on top of the SAT.
In this way it (and some other sprite that was hidden in the previous frame) will appear in the next frame
rotation is "optimal" if the 5th sprite problem ocuurs only once
as S0 holds only the last occurrence of 5th sprite condition
Wow. Is this just a slight upgrade on the ringbuffer, or is it a trick that
makes spritesort unnessesary, I cannot imagine by now.
In first look, it looks like only a slight upgrade to the ringbuffer method.
On a second look however it does attack the problems where they are happening,
which was my goal.
It is not ideal, on the other hand it does attack the next problem right next frame
without the usual roundtrip time. I got to look into this.
@hit9918
Good work, the idea gives good results, but seems very CPU expensive.
That is the problem. In readme I mention further tradeoffs. Also maybe
the whole thing can be rewritten to snip IX IY and stuff them to the
EXX registerset.
In my first version I did not dare to trade too much accuracy.
The trade towards full speed is one scanline buffer entry is for
16 scanlines. Then spritesort only needs to touch 2 cells with
the DEC (HL) OR (HL) INC L cascade.
The idea is simple:
If the 5th sprite bit in S0 is set, its plane is in S0 too.
All you need to do is to move it (and all the seguent sprites) on top of the SAT.
In this way it (and some other sprite that was hidden in the previous frame) will appear in the next frame
rotation is "optimal" if the 5th sprite problem ocuurs only once
as S0 holds only the last occurrence of 5th sprite condition
Wow. Is this just a slight upgrade on the ringbuffer, or is it a trick that
makes spritesort unnessesary, I cannot imagine by now.
In first look, it looks like only a slight upgrade to the ringbuffer method.
On a second look however it does attack the problems where they are happening,
which was my goal.
It is not ideal, on the other hand it does attack the next problem right next frame
without the usual roundtrip time. I got to look into this.

By hit9918
Champion (432)
07-03-2010, 01:33