7 virtual void DrawPixel(Uint32 color,
int x,
int y) = 0;
9 unsigned char alpha) = 0;
11 virtual void DrawLine(Uint32 color,
int sx,
int sy,
int dx,
int dy) = 0;
13 int dx,
int dy,
unsigned char alpha) = 0;
15 virtual void DrawRectangle(Uint32 color,
int x,
int y,
int w,
int h) = 0;
17 int w,
int h,
unsigned char alpha) = 0;
20 int w,
int h,
unsigned char alpha) = 0;
22 virtual void DrawCircle(Uint32 color,
int x,
int y,
int r) = 0;
24 int r,
unsigned char alpha) = 0;
26 virtual void FillCircle(Uint32 color,
int x,
int y,
int r) = 0;
28 int r,
unsigned char alpha) = 0;
33 template <const
int BPP>
34 static inline Uint32
GetPixel(
const void *
const pixels,
unsigned int index)
37 return (((Uint8 *)pixels)[index]);
38 }
else if (BPP == 2) {
39 return (((Uint16 *)pixels)[index]);
40 }
else if (BPP == 4) {
41 return (((Uint32 *)pixels)[index]);
48 template <const
int BPP>
49 static inline void PutPixel(
void *
const pixels,
50 unsigned int index, Uint32 color)
53 ((Uint8 *)pixels)[index] = color;
54 }
else if (BPP == 2) {
55 ((Uint16 *)pixels)[index] = color;
56 }
else if (BPP == 4) {
57 ((Uint32 *)pixels)[index] = color;
63 template <const
int BPP>
70 *((Uint16 *)(((Uint8 *)pixels) + index)) = color;
71 }
else if (BPP == 2) {
74 *((Uint32 *)(((Uint16 *)pixels) + index)) = color;
75 }
else if (BPP == 4) {
76 Uint32 *ptr = ((Uint32 *)pixels) + index;
81 *((Uint64 *)ptr) = tmp | color;
91 template <const
int BPP>
99 *((Uint32 *)(((Uint8 *)pixels) + index)) = color;
100 }
else if (BPP == 2) {
101 Uint32 *ptr = (Uint32 *)(((Uint16 *)pixels) + index);
103 color |= color << 16;
108 *((Uint64 *)ptr) = tmp | color;
113 }
else if (BPP == 4) {
114 Uint32 *ptr = ((Uint32 *)pixels) + index;
119 *((Uint64 *)ptr) = tmp;
120 *((Uint64 *)(ptr + 2)) = tmp;
132 template <const
int BPP>
133 static inline void DrawHLine(
void *pixels,
unsigned int index,
134 int width, Uint32 color)
144 memset((
void *)(((Uint8 *)pixels) + index), color, width);
145 }
else if (BPP == 2) {
147 switch (((uintptr_t)pixels) & 6) {
149 PutPixel<BPP>(pixels, index, color);
153 PutPixel<BPP>(pixels, index, color);
157 PutPixel<BPP>(pixels, index, color);
164 if (((uintptr_t)pixels) & BPP) {
165 PutPixel<BPP>(pixels, index, color);
172 else if (BPP == 4 && ((uintptr_t)pixels) & BPP) {
173 PutPixel<BPP>(pixels, index, color);
179 PutPixelQuatro<BPP>(pixels, index, color);
185 PutPixel<BPP>(pixels, index, color);
189 PutPixel<BPP>(pixels, index, color);
193 PutPixel<BPP>(pixels, index, color);
208 template <const
int BPP, const
int MASK>
212 static inline void PutTransPixel(
void *pixels,
unsigned int index,
213 Uint32 color,
unsigned int alpha)
217 Uint16 *p = (((Uint16 *)pixels) + index);
220 if (MASK == 0xf7de) {
222 color = (((color << 16) | color) & 0x07E0F81F);
224 dp = ((dp << 16) | dp) & 0x07E0F81F;
225 dp += (((color - dp) * alpha) >> 5);
228 if (MASK == 0xfbde) {
230 color = (((color << 16) | color) & 0x03e07c1f);
232 dp = ((dp << 16) | dp) & 0x03e07c1f;
233 dp += (((color - dp) * alpha) >> 5);
239 *p = (dp >> 16) | dp;
240 }
else if (BPP == 4) {
242 Uint32 *p = (((Uint32 *)pixels) + index);
243 unsigned int sp2 = (color & 0xFF00FF00) >> 8;
249 dp2 = (dp & 0xFF00FF00) >> 8;
252 dp += (((color - dp) * alpha) >> 8);
254 dp2 += (((sp2 - dp2) * alpha) >> 8);
256 *p = (dp | (dp2 << 8));
262 static inline void PutTransPixelDouble(
void *pixels,
unsigned int index,
263 Uint32 color,
unsigned int alpha)
275 PutTransPixel(pixels, index, color, alpha);
276 PutTransPixel(pixels, index + 1, color, alpha);
278 }
else if (BPP == 4) {
280 Uint64 *
const p = (Uint64 *)(((Uint32 *)pixels) + index);
281 const Uint64 A = alpha;
283 Uint64 src1 = (src0 | (src0 << 32));
285 Uint64 dst1 = (dst0 >> 8);
290 src0 &= 0x00FF00FF00FF00FF;
291 src1 &= 0x00FF00FF00FF00FF;
293 dst0 &= 0x00FF00FF00FF00FF;
294 dst1 &= 0x00FF00FF00FF00FF;
296 dst0 += ((src0 - dst0) * A >> 8);
297 dst0 &= 0x00FF00FF00FF00FF;
299 dst1 += ((src1 - dst1) * A >> 8);
300 dst1 &= 0x00FF00FF00FF00FF;
302 *p = dst0 | (dst1 << 8)
304 Uint32 * p = (((Uint32 *)pixels) + index);
310 unsigned int d1, s1 = color & 0xff00ff;
311 unsigned int dp = *p;
315 color = (color >> 8) | (color << 8);
317 d1 += (s1 - d1) * alpha >> 8;
320 dp = ((dp & 0xff00) >> 8) |
321 ((p[1] & 0xff00) << 8);
323 dp += (color - dp) * alpha >> 8;
326 *p++ = d1 | ((dp << 8) & 0xff00) | 0xff000000;
330 d1 += (s1 - d1) * alpha >> 8;
333 *p = d1 | ((dp >> 8) & 0xff00) | 0xff000000;
341 static inline void PutTransPixel128(
void *pixels,
unsigned int index, Uint32 color)
345 #define BLEND16_50(d, s, mask) \
346 ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
348 Uint16 *p = (((Uint16 *)pixels) + index);
350 Uint16 s = color & 0xFFFF;
355 }
else if (BPP == 4) {
356 Uint32 *p = (((Uint32 *)pixels) + index);
359 *p = ((((color & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
360 + (color & d & 0x00010101)) | 0xff000000;
367 static inline void PutTransPixel128Double(
void *pixels,
const unsigned int index,
372 #define BLEND2x16_50(d, s, mask) \
373 (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
374 + (s & d & (~(mask | mask << 16))))
376 Uint32 *p = (Uint32 *)(((Uint16 *)pixels) + index);
378 const Uint32 s = (color & 0xFFFF) | color << 16;
383 }
else if (BPP == 4) {
384 Uint32 *p = (((Uint32 *)pixels) + index);
386 unsigned long long int d = *(
unsigned long long int *)p;
387 unsigned long long int s, c = color;
390 c = s & 0x00fefefe00fefefe;
392 *(
unsigned long long int *)p =
393 (((c + (d & 0x00fefefe00fefefe)) >> 1)
394 + (s & d & 0x0001010100010101)) |
398 const Uint32 c = color & 0x00fefefe;
399 *p++ = (((c + (d & 0x00fefefe)) >> 1)
400 + (color & d & 0x00010101)) | 0xff000000;
402 *p = (((c + (d & 0x00fefefe)) >> 1)
403 + (color & d & 0x00010101)) | 0xff000000;
410 static void DrawVLine(
void *pixels,
const unsigned int pitch,
411 unsigned int index,
int height, Uint32 color)
413 if (height < 1) {
return; }
415 DRAW::PutPixel<BPP>(pixels, index, color);
420 static void DrawTransVLine(
void *pixels,
const unsigned int pitch,
421 unsigned int index,
int height, Uint32 color,
unsigned int alpha)
423 if (height < 1) {
return; }
426 PutTransPixel128(pixels, index, color);
431 PutTransPixel(pixels, index, color, alpha);
437 static inline void DrawTransHLine128(
void *pixels,
438 unsigned int index,
int width, Uint32 color)
442 if (((uintptr_t)pixels) & BPP) {
446 PutTransPixel128(pixels, index, color);
451 PutTransPixel128Double(pixels, index, color);
456 if (width) { PutTransPixel128(pixels, index, color); }
462 static inline void DrawTransHLineNon128(
void *pixels,
463 unsigned int index,
int width, Uint32 color,
unsigned int alpha)
466 if (((uintptr_t)pixels) & BPP) {
470 PutTransPixel(pixels, index, color, alpha);
475 PutTransPixelDouble(pixels, index, color, alpha);
480 if (width) { PutTransPixel(pixels, index, color, alpha); }
484 static inline void DrawTransHLine(
void *pixels,
485 unsigned int index,
int width, Uint32 color,
unsigned int alpha)
489 DrawTransHLine128(pixels, index, width, color);
491 DrawTransHLineNon128(pixels, index, width, color, alpha);
495 void DrawPixel(Uint32 color,
int x,
int y)
497 unsigned int index =
TheScreen->pitch / BPP;
500 DRAW::PutPixel<BPP>(
TheScreen->pixels, index, color);
503 void DrawTransPixel(Uint32 color,
int x,
int y,
unsigned char alpha)
505 unsigned int index =
TheScreen->pitch / BPP;
509 PutTransPixel128(
TheScreen->pixels, index, color);
511 PutTransPixel(
TheScreen->pixels, index, color, alpha);
515 void DrawLine(Uint32 color,
int sx,
int sy,
int dx,
int dy)
518 const unsigned int pitch =
TheScreen->pitch / BPP;
521 unsigned int len = 1;
523 index = sx + sy * pitch;
526 index = dx + dy * pitch;
529 DrawVLine(
TheScreen->pixels, pitch, index, len, color);
534 unsigned int len = 1;
536 index = sx + sy * pitch;
539 index = dx + dy * pitch;
542 DRAW::DrawHLine<BPP>(
TheScreen->pixels, index, len, color);
583 p = (ylen << 1) - xlen;
587 for (x = sx; x < dx; ++x) {
588 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + index, color);
592 p += (ylen - xlen) << 1;
603 p = (xlen << 1) - ylen;
605 for (y = sy; y < dy; ++y) {
606 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + index, color);
609 p += (xlen - ylen) << 1;
623 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + index, color);
631 void DrawTransLine(Uint32 color,
int sx,
int sy,
632 int dx,
int dy,
unsigned char alpha)
634 DrawLine(color, sx, sy, dx, dy);
638 void DrawRectangle(Uint32 color,
int x,
int y,
int w,
int h)
640 const unsigned int pitch =
TheScreen->pitch / BPP;
641 unsigned int index = y * pitch;
642 unsigned int y_offset = (
h - 1) * pitch;
643 PutTransPixel128(
TheScreen->pixels, x + index, color);
644 DRAW::DrawHLine<BPP>(
TheScreen->pixels, x + index + 1,
w - 2, color);
645 PutTransPixel128(
TheScreen->pixels, x + index +
w - 1, color);
647 PutTransPixel128(
TheScreen->pixels, x + index + y_offset, color);
648 DRAW::DrawHLine<BPP>(
TheScreen->pixels, x + index + y_offset + 1,
w - 2, color);
649 PutTransPixel128(
TheScreen->pixels, x + index + y_offset +
w - 1, color);
651 DrawVLine(
TheScreen->pixels, pitch, x + index + pitch,
653 DrawVLine(
TheScreen->pixels, pitch, x + index +
w - 1 + pitch,
657 void DrawTransRectangle(Uint32 color,
int x,
int y,
658 int w,
int h,
unsigned char alpha)
660 const unsigned int pitch =
TheScreen->pitch / BPP;
661 unsigned int index = y * pitch;
662 unsigned int y_offset = (
h - 1) * pitch;
665 PutTransPixel(
TheScreen->pixels, x + index, color, alpha / 2);
666 DrawTransHLine(
TheScreen->pixels, x + index + 1,
w - 2, color, alpha);
667 PutTransPixel(
TheScreen->pixels, x + index +
w - 1, color, alpha / 2);
669 PutTransPixel(
TheScreen->pixels, x + index + y_offset, color, alpha / 2);
670 DrawTransHLine(
TheScreen->pixels, x + index + y_offset + 1,
671 w - 2, color, alpha);
673 x + index + y_offset +
w - 1, color, alpha / 2);
675 DrawTransVLine(
TheScreen->pixels, pitch, x + index + pitch,
676 h - 2, color, alpha);
677 DrawTransVLine(
TheScreen->pixels, pitch, x + index +
w - 1 + pitch,
678 h - 2, color, alpha);
681 void FillTransRectangle(Uint32 color,
int x,
int y,
682 int w,
int h,
unsigned char alpha)
684 const unsigned int pitch =
TheScreen->pitch / BPP;
685 unsigned int index = y * pitch;
688 DrawTransHLine128(
TheScreen->pixels, x + index,
w, color);
693 DrawTransHLineNon128(
TheScreen->pixels, x + index,
w, color, alpha);
699 void DrawCircle(Uint32 color,
int x,
int y,
int r)
701 const unsigned int pitch =
TheScreen->pitch / BPP;
706 for (; px <= py + 1; ++px) {
707 unsigned int index_plus = (y + py) * pitch;
708 unsigned int index_minus = (y - py) * pitch;
710 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + px + index_plus, color);
711 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + px + index_minus, color);
712 DRAW::PutPixel<BPP>(
TheScreen->pixels, x - px + index_plus, color);
713 DRAW::PutPixel<BPP>(
TheScreen->pixels, x - px + index_minus, color);
715 index_plus = (y + px) * pitch;
716 index_minus = (y - px) * pitch;
718 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + py + index_plus, color);
719 DRAW::PutPixel<BPP>(
TheScreen->pixels, x + py + index_minus, color);
720 DRAW::PutPixel<BPP>(
TheScreen->pixels, x - py + index_plus, color);
721 DRAW::PutPixel<BPP>(
TheScreen->pixels, x - py + index_minus, color);
726 p += 2 * (px - py) + 5;
732 void DrawTransCircle(Uint32 color,
int x,
int y,
733 int r,
unsigned char alpha)
735 const unsigned int pitch =
TheScreen->pitch / BPP;
740 for (; px <= py + 1; ++px) {
741 unsigned int index_plus = (y + py) * pitch;
742 unsigned int index_minus = (y - py) * pitch;
744 PutTransPixel(
TheScreen->pixels, x + px + index_plus, color, alpha);
745 PutTransPixel(
TheScreen->pixels, x + px + index_minus, color, alpha);
746 PutTransPixel(
TheScreen->pixels, x - px + index_plus, color, alpha);
747 PutTransPixel(
TheScreen->pixels, x - px + index_minus, color, alpha);
749 index_plus = (y + px) * pitch;
750 index_minus = (y - px) * pitch;
752 PutTransPixel(
TheScreen->pixels, x + py + index_plus, color, alpha);
753 PutTransPixel(
TheScreen->pixels, x + py + index_minus, color, alpha);
754 PutTransPixel(
TheScreen->pixels, x - py + index_plus, color, alpha);
755 PutTransPixel(
TheScreen->pixels, x - py + index_minus, color, alpha);
760 p += 2 * (px - py) + 5;
766 void FillCircle(Uint32 color,
int x,
int y,
int r)
768 const unsigned int pitch =
TheScreen->pitch / BPP;
773 for (; px <= py; ++px) {
775 unsigned int y_index = y * pitch;
776 unsigned int py_index = py * pitch;
783 x + px + (y_index - py_index),
791 x - px + (y_index - py_index),
798 p += 2 * (px - py) + 5;
802 unsigned int px_index = px * pitch;
804 x + py + 1 + y_index,
807 x + py + 1 + (y_index - px_index),
810 x - py - 1 + y_index,
813 x - py - 1 + (y_index - px_index),
820 void FillTransCircle(Uint32 color,
int x,
int y,
821 int r,
unsigned char alpha)
823 const unsigned int pitch =
TheScreen->pitch / BPP;
828 for (; px <= py; ++px) {
830 unsigned int y_index = y * pitch;
831 unsigned int py_index = py * pitch;
836 py + 1, color, alpha);
838 x + px + (y_index - py_index),
844 py + 1, color, alpha);
846 x - px + (y_index - py_index),
853 p += 2 * (px - py) + 5;
857 unsigned int px_index = px * pitch;
859 x + py + 1 + y_index,
860 px + 1, color, alpha);
862 x + py + 1 + (y_index - px_index),
865 x - py - 1 + y_index,
866 px + 1, color, alpha);
868 x - py - 1 + (y_index - px_index),