Sprites under work

I am implementing sprites, at first for the 220x176x2bpp mode. A sprite is basically an own, usually a small size, “screen buffer” with an own palette, and it is layered over the normal screen buffer. There can be many of them. I have now sprites working on HW and under Simulator, but I still have to work on performance. I am not yet sure if they are fast enough to be usable.

6 Likes

how is this different from directBitmap()?
also the simulator is not very accurate things that flicker on hardware don’t in the simulator for custom graphics

The directBitmap draws immediately to the LCD. Sprite is drawn only when Display::Update() is called. If you draw like this with directBitmap:

  1. Display::Update() ==> Draws to LCD
  2. directBitmap() ==> Draws to LCD

Then some of the LCD pixels are drawn twice, which causes flicker.

With the sprite, the normal screen buffer scanlines and sprite scanlines are combined, and the result scanlines are drawn to LCD once => no flicker.

2 Likes

hang on how are you not using a the buffer then?
and you still in 2bpp mode?

Which buffer you mean? I am using the 2bpp screen buffer for background and other graphics. Sprites are layered above them.
Currently, the sprite must also be 2bpp to keep the implementation simple. The biggest challenge is to get drawing optimized for speed.

1 Like

whats the limitation then? they cant overlap or something?

it just sounds like a second buffer to me

There are no special limitations, sprites can overlap each other.
Yes, they are like extra buffers. The trick is that they (screen buffer & sprite buffers) are combined in Update() by scanline level to LCD, which means:

  1. the screen buffer is untouched, i.e. it does not contain sprite data, and
  2. sprites can add more colors to LCD as they have own palettes.
2 Likes

oh ok its a scanline buffer, why not like directBitmap the scanline so you have a full pallet
you could even swap pallet per scanline for effects

and not even bother with the background layer and just press everything into sprites

In other words it’ll be something like this:

class Sprite
{
public:
  uint8_t x, y, width, height;
  uint8_t paletteIndex; // Colour palette number
  uint8_t * data; // Colour data
};

And there will be a list of those, and then on each update the code goes through the list and direct-draws them all at once. Pixels aren’t buffered at any point, there are no ‘scanlines’, the whole screen is represented as a list of sprites - just like old-fashioned hardware sprites.

Right @Hanski?

That is almost a duplicate of my SpriteInfo struct :slight_smile:

1 Like

so are you putting the sprites is a list (vector) of some sort and then look in reverse order wich sprite is drawn last on this coordinate?

its allot of checking per pixel and is probebly realy slow

That is more about the definition of “sprite”. You could call the background screen buffer a full screen sprite. Also, to add more generalization, you could direct the buffer drawing primitives to any sprite buffer :wink:

The common thing with all sprites is the need for the scanline combiner, before writing to LCD, to avoid flicker. And yes, the combiner would become very slow very easily. I probably must limit the number and size of sprites radically, if at all possible with a good performance. But that is the fun part: try to get this to work fast :wink:

1 Like

i been looking around for solutions and what do you think of an adaptive tile refresh like method?

Do you mean solutions for scrolling tiles?

yes, basically reducing the amount of stuff to refresh on screen

I think if you’re intending to draw the sprites to a scanline buffer or in order from top left to bottom right you’ll ideally want some kind of sorted data structure to keep the sprites ordered (by y first, then x).

1 Like

using a vector would help and having functions to push it to the back or to the front

having to pass a sort every time a new sprite instance pops up could slow down stuff even more, theres just to much going on imo

About scrolling: If you use direct drawing mode, maybe it is possible to set visible screen width in LCD to a bit less than 220 pixels, say 212 pixels? And then use LCD HW scrolling. Then you should only draw 8x176 rect on LCD each frame :slight_smile:

it doesn’t work like that, to explain hw scrolling the easiest it sets the starting index of the screen buffer
you cant disable the sides of the screen to not draw the buffer
you just have to deal with the edge flickering i guess

unless the screen buffer on the display chip is larger then the screen

How about this?

  • In the ST7775R spec: "9.2.21 Horizontal and Vertical RAM Address Position (R36h, R37h, R38h, R39h) "

To me it looks like you can set the visible window(?)