Recently I've changed my boing boing routine so I could have multiple of them on screen for harder levels and during this, I've stumbled on a rather obvious issue:
The conclusion was also very obvious - I needed to implement sorting by Y position as C64 have predefined sprites priority - sprites with lower index always display on the front of others. So what I needed to do is get around of C64 sprite handling by using my own structure to hold sprite information (position, frame, color, etc.), sort this structure and after that put the info in hardware sprites in the right order.
This also opens the possibility to render more than 8 sprites by using the technique used by many old C64 games - f.e. Green Beret. In C64 you can use interrupts and synchronize with VIC raster lines right when it starts or ends drawing them. When you wait for one sprite to end drawing you can change its position to the lower area. There were two techniques used for this - Zone Split and the one that suited me best - sorting.
The whole process looks like this:
It's all looking quite smart and simple but there is one catch - TIMING. You need to do all operations in sync with VIC and be aware that there are "only" 63 cycles of CPU for each raster line that you can spend on sorting and repositioning of the sprites and setting up proper graphics, color and stretching (sprites can be individually stretched in X and/or Y).
Here's example of first failed attempt that I will try to describe:
The border color shows when separate functions start and end in sync with VIC while it draws the screen and sprites:
- RED means the "main" procedure with one loop that updates sprites positions in my structure - it starts at raster line number 250 (lower border) just after the previous frame was drawn - as you can see it takes some time even bleeding into the next frame (top of the screen)
- WHITE means sorting - simple bubble sort and not even properly working
- GREEN - setting up sprites, waiting for them to finish drawing, etc. - as you can see it doesn't even start on the top border so top sprites simply don't have time to be properly set up on the screen
After that, I've changed my sorting technique to not try the entire sorting at once but simply do one step per frame. There are 50 frames on PAL machines so I can do plenty of comparisons even in simple bubble sort, traverse entire structure a few times per second and, hopefully, the player won't even notice short situations when sprite that is higher is drawn on top of the one that is lower.
As you can see the sorting routine (white) doesn't take much time now (the green/blue blinking means swapping was needed due to the comparison). Also, you can notice nice sorting as the sprites that are on the top are shown below those in the bottom.
One more time without the blinking and 4 extra sprites:
All that is left now to do is implement this technique into the game and try to optimize it further as currently 16 sprites limit is my max but I read about 30 sprites in some games :O. There are some things that I could write in a different manner but for now, I am quite happy with the result as I don't even write it using assembler but trusty Turbo Rascal
.