ellipse_fill32.cc 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. MODULE ellipse_fill32(
  7. bus_master(bus),
  8. const uint16& x0,
  9. const uint16& x1,
  10. const uint16& y0,
  11. const uint16& y1,
  12. const uint32& rgba, //color
  13. const busaddr_t& base, //pixel offset
  14. const int16& xstride, //normally 4, but can run backwards
  15. const int16& ystride //bytes to skip for next line (usually the framebuffer width * 4 bytes)
  16. )
  17. {
  18. busaddr_t yaddr;
  19. int16 x, y, rw, rh;
  20. int32 xx, yy, ww, hh;
  21. int64 xh, yw, wh;
  22. bus_setup32();
  23. rh = (y1 - y0) >> 1;
  24. rw = (x1 - x0) >> 1;
  25. ww = rw*rw;
  26. hh = rh*rh;
  27. wh = promote_u64(ww)*promote_u64(hh);
  28. yaddr = base;
  29. y = -rh;
  30. while(y < rh)
  31. {
  32. bus_set_address(yaddr);
  33. yy = y*y;
  34. yw = promote_u64(yy)*promote_u64(ww);
  35. x = -rw;
  36. while(x < rw)
  37. {
  38. xx = x*x;
  39. xh = promote_u64(xx)*promote_u64(hh);
  40. if(xh + yw < wh)
  41. {
  42. //point lies inside
  43. bus_write_start(rgba);
  44. if(!bus_write_pending())
  45. {
  46. bus_stop();
  47. bus_inc_address(xstride);
  48. x = x + 1;
  49. }
  50. }
  51. else
  52. {
  53. bus_inc_address(xstride);
  54. x = x + 1;
  55. }
  56. }
  57. while(bus_write_pending()); //wait last transaction
  58. bus_release();
  59. yaddr = yaddr + ystride;
  60. y = y + 1;
  61. }
  62. }