line32.cc 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //(C) 2023 Victor Suarez Rovere <suarezvictor@gmail.com>
  2. // SPDX-License-Identifier: AGPL-3.0-only
  3. #include "cflexhdl.h"
  4. #include "bus.h"
  5. #include "graphics.h"
  6. #ifndef iabs
  7. #warning iabs should be defined
  8. #define iabs(x) ((x) < 0 ? -(x) : (x))
  9. #endif
  10. MODULE line32(
  11. bus_master(bus),
  12. const uint16& x0,
  13. const uint16& x1,
  14. const uint16& y0,
  15. const uint16& y1,
  16. const uint32& rgba, //color
  17. const busaddr_t& base, //pixel offset
  18. const int16& xstride, //normally 4, but can run backwards
  19. const int16& ystride //bytes to skip for next line (usually the framebuffer width * 4 bytes)
  20. )
  21. {
  22. bus_setup32();
  23. //signed coordinates
  24. int16 x0i = x0;
  25. int16 x1i = x1;
  26. int16 y0i = y0;
  27. int16 y1i = y1;
  28. int16 dx = iabs (x1i - x0i);
  29. int16 dy = -iabs (y1i - y0i);
  30. int2 sx = x0 < x1 ? 1 : -1;
  31. int2 sy = y0 < y1 ? 1 : -1;
  32. int16 err = dx + dy; /* error value e_xy */
  33. int16 x = x0;
  34. int16 y = y0;
  35. int16 e2;
  36. bus_set_address(base);
  37. while(x != x1 || y != y1)
  38. {
  39. bus_write_start(rgba);
  40. if(!bus_write_pending())
  41. {
  42. bus_stop();
  43. //these variables needs to be signed
  44. busaddr_diff_t xincaddr = 0;
  45. busaddr_diff_t yincaddr = 0;
  46. e2 = err << 1;
  47. int16 dxe = 0;
  48. if (e2 <= dx) // e_xy+e_y < 0
  49. {
  50. dxe = dx;
  51. y = y + sy;
  52. yincaddr = ystride;
  53. }
  54. int16 dye = 0;
  55. if (e2 >= dy) // e_xy+e_x > 0
  56. {
  57. dye = dy;
  58. x = x + sx;
  59. xincaddr = xstride;
  60. }
  61. bus_inc_address(xincaddr + yincaddr);
  62. err = err + dxe + dye;
  63. }
  64. }
  65. while(bus_write_pending()); //wait last transaction
  66. bus_release();
  67. }