drawPlusMask artifacts, frequent bricking after upload

And, yes. That .hex is WITH artifacts.

The advanced drawing features use memory registers directly. @MLXXXp or @Dreamer3 is this related to the glitches we saw before with this function?

The issue with it bricking is certainly related we’ve seen it happen elsewhere and it’s related to the use of ram which is overriding the “magic number” that is a bit flipped in ram that lets the bootloader know it’s been activated.

This is some what of a mysterious bug that’s effecting “advanced” users that seems to involve when you hit around 70% ram usage.

1 Like

I’ve uploaded it to my official Arduboy now too and still see no artifacts.

What I see is a little ship with an little afterburner in a flashing circle. when I move it zig zagging around all looks smootly. sometimes I see a pixel or two moving along inside the circle. but those are starfield pixels to me as when I stop moving the ship the pixel moves along to the left as starfield pixels do.

Is you’re Arduboy fully charged or powered by USB power? I can imagine Arduboy may start behave oodly when the battery is (almost) fully drained

@Mr.Blinky Yes fully charged and powered by USB.

@bateske Would this issue manifest differently on different Arduboys? @Mr.Blinky isn’t seeing the artifacts using the same .hex on his device.

I just realize my Arduboy is a bit different though as it uses my custom bootloader which clears more ram (for the display buffer) then the stock bootloader. I wonder if that is related. Has anybody else tried it and seen the artifacts?

@Kevin I saw the Assembly code with the workarounds and decided not to touch it in the moment. is there any info about those glitches?

Here’s the thread that sparked the rewrite of the assembly code for drawPlusMask.

There’s a fair bit of info towards the end as well as a bit about the failed attempts and their behaviours.

@alivesay What version of the Arduboy2 library are you using?

And what do the artefacts look like?


Could this have anything to do with the lock bits being set incorrectly on production Arduboys and that @Mr.Blinky reflashed a bootloader with the bits locked correctly?

1 Like

No, Lock bits don’t have an influence.

@Pharap I’m using Arduboy2 4.1.0. Have also tried with 4.0.2 and 4.0.1. Here’s what the artifacts look like (under the ship):


Is the right of the screen meant to look like that or is it an artifact too?

The rest of the screen is fine. The trails/ghosting are just from the photo.

1 Like

So is it the large blob of white beneath the ship?

Correct. The artifacts only appear in the “dead space” of the bitmap (height is 16).

If I move the ship (changing the x/y values of drawPlusMask(x,y)) the artifacts change.

It mostly appears random but at some locations the artifacts are actually a mirror of the ship sprite itself.

1 Like

Have you checked the defined size of the sprites in the Progmem section

Did you use a png converter?

They appear correct to me: https://github.com/alivesay/starfire/blob/master/starfire-game/sprites.h

That was generated using the TeamARG tool on their site.

1 Like

Try using an external mask and see if that works

its a 16x16 sprite correct?

Not a bad idea to try using an external mask, however since calling the base class member function noop() resolves the issue I’m thinking there is just something fishy going on with the assembly routines in drawBitmap()… which will still be called by drawExternalMask().

Sprite frames are 13x16. Issue happens when I use a different sprite that’s 8x8.

1 Like

In the call of .drawExternalmask it doesn’t to my knowledge use the assembly code in drawbitmap

  204     case SPRITE_MASKED:
  205       uint8_t *mask_ofs;
  206       mask_ofs = (uint8_t *)mask + (start_h * w) + xOffset;
  207       for (uint8_t a = 0; a < loop_h; a++) {
  208         for (uint8_t iCol = 0; iCol < rendered_width; iCol++) {
  209           // NOTE: you might think in the yOffset==0 case that this results
  210           // in more effort, but in all my testing the compiler was forcing
  211           // 16-bit math to happen here anyways, so this isn't actually
  212           // compiling to more code than it otherwise would. If the offset
  213           // is 0 the high part of the word will just never be used.
  215           // load data and bit shift
  216           // mask needs to be bit flipped
  217           mask_data = ~(pgm_read_byte(mask_ofs) * mul_amt);
  218           bitmap_data = pgm_read_byte(bofs) * mul_amt;
  220           if (sRow >= 0) {
  221             data = Arduboy2Base::sBuffer[ofs];
  222             data &= (uint8_t)(mask_data);
  223             data |= (uint8_t)(bitmap_data);
  224             Arduboy2Base::sBuffer[ofs] = data;
  225           }
  226           if (yOffset != 0 && sRow < 7) {
  227             data = Arduboy2Base::sBuffer[ofs + WIDTH];
  228             data &= (*((unsigned char *) (&mask_data) + 1));
  229             data |= (*((unsigned char *) (&bitmap_data) + 1));
  230             Arduboy2Base::sBuffer[ofs + WIDTH] = data;
  231           }
  232           ofs++;
  233           mask_ofs++;
  234           bofs++;
  235         }
  236         sRow++;
  237         bofs += w - rendered_width;
  238         mask_ofs += w - rendered_width;
  239         ofs += WIDTH - rendered_width;
  240       }
  241       break;

Ah, okay. Do you know of a tool that will generate for use with drawExternalMask?

1 Like

I think @pharap Has one

1 Like