10 const uint8_t *mask, uint8_t frame, uint8_t mask_frame)
12 draw(x, y, bitmap, frame, mask, mask_frame, SPRITE_MASKED);
17 draw(x, y, bitmap, frame, NULL, 0, SPRITE_OVERWRITE);
22 draw(x, y, bitmap, frame, NULL, 0, SPRITE_IS_MASK_ERASE);
27 draw(x, y, bitmap, frame, NULL, 0, SPRITE_IS_MASK);
32 draw(x, y, bitmap, frame, NULL, 0, SPRITE_PLUS_MASK);
37 void Sprites::draw(int16_t x, int16_t y,
38 const uint8_t *bitmap, uint8_t frame,
39 const uint8_t *mask, uint8_t sprite_frame,
42 unsigned int frame_offset;
47 uint8_t width = pgm_read_byte(bitmap);
48 uint8_t height = pgm_read_byte(++bitmap);
50 if (frame > 0 || sprite_frame > 0) {
51 frame_offset = (width * ( height / 8 + ( height % 8 == 0 ? 0 : 1)));
53 if (drawMode == SPRITE_PLUS_MASK) {
55 }
else if (mask != NULL) {
56 mask += sprite_frame * frame_offset;
58 bitmap += frame * frame_offset;
63 if (drawMode == SPRITE_AUTO_MODE) {
64 drawMode = mask == NULL ? SPRITE_UNMASKED : SPRITE_MASKED;
67 drawBitmap(x, y, bitmap, mask, width, height, drawMode);
70 void Sprites::drawBitmap(int16_t x, int16_t y,
71 const uint8_t *bitmap,
const uint8_t *mask,
72 uint8_t w, uint8_t h, uint8_t draw_mode)
75 if (x + w <= 0 || x >
WIDTH - 1 || y + h <= 0 || y >
HEIGHT - 1)
83 uint16_t xOffset, ofs;
84 int8_t yOffset = y & 7;
86 uint8_t loop_h, start_h, rendered_width;
88 if (y < 0 && yOffset > 0) {
100 if (x + w >
WIDTH - 1) {
101 rendered_width = ((
WIDTH - x) - xOffset);
103 rendered_width = (w - xOffset);
108 start_h = abs(sRow) - 1;
113 loop_h = h / 8 + (h % 8 > 0 ? 1 : 0);
116 if (sRow + loop_h > (
HEIGHT / 8)) {
117 loop_h = (
HEIGHT / 8) - sRow;
125 ofs = (sRow *
WIDTH) + x + xOffset;
126 uint8_t *bofs = (uint8_t *)bitmap + (start_h * w) + xOffset;
129 uint8_t mul_amt = 1 << yOffset;
131 uint16_t bitmap_data;
134 case SPRITE_UNMASKED:
137 mask_data = ~(0xFF * mul_amt);
140 for (uint8_t a = 0; a < loop_h; a++) {
141 for (uint8_t iCol = 0; iCol < rendered_width; iCol++) {
142 bitmap_data = pgm_read_byte(bofs) * mul_amt;
146 data &= (uint8_t)(mask_data);
147 data |= (uint8_t)(bitmap_data);
150 if (yOffset != 0 && sRow < 7) {
151 const size_t index =
static_cast<uint16_t
>(ofs +
WIDTH);
153 data &= (uint8_t)(mask_data >> 8);
154 data |= (uint8_t)(bitmap_data >> 8);
161 bofs += w - rendered_width;
162 ofs +=
WIDTH - rendered_width;
167 for (uint8_t a = 0; a < loop_h; a++) {
168 for (uint8_t iCol = 0; iCol < rendered_width; iCol++) {
169 bitmap_data = pgm_read_byte(bofs) * mul_amt;
173 if (yOffset != 0 && sRow < 7) {
174 const size_t index =
static_cast<uint16_t
>(ofs +
WIDTH);
181 bofs += w - rendered_width;
182 ofs +=
WIDTH - rendered_width;
186 case SPRITE_IS_MASK_ERASE:
187 for (uint8_t a = 0; a < loop_h; a++) {
188 for (uint8_t iCol = 0; iCol < rendered_width; iCol++) {
189 bitmap_data = pgm_read_byte(bofs) * mul_amt;
193 if (yOffset != 0 && sRow < 7) {
194 const size_t index =
static_cast<uint16_t
>(ofs +
WIDTH);
201 bofs += w - rendered_width;
202 ofs +=
WIDTH - rendered_width;
208 mask_ofs = (uint8_t *)mask + (start_h * w) + xOffset;
209 for (uint8_t a = 0; a < loop_h; a++) {
210 for (uint8_t iCol = 0; iCol < rendered_width; iCol++) {
219 mask_data = ~(pgm_read_byte(mask_ofs) * mul_amt);
220 bitmap_data = pgm_read_byte(bofs) * mul_amt;
224 data &= (uint8_t)(mask_data);
225 data |= (uint8_t)(bitmap_data);
228 if (yOffset != 0 && sRow < 7) {
229 const size_t index =
static_cast<uint16_t
>(ofs +
WIDTH);
231 data &= (uint8_t)(mask_data >> 8);
232 data |= (uint8_t)(bitmap_data >> 8);
240 bofs += w - rendered_width;
241 mask_ofs += w - rendered_width;
242 ofs +=
WIDTH - rendered_width;
247 case SPRITE_PLUS_MASK:
249 bofs = (uint8_t *)(bitmap + ((start_h * w) + xOffset) * 2);
251 uint8_t xi = rendered_width;
256 "movw r28, %[buffer_ofs]\n"
263 "lpm %A[bitmap_data], Z+\n"
264 "lpm %A[mask_data], Z+\n"
268 "breq skip_shifting\n"
269 "mul %A[bitmap_data], %[mul_amt]\n"
270 "movw %[bitmap_data], r0\n"
271 "mul %A[mask_data], %[mul_amt]\n"
272 "movw %[mask_data], r0\n"
277 "brge end_second_page\n"
280 "com %B[mask_data]\n"
281 "and %[data], %B[mask_data]\n"
282 "or %[data], %B[bitmap_data]\n"
292 "brmi skip_first_page\n"
293 "ld %[data], %a[buffer_ofs]\n"
295 "com %A[mask_data]\n"
296 "and %[data], %A[mask_data]\n"
297 "or %[data], %A[bitmap_data]\n"
299 "st %a[buffer_ofs]+, %[data]\n"
300 "jmp end_first_page\n"
304 "adiw %[buffer_ofs], 1\n"
316 "mov %[xi], %[x_count]\n"
321 "add %A[sprite_ofs], %A[sprite_ofs_jump]\n"
322 "adc %B[sprite_ofs], __zero_reg__\n"
324 "add %A[buffer_ofs], %A[buffer_ofs_jump]\n"
325 "adc %B[buffer_ofs], __zero_reg__\n"
327 "add r28, %A[buffer_ofs_jump]\n"
328 "adc r29, __zero_reg__\n"
340 [mask_data]
"=&l" (mask_data),
341 [bitmap_data]
"=&l" (bitmap_data)
343 [screen_width]
"M" (
WIDTH),
344 [x_count]
"l" (rendered_width),
345 [sprite_ofs]
"z" (bofs),
347 [buffer_ofs_jump]
"a" (
WIDTH-rendered_width),
348 [sprite_ofs_jump]
"a" ((w-rendered_width)*2),
351 [yOffset]
"l" (yOffset),
352 [mul_amt]
"l" (mul_amt)