Sprites under work

From what I was reading when I looked at it, if you set a window, you can’t then draw outside that window at all. So setting a window is of very little use for things like that.

2 Likes

I wouldn’t like to speculate too much without testing, but I doubt doing an O(n) sort on a list just before rendering would be ideal for performance if less than n sprites are being updated each frame.

If every sprite is being moved (e.g. in a game like asteroids) then it might be optimal to sort just before rendering, but if a reasonable number of sprites aren’t moving then it would probably be better to maintain a sorted list and then only update the ones that have moved since the last frame.

I am afraid that the sprite list will be quite short…but tough to say yet.

Phew! Finally, I got sprites to work and was able to squash remaining visual bugs. Per-pixel-optimizing is tough and takes a lot of time. Now, I am able to use 8 Hi-Res sprites over the Hi-Res screen buffer. Each sprite has own 4-color palette. So you can draw any graphics on the background, i.e. screen buffer, using the screen buffer palette, and then draw sprites over it with own colors. Much like sprites in C-64 :wink: (thought C-64 had fixed palette).

The main benefits using sprites over using the drawBitmap or directDrawBitmap functions are:

  1. Own palette for each sprite.
  2. Built-in dirty rect handling for the sprite background.
  3. Sprites are inherently flicker-free as pixels of the background screen buffer and all the sprites are combined before writing to LCD.

Performance-wise the sprites are quite fast. In preliminary testing, I ran 8 (32x16 pixel) sprites with no-dip in the throttled 16 fps on HW (there is that limit somewhere in the code…), but performance depends on sprite movement and positions as it affects to the total background area needed to draw. Scanline drawing to LCD is optimized so that only the required area is being drawn each frame.

Video coming soon…

2 Likes

Sound great! Would it be straight forward to add to other screen modes? In think the fixed number of sprites is a great idea, perhaps have the pallets match the screen mode?

The sprite code is heavily optimized for the Hi-Res screen mode so modifying it to another screen mode is not straightforward, but not particularly hard either, if you are familiar to bit blitting code. What makes it easier is that you can develop it under the simulator. The code is almost identical to HW. It is also possible to modify it so that the sprites are in different color mode than the screen buffer.

Edit: the max sprite count is a compile-time define for building for optimized number of sprites for the game.

Here is a video of the sprites system in action.

The screen buffer is in Hi-Res mode (220x176, 4 colors) and Hi-Res sprites are blitted over it. As you see in the video, the fps for one sprite is 50 and for 8 sprites between 25-16, depending heavily on where the sprites are on screen, as that affects how much of the background image must be drawn behind sprites.

As there are 8 sprites on screen in this demo the total number of colors on Hi-Res screen is: 4 + 8*3 = 28 (!). Note that 1 color is for transparency in each sprite.

8 Likes

That is awesome!

2 Likes

I’d love to see your code for this, it would be nice to add sprites to mode13 at some point.

Here it is :slight_smile: Works both under Simulator and on HW. I have also added on-screen FPS counter (that is drawn vertically for performance reasons).

Here is the binary also:
spritetest.bin (51.5 KB)

P.s. Just merged the latest PokittoLib to my repo so it is up-to-date.

1 Like

Hi

Sprites are available when my merge request is accepted for PokittoLib.

Sprite features

  • Sprites are implemented only for the Hi-Res (220x176, 4 colors) screen mode. The sprites itself are also drawn in this mode. There are no pixel size limitations for the sprites. By default the max number of sprites is 4, but that can be increased (or decreased, to optimize for speed) via the define like this:
    #define SPRITE_COUNT 8

  • Each sprite contain own 4 color palette. The color of index 0 is ignored as it is considered as transparent

  • The sprite 0 is drawn first and so it is the lowermost sprite

Usage

Using sprites is very simple. An example is in Examples/Sprites/main.cpp. You do not have to care about storing or redrawing the sprite background as the sprite moves. Normally, use game.Update(true) and game.display.persistence = 1 with sprites to keep the performance good. Use game.Update(false) only if the screen buffer (background) graphics has been changed.

  • To create sprite just call the function below. To disable sprite, just call the same function with NULL as bitmap pointer.
    setSpriteBitmap(uint8_t index, const uint8_t* bitmap, const uint16_t* palette4x16bit, int16_t x, int16_t y );

  • To move the sprite you just need the sprite index and the coordinates:
    setSpritePos(uint8_t index, int16_t x, int16_t y);

Note

  • I have also implemented automatic on-screen FPS counter for Hi-Res mode (works also without sprites). It is enabled by:
    #define PROJ_USE_FPS_COUNTER

Have fun!

6 Likes

Merged! thanks @Hanski

1 Like

Now added to online mbed team page

https://os.mbed.com/teams/Pokitto-Community-Team/code/Sprites/

1 Like

Do animated bitmaps work with this? Or would they needed to be saved as individual bitmaps swapped out?

You can create several bitmaps and swap them to create animation. There is no built-in animation support.