graphics.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <os.h>
  2. #include <graphics.h>
  3. #include <misc.h>
  4. #define LCD_CONTROLLER 0xC0000000
  5. volatile unsigned *lcd_base = (unsigned *) (LCD_CONTROLLER + 0x10);
  6. volatile unsigned *lcd_ris = (unsigned *) (LCD_CONTROLLER + 0x20);
  7. volatile unsigned *lcd_icr = (unsigned *) (LCD_CONTROLLER + 0x28);
  8. volatile unsigned *lcd_control = (unsigned *) (LCD_CONTROLLER + 0x18);
  9. unsigned lcd_control_bkp;
  10. #define BUFFER_SIZE 320 * 240 * 2
  11. unsigned short *buffer_front = NULL, *buffer_back = NULL, *buffer_os;
  12. /*
  13. * Buffer management
  14. */
  15. void buffer_allocate()
  16. {
  17. buffer_front = (unsigned short *) malloc(BUFFER_SIZE);
  18. buffer_back = (unsigned short *) malloc(BUFFER_SIZE);
  19. if (buffer_front == NULL || buffer_back == NULL)
  20. {
  21. free(buffer_front);
  22. free(buffer_back);
  23. exit(0);
  24. }
  25. buffer_os = (unsigned short *) *lcd_base;
  26. *lcd_base = (unsigned) buffer_front;
  27. // Set up the controller in order to use vsync signals
  28. lcd_control_bkp = *lcd_control;
  29. *lcd_control &= ~(0b11 << 12);
  30. *lcd_control |= 0b11 << 12;
  31. }
  32. void buffer_free()
  33. {
  34. free(buffer_front);
  35. free(buffer_back);
  36. *lcd_base = (unsigned) buffer_os;
  37. *lcd_control = lcd_control_bkp;
  38. }
  39. void buffer_swap()
  40. {
  41. unsigned short *buffer_front_tmp = buffer_front;
  42. buffer_front = buffer_back;
  43. buffer_back = buffer_front_tmp;
  44. *lcd_base = (unsigned) buffer_front;
  45. }
  46. void buffer_fill(unsigned color)
  47. {
  48. unsigned *buffer_back_32 = (unsigned *) buffer_back;
  49. color += color << 16;
  50. for (unsigned i = 0; i < (BUFFER_SIZE / 4); i++)
  51. buffer_back_32[i] = color;
  52. }
  53. /*
  54. * Misc LCD functions
  55. */
  56. void lcd_vsync()
  57. {
  58. *lcd_icr = 1 << 3;
  59. while (!(*lcd_ris & (1 << 3)));
  60. }
  61. /*
  62. * Drawing
  63. */
  64. void draw_pixel(unsigned x, unsigned y, unsigned short color)
  65. {
  66. buffer_back[x + (y * 320)] = color;
  67. }
  68. void draw_sprite_sheet(const unsigned short *sheet, int x, int y, const Rect_t *window)
  69. {
  70. unsigned short color;
  71. int w = min(window->w + x, 320);
  72. int h = min(window->h + y, 240);
  73. for (int j = max(y, 0), l = window->y - min(y, 0); j < h; j++, l++)
  74. {
  75. for (int i = max(x, 0), k = window->x - min(x, 0); i < w; i++, k++)
  76. {
  77. color = sprite_pixel_get(sheet, k, l);
  78. if (color != sheet[2])
  79. draw_pixel(i, j, color);
  80. }
  81. }
  82. }
  83. /*
  84. * Sprite manipulation
  85. */
  86. unsigned short sprite_pixel_get(const unsigned short *sprite, unsigned x, unsigned y)
  87. {
  88. if (x < sprite[0] && y < sprite[1])
  89. return sprite[x + (y * sprite[0]) + 3];
  90. else
  91. return sprite[2];
  92. }