graphics.c 3.0 KB

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