Graphics.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <stdio.h>
  2. #include "Graphics.h"
  3. #include "CXfb.h"
  4. #include "utility/misc.h"
  5. #include "utility/minmax.h"
  6. using namespace WalrusRPG; /*::Graphics*/
  7. using namespace Nspire;
  8. using WalrusRPG::Utils::Rect;
  9. void Graphics::init()
  10. {
  11. CXfb::buffer_allocate();
  12. }
  13. void Graphics::deinit()
  14. {
  15. CXfb::buffer_free();
  16. }
  17. void Graphics::frame_begin()
  18. {
  19. }
  20. void Graphics::frame_end()
  21. {
  22. CXfb::buffer_swap_render();
  23. }
  24. void Graphics::put_sprite(const Texture &sheet, int x, int y, const Rect &window)
  25. {
  26. CXfb::draw_sprite_sheet(sheet.data, x, y, window);
  27. }
  28. void Graphics::put_sprite_tint(const Texture &sheet, int x, int y, const Rect &window,
  29. const Pixel &color)
  30. {
  31. CXfb::draw_sprite_sheet_tint(sheet.data, x, y, window, color.value);
  32. }
  33. void Graphics::put_sprite_clipping(const Texture &sheet, int x, int y,
  34. const Rect &sprite_window, const Rect &clipping_window)
  35. {
  36. const signed &ss_x = sprite_window.x, ss_y = sprite_window.y;
  37. const signed &ss_w = sprite_window.width, &ss_h = sprite_window.height;
  38. const signed &cx = clipping_window.x, &cy = clipping_window.y;
  39. const signed &cw = clipping_window.width, &ch = clipping_window.height;
  40. const signed lx = x - cx, ly = y - cy;
  41. if (lx < -ss_w || lx > cw)
  42. return;
  43. if (ly < -ss_h || ly > ch)
  44. return;
  45. signed fx = x, fy = y;
  46. unsigned fssx = ss_x, fssy = ss_y;
  47. signed fssw = ss_w, fssh = ss_h;
  48. if (lx < 0)
  49. {
  50. fssw = ss_w + lx;
  51. fssx = -lx;
  52. fx = cx;
  53. }
  54. if (lx > cw - ss_w)
  55. {
  56. fssw -= lx - (cw - ss_w);
  57. }
  58. if (ly > ch - ss_h)
  59. {
  60. fssh -= ly - (ch - ss_h);
  61. }
  62. if (ly < 0)
  63. {
  64. fssh = ss_h + ly;
  65. fssy = -ly;
  66. fy = cy;
  67. }
  68. CXfb::draw_sprite_sheet(sheet.data, fx, fy, {fssx, fssy, fssw, fssh});
  69. }
  70. void Graphics::fill(const Pixel &color)
  71. {
  72. CXfb::buffer_fill(color);
  73. }
  74. void Graphics::put_pixel(uint16_t x, uint16_t y, const Pixel &color)
  75. {
  76. CXfb::draw_pixel(x, y, color.value);
  77. }
  78. void Graphics::put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
  79. const Pixel &color)
  80. {
  81. if (x > x2)
  82. {
  83. uint16_t temp = x;
  84. x = x2;
  85. x2 = temp;
  86. }
  87. for (; x <= x2; x++)
  88. {
  89. CXfb::draw_pixel(x, y, color);
  90. }
  91. }
  92. void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
  93. {
  94. if (y > y2)
  95. {
  96. uint16_t temp = y;
  97. y = y2;
  98. y2 = temp;
  99. }
  100. for (; y <= y2; y++)
  101. {
  102. CXfb::draw_pixel(x, y, color);
  103. }
  104. }
  105. void Graphics::put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
  106. const Pixel &color)
  107. {
  108. if (x == x2)
  109. {
  110. put_vertical_line(x, y, y2, color);
  111. return;
  112. }
  113. else if (y == y2)
  114. {
  115. put_horizontal_line(x, x2, y, color);
  116. return;
  117. }
  118. int dx = abs(x - x2), sx = x < x2 ? 1 : -1;
  119. int dy = abs(y - y2), sy = y < y2 ? 1 : -1;
  120. int err = (dx > dy ? dx : -dy) / 2, e2;
  121. for (;;)
  122. {
  123. put_pixel(x, y, color);
  124. if (x == x2 && y == y2)
  125. break;
  126. e2 = err;
  127. if (e2 > -dx)
  128. {
  129. err -= dy;
  130. x += sx;
  131. }
  132. if (e2 < dy)
  133. {
  134. err += dx;
  135. y += sy;
  136. }
  137. }
  138. }
  139. void Graphics::put_rectangle(const Rect &rect, const Pixel &color)
  140. {
  141. uint16_t xmax = min(320, rect.x + rect.width);
  142. uint16_t ymax = min(240, rect.y + rect.height);
  143. for (uint16_t x = rect.x; x < xmax; x++)
  144. {
  145. for (uint16_t y = rect.y; y < ymax; y++)
  146. {
  147. CXfb::draw_pixel(x, y, color.value);
  148. }
  149. }
  150. }