Graphics.cpp 2.7 KB

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