Sprites::drawOverwrite draws black overhang below sprite

I was under the impresion that Sprites::drawOverwrite would cut off any vertical excess because it’s provided with a height.

It doesn’t seem to be doing that though, instead I’m getting black excess/overhang.

1 Like

Sounds like a bug to me but I didn’t write the code for the Sprites classes, so I can’t say for sure what the intended behaviour should be.

Does using SpritesB behave the same?

Yes.


I didn’t get chance to write one before, so here is a demo program.
It fills the screen with white and then draws a bitmap of a black circle on a white background.
The black overhang is clearly visible below the circle.
It behaves the same with both Sprites and SpritesB.

#include <Arduboy2.h>

constexpr uint8_t ACircleWidth = 28;
constexpr uint8_t ACircleHeight = 28;

uint8_t const ACircle[] PROGMEM =
{
	// Dimensions
	ACircleWidth, ACircleHeight,

	// Frame 0 - ACircle
	0xFF, 0xFF, 0x3F, 0xDF, 0xEF, 0xF7, 0xFB, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFB, 0xFB, 0xF7, 0xEF, 0xDF, 0x3F, 0xFF, 0xFF,
	0x07, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07,
	0xFC, 0xF3, 0xCF, 0xBF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xCF, 0xF1, 0xFE,
	0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0D, 0x0D, 0x0B, 0x0B, 0x0B, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0B, 0x0B, 0x0B, 0x0D, 0x0D, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
};

Arduboy2 arduboy;

void setup(void)
{
	arduboy.begin();
}

void loop(void)
{
	if(!arduboy.nextFrame())
		return;
	
	// Fill screen with white
	arduboy.fillScreen(WHITE);
	
	// drawOverwrite
	Sprites::drawOverwrite(32, 16, ACircle, 0);
	
	// Display
	arduboy.display();
}

Doesn’t the height have to be multiple of 8?

EDIT:

https://mlxxxp.github.io/documents/Arduino/libraries/Arduboy2/Doxygen/html/classSprites.html#details

The height must be a multiple of 8 pixels

I thought the code had got past that limitation at some point.
Evidently I imagined that.

It’s certainly solvable, it just means doing a bit of masking on the last byte of each column.

Yes, now that I think about it, I think I wrote for the Arduboy2 Sprites documentation:

The height must be a multiple of 8 pixels, but with proper masking, a sprite of any height can be created.

after analysing the code and discovering that was the case.

Otherwise, there would have to be additional masking operations performed, for every Sprites draw function, whenever the height wasn’t an even multiple of 8 pixels.

Edit:
However, the Y axis location for a sprite doesn’t have to start on a even byte, so there must be some masking going on to handle that. Perhaps by modifying that code, any height could be handled with not much more code overhead. :thinking:

1 Like

When this issue came up and the possibility of updating the drawing methods is being discussed, I’d like to mention what I’ve just recently talked about to @Pharap:

I think it would be extremely useful to have the possibility (optional parameter) to transform (flip horizontal/vertical, rotate 90 degrees, …) the sprite when drawing. Because typically in e.g. platformers you have sprites facing left and right for all characters. Just the possibility of horizontal flip would be a matter of doing --x instead of ++x in the drawing loop and would reduce the number of character bitmaps needed to store in progmem to half. These symmetries are almost everywhere and their exploitation used to be very common on the old consoles with limited memory.

I added horizontal flipping to the drawCompressed() function in a subclass of the Arduboy2 library, here>

Also, I understand the ArdBitmap library can do flipping but I have never used it.

1 Like

That’s pretty much the same answer I gave @drummyfish :P


Perhaps it would be better to suggest this in a separate thread or a GitHub issue?
Otherwise things might get confusing if we’re discussing two unrelated issues (a feature and (arguably) a bug).