Fix portability issues in the Sprites classes

Issues discovered and fixes developed by @Pharap

The Sprites classes relied on the behavior of 16 bit integer arithmetic
for operations that cause an overflow; specifically (ofs + WIDTH)
calculations for an index into the screen buffer. This would cause
problems if the code was ported to an environment in which the basic
integer type (i.e. "int") is larger than 16 bits.

Also, there was code that assumed little endianness for a technique
used to retrieve the high byte a 16 bit value. This would cause
problems if the code was ported to a big endian architecture.

The changes made are strictly for the sake of improved portability and
better programming practices. They don’t affect code compiled for the
Arduboy in any way.
This commit is contained in:
Scott Allen 2020-07-18 18:56:48 -04:00
parent d7758249fa
commit 4530325412
2 changed files with 19 additions and 14 deletions

View File

@ -148,10 +148,11 @@ void Sprites::drawBitmap(int16_t x, int16_t y,
Arduboy2Base::sBuffer[ofs] = data; Arduboy2Base::sBuffer[ofs] = data;
} }
if (yOffset != 0 && sRow < 7) { if (yOffset != 0 && sRow < 7) {
data = Arduboy2Base::sBuffer[ofs + WIDTH]; const size_t index = static_cast<uint16_t>(ofs + WIDTH);
data &= (*((unsigned char *) (&mask_data) + 1)); data = Arduboy2Base::sBuffer[index];
data |= (*((unsigned char *) (&bitmap_data) + 1)); data &= (uint8_t)(mask_data >> 8);
Arduboy2Base::sBuffer[ofs + WIDTH] = data; data |= (uint8_t)(bitmap_data >> 8);
Arduboy2Base::sBuffer[index] = data;
} }
ofs++; ofs++;
bofs++; bofs++;
@ -170,7 +171,8 @@ void Sprites::drawBitmap(int16_t x, int16_t y,
Arduboy2Base::sBuffer[ofs] |= (uint8_t)(bitmap_data); Arduboy2Base::sBuffer[ofs] |= (uint8_t)(bitmap_data);
} }
if (yOffset != 0 && sRow < 7) { if (yOffset != 0 && sRow < 7) {
Arduboy2Base::sBuffer[ofs + WIDTH] |= (*((unsigned char *) (&bitmap_data) + 1)); const size_t index = static_cast<uint16_t>(ofs + WIDTH);
Arduboy2Base::sBuffer[index] |= (uint8_t)(bitmap_data >> 8);
} }
ofs++; ofs++;
bofs++; bofs++;
@ -189,7 +191,8 @@ void Sprites::drawBitmap(int16_t x, int16_t y,
Arduboy2Base::sBuffer[ofs] &= ~(uint8_t)(bitmap_data); Arduboy2Base::sBuffer[ofs] &= ~(uint8_t)(bitmap_data);
} }
if (yOffset != 0 && sRow < 7) { if (yOffset != 0 && sRow < 7) {
Arduboy2Base::sBuffer[ofs + WIDTH] &= ~(*((unsigned char *) (&bitmap_data) + 1)); const size_t index = static_cast<uint16_t>(ofs + WIDTH);
Arduboy2Base::sBuffer[index] &= ~(uint8_t)(bitmap_data >> 8);
} }
ofs++; ofs++;
bofs++; bofs++;
@ -223,10 +226,11 @@ void Sprites::drawBitmap(int16_t x, int16_t y,
Arduboy2Base::sBuffer[ofs] = data; Arduboy2Base::sBuffer[ofs] = data;
} }
if (yOffset != 0 && sRow < 7) { if (yOffset != 0 && sRow < 7) {
data = Arduboy2Base::sBuffer[ofs + WIDTH]; const size_t index = static_cast<uint16_t>(ofs + WIDTH);
data &= (*((unsigned char *) (&mask_data) + 1)); data = Arduboy2Base::sBuffer[index];
data |= (*((unsigned char *) (&bitmap_data) + 1)); data &= (uint8_t)(mask_data >> 8);
Arduboy2Base::sBuffer[ofs + WIDTH] = data; data |= (uint8_t)(bitmap_data >> 8);
Arduboy2Base::sBuffer[index] = data;
} }
ofs++; ofs++;
mask_ofs++; mask_ofs++;

View File

@ -159,10 +159,11 @@ void SpritesB::drawBitmap(int16_t x, int16_t y,
Arduboy2Base::sBuffer[ofs] = data; Arduboy2Base::sBuffer[ofs] = data;
} }
if (yOffset != 0 && sRow < 7) { if (yOffset != 0 && sRow < 7) {
data = Arduboy2Base::sBuffer[ofs + WIDTH]; const size_t index = static_cast<uint16_t>(ofs + WIDTH);
data &= (*((unsigned char *) (&mask_data) + 1)); data = Arduboy2Base::sBuffer[index];
data |= (*((unsigned char *) (&bitmap_data) + 1)); data &= (uint8_t)(mask_data >> 8);
Arduboy2Base::sBuffer[ofs + WIDTH] = data; data |= (uint8_t)(bitmap_data >> 8);
Arduboy2Base::sBuffer[index] = data;
} }
ofs++; ofs++;
mask_ofs += ofs_step; mask_ofs += ofs_step;