u8x8_d_bitmap.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. u8x8_d_bitmap.c
  3. a bitmap device
  4. */
  5. #include "stdlib.h" /* malloc */
  6. #include "stdint.h" /* uint16_t */
  7. #include "string.h" /* memcpy */
  8. #include "stdio.h" /* FILE */
  9. #include "u8g2.h" /* because of u8g2_Setup... */
  10. /*========================================================*/
  11. /* bitmap struct */
  12. struct _u8x8_bitmap_struct
  13. {
  14. u8x8_msg_cb u8x8_bitmap_display_old_cb;
  15. uint16_t tile_width;
  16. uint16_t tile_height;
  17. uint16_t pixel_width;
  18. uint16_t pixel_height;
  19. uint8_t *u8x8_buf;
  20. uint8_t *u8g2_buf;
  21. };
  22. typedef struct _u8x8_bitmap_struct u8x8_bitmap_t;
  23. /*========================================================*/
  24. /* bitmap functions */
  25. uint8_t u8x8_bitmap_SetSize(u8x8_bitmap_t *b, uint16_t pixel_width, uint16_t pixel_height)
  26. {
  27. if ( b->u8x8_buf != NULL )
  28. free(b->u8x8_buf);
  29. b->tile_width = (pixel_width+7)/8;
  30. b->tile_height = (pixel_height+7)/8;
  31. b->pixel_width = pixel_width;
  32. b->pixel_height = pixel_height;
  33. /* allocate the bitmap twice, one for u8x8 and another bitmap for u8g2 */
  34. /* however, the final bitmap will always be in the first half of the buffer */
  35. b->u8x8_buf = (uint8_t *)malloc((size_t)b->tile_width*(size_t)b->tile_height*(size_t)8*(size_t)2);
  36. b->u8g2_buf = b->u8x8_buf+(size_t)b->tile_width*(size_t)b->tile_height*(size_t)8;
  37. if ( b->u8x8_buf == NULL ) {
  38. b->u8g2_buf = NULL;
  39. return 0;
  40. }
  41. //printf("pixel size: %d %d\n", b->pixel_width, b->pixel_height);
  42. //printf("tile size: %d %d\n", b->tile_width, b->tile_height);
  43. return 1;
  44. }
  45. void u8x8_bitmap_DrawTiles(u8x8_bitmap_t *b, uint16_t tx, uint16_t ty, uint8_t tile_cnt, uint8_t *tile_ptr)
  46. {
  47. uint8_t *dest_ptr = b->u8x8_buf;
  48. //printf("tile pos: %d %d, cnt=%d\n", tx, ty, tile_cnt);
  49. if ( dest_ptr == NULL )
  50. return;
  51. dest_ptr += ty*b->pixel_width;
  52. dest_ptr += tx*8;
  53. memcpy(dest_ptr, tile_ptr, tile_cnt*8);
  54. }
  55. uint8_t u8x8_bitmap_GetPixel(u8x8_bitmap_t *b, uint16_t x, uint16_t y)
  56. {
  57. uint8_t *dest_ptr = b->u8x8_buf;
  58. if ( dest_ptr == NULL )
  59. return 0;
  60. dest_ptr += (y/8)*b->pixel_width;
  61. y &= 7;
  62. dest_ptr += x;
  63. if ( (*dest_ptr & (1<<y)) == 0 )
  64. return 0;
  65. return 1;
  66. }
  67. static void tga_write_byte(FILE *fp, uint8_t byte)
  68. {
  69. fputc(byte, fp);
  70. }
  71. static void tga_write_word(FILE *fp, uint16_t word)
  72. {
  73. tga_write_byte(fp, word&255);
  74. tga_write_byte(fp, word>>8);
  75. }
  76. void u8x8_bitmap_SaveTGA(u8x8_bitmap_t *b, const char *name)
  77. {
  78. FILE *fp;
  79. uint16_t x, y;
  80. fp = fopen(name, "wb");
  81. if ( fp != NULL )
  82. {
  83. tga_write_byte(fp, 0); /* no ID */
  84. tga_write_byte(fp, 0); /* no color map */
  85. tga_write_byte(fp, 2); /* uncompressed true color */
  86. tga_write_word(fp, 0);
  87. tga_write_word(fp, 0);
  88. tga_write_byte(fp, 0);
  89. tga_write_word(fp, 0); /* x origin */
  90. tga_write_word(fp, 0); /* y origin */
  91. tga_write_word(fp, b->pixel_width); /* width */
  92. tga_write_word(fp, b->pixel_height); /* height */
  93. tga_write_byte(fp, 24); /* color depth */
  94. tga_write_byte(fp, 0);
  95. for( y = 0; y < b->pixel_height; y++ )
  96. {
  97. for( x = 0; x < b->pixel_width; x++ )
  98. {
  99. if ( u8x8_bitmap_GetPixel(b, x, b->pixel_height-y-1) == 0 )
  100. {
  101. tga_write_byte(fp, 255); /* R */
  102. tga_write_byte(fp, 255); /* G */
  103. tga_write_byte(fp, 255); /* B */
  104. }
  105. else
  106. {
  107. tga_write_byte(fp, 0); /* R */
  108. tga_write_byte(fp, 0); /* G */
  109. tga_write_byte(fp, 0); /* B */
  110. }
  111. }
  112. }
  113. tga_write_word(fp, 0);
  114. tga_write_word(fp, 0);
  115. tga_write_word(fp, 0);
  116. tga_write_word(fp, 0);
  117. fwrite("TRUEVISION-XFILE.", 18, 1, fp);
  118. fclose(fp);
  119. }
  120. }
  121. /*========================================================*/
  122. /* global objects for the bitmap */
  123. u8x8_bitmap_t u8x8_bitmap;
  124. static u8x8_display_info_t u8x8_bitmap_info =
  125. {
  126. /* chip_enable_level = */ 0,
  127. /* chip_disable_level = */ 1,
  128. /* post_chip_enable_wait_ns = */ 0,
  129. /* pre_chip_disable_wait_ns = */ 0,
  130. /* reset_pulse_width_ms = */ 0,
  131. /* post_reset_wait_ms = */ 0,
  132. /* sda_setup_time_ns = */ 0,
  133. /* sck_pulse_width_ns = */ 0,
  134. /* sck_clock_hz = */ 4000000UL,
  135. /* spi_mode = */ 1,
  136. /* i2c_bus_clock_100kHz = */ 0,
  137. /* data_setup_time_ns = */ 0,
  138. /* write_pulse_width_ns = */ 0,
  139. /* tile_width = */ 8, /* dummy value */
  140. /* tile_hight = */ 4, /* dummy value */
  141. /* default_x_offset = */ 0,
  142. /* flipmode_x_offset = */ 0,
  143. /* pixel_width = */ 64, /* dummy value */
  144. /* pixel_height = */ 32 /* dummy value */
  145. };
  146. /*========================================================*/
  147. /* functions for handling of the global objects */
  148. /* allocate bitmap */
  149. /* will be called by u8x8_SetupBitmap or u8g2_SetupBitmap */
  150. static uint8_t u8x8_SetBitmapDeviceSize(U8X8_UNUSED u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height)
  151. {
  152. /* update the global bitmap object, allocate the bitmap */
  153. if ( u8x8_bitmap_SetSize(&u8x8_bitmap, pixel_width, pixel_height) == 0 )
  154. return 0;
  155. /* update the u8x8 object */
  156. u8x8_bitmap_info.tile_width = (pixel_width+7)/8;
  157. u8x8_bitmap_info.tile_height = (pixel_height+7)/8;
  158. u8x8_bitmap_info.pixel_width = pixel_width;
  159. u8x8_bitmap_info.pixel_height = pixel_height;
  160. return 1;
  161. }
  162. /* draw tiles to the bitmap, called by the device procedure */
  163. static void u8x8_DrawBitmapTiles(U8X8_UNUSED u8x8_t *u8x8, uint16_t tx, uint16_t ty, uint8_t tile_cnt, uint8_t *tile_ptr)
  164. {
  165. u8x8_bitmap_DrawTiles(&u8x8_bitmap, tx, ty, tile_cnt, tile_ptr);
  166. }
  167. uint8_t u8x8_GetBitmapPixel(U8X8_UNUSED u8x8_t *u8x8, uint16_t x, uint16_t y)
  168. {
  169. return u8x8_bitmap_GetPixel(&u8x8_bitmap, x, y);
  170. }
  171. void u8x8_SaveBitmapTGA(U8X8_UNUSED u8x8_t *u8x8, const char *filename)
  172. {
  173. u8x8_bitmap_SaveTGA(&u8x8_bitmap, filename);
  174. }
  175. /*========================================================*/
  176. static uint8_t u8x8_d_bitmap(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  177. {
  178. u8g2_uint_t x, y, c;
  179. uint8_t *ptr;
  180. switch(msg)
  181. {
  182. case U8X8_MSG_DISPLAY_SETUP_MEMORY:
  183. u8x8_d_helper_display_setup_memory(u8x8, &u8x8_bitmap_info);
  184. break;
  185. case U8X8_MSG_DISPLAY_INIT:
  186. u8x8_d_helper_display_init(u8x8); /* update low level interfaces (not required here) */
  187. break;
  188. case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
  189. break;
  190. case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
  191. break;
  192. case U8X8_MSG_DISPLAY_DRAW_TILE:
  193. x = ((u8x8_tile_t *)arg_ptr)->x_pos;
  194. y = ((u8x8_tile_t *)arg_ptr)->y_pos;
  195. c = ((u8x8_tile_t *)arg_ptr)->cnt;
  196. ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
  197. do
  198. {
  199. u8x8_DrawBitmapTiles(u8x8, x, y, c, ptr);
  200. x += c;
  201. arg_int--;
  202. } while( arg_int > 0 );
  203. break;
  204. default:
  205. return 0;
  206. }
  207. return 1;
  208. }
  209. /*========================================================*/
  210. /* u8x8 and u8g2 setup functions */
  211. void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height)
  212. {
  213. u8x8_SetBitmapDeviceSize(u8x8, pixel_width, pixel_height);
  214. /* setup defaults */
  215. u8x8_SetupDefaults(u8x8);
  216. /* setup specific callbacks */
  217. u8x8->display_cb = u8x8_d_bitmap;
  218. /* setup display info */
  219. u8x8_SetupMemory(u8x8);
  220. }
  221. void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t pixel_width, uint16_t pixel_height)
  222. {
  223. /* allocate bitmap, assign the device callback to u8x8 */
  224. u8x8_SetupBitmap(u8g2_GetU8x8(u8g2), pixel_width, pixel_height);
  225. /* configure u8g2 in full buffer mode */
  226. u8g2_SetupBuffer(u8g2, u8x8_bitmap.u8g2_buf, (pixel_height+7)/8, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
  227. }
  228. /*========================================================*/
  229. static uint8_t u8x8_d_bitmap_chain(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  230. {
  231. if ( msg == U8X8_MSG_DISPLAY_DRAW_TILE )
  232. u8x8_d_bitmap(u8x8, msg, arg_int, arg_ptr);
  233. return u8x8_bitmap.u8x8_bitmap_display_old_cb(u8x8, msg, arg_int, arg_ptr);
  234. }
  235. /* connect the bitmap to an existing u8g2 or u8x8 object */
  236. uint8_t u8x8_ConnectBitmapToU8x8(u8x8_t *u8x8)
  237. {
  238. if ( u8x8_SetBitmapDeviceSize(u8x8, u8x8_GetCols(u8x8)*8, u8x8_GetRows(u8x8)*8) == 0 )
  239. return 0;
  240. u8x8_bitmap.u8x8_bitmap_display_old_cb = u8x8->display_cb;
  241. u8x8->display_cb = u8x8_d_bitmap_chain;
  242. return 1;
  243. }