blit.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "minilisp.h"
  2. #include "blit.h"
  3. #include "machine.h"
  4. #include "utf8.h"
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #define FAST_BLIT
  8. #define put_pixel machine_video_set_pixel
  9. int blit_vector32(int h, int w, int dy, int dx, Cell* bytes_c)
  10. //int blit_vector32(uint32_t* pixels, uint sx, uint sy, uint pitch, uint w, uint h, uint dx, uint dy)
  11. {
  12. uint8_t* pixels = bytes_c->addr;
  13. int sx = 0;
  14. int sy = 0;
  15. for (int y=0; y<h; y++) {
  16. for (int x=0; x<w; x++) {
  17. int offset = ((sy+y)*w+sx+x)*3;
  18. if (offset<bytes_c->size) {
  19. uint32_t r = pixels[offset];
  20. uint32_t g = pixels[offset+1];
  21. uint32_t b = pixels[offset+2];
  22. put_pixel(dx+x,dy+y, (b<<16)|(g<<8)|r);
  23. }
  24. }
  25. }
  26. return 0;
  27. }
  28. static COLOR_TYPE* FB;
  29. void init_blitter(COLOR_TYPE* fb) {
  30. FB = fb;
  31. }
  32. int blit_string1(COLOR_TYPE color, int h, int w, int y, int x, int cursor_pos, Cell* str_c, Cell* font) {
  33. uint8_t* pixels = font->addr;
  34. uint8_t* str = str_c->addr;
  35. int x2 = x+w;
  36. int y2 = y+h;
  37. int x1 = x;
  38. int i = 0;
  39. int p = 0;
  40. uint8_t c = 0;
  41. do {
  42. c = str[i];
  43. uint8_t len = utf8_rune_len(c);
  44. uint32_t rune = utf8_rune_at(&str[i],0);
  45. if (cursor_pos != p) {
  46. if (rune!=10 && rune!=32) {
  47. blit_vector1_invert(color, y, x, 16, 16, 4096, (rune/256)*16, (rune&0xff)*16, pixels);
  48. }
  49. } else {
  50. if (rune == 0) rune = 32;
  51. blit_vector1(color, y, x, 16, 16, 4096, (rune/256)*16, (rune&0xff)*16, pixels);
  52. }
  53. i+=len;
  54. x+=8;
  55. if (x>=x2 || c==10) {
  56. y+=16;
  57. x=x1;
  58. }
  59. if (y>=y2) {
  60. break;
  61. }
  62. p++;
  63. } while (c);
  64. return i;
  65. }
  66. // 32bit source blitting gives ~2fps
  67. // reading uint32_t from source is slower than reading bytes (at least 2x?)
  68. // solution: 256-color palette / intensity / mask!
  69. // O3 is slower than O2
  70. // very fast: convert to 0x1 and 0x0 and subtract 1 (using overflow)
  71. #ifdef FAST_BLIT
  72. int blit_vector1(COLOR_TYPE color, uint dy, uint dx, uint h, uint w, uint pitch, uint sy, uint sx, uint8_t* pixels)
  73. {
  74. uint32_t s_offset = sy*pitch+sx;
  75. uint32_t t_offset = dy*SCREEN_W+dx;
  76. for (unsigned int y=0; y<h; y++) {
  77. register COLOR_TYPE* tfb = FB+t_offset;
  78. /*for (unsigned int x=0; x<w; x++) {
  79. register uint32_t px = pixels[s_offset+x];
  80. px |= (px<<8);
  81. px |= (px<<16);
  82. *(tfb+x) = px;
  83. }*/
  84. // letz unroll it
  85. register uint8_t* ptr = pixels+s_offset;
  86. for (unsigned int x=0; x<16; x++) {
  87. register COLOR_TYPE px = *ptr - 1;
  88. //px |= (px<<8);
  89. //px |= (px<<16);
  90. *tfb = px&color;
  91. tfb++;
  92. ptr++;
  93. }
  94. s_offset += pitch;
  95. t_offset += SCREEN_W;
  96. }
  97. return 0;
  98. }
  99. int blit_vector1_invert(COLOR_TYPE color, uint dy, uint dx, uint h, uint w, uint pitch, uint sy, uint sx, uint8_t* pixels)
  100. {
  101. uint32_t s_offset = sy*pitch+sx;
  102. uint32_t t_offset = dy*SCREEN_W+dx;
  103. for (unsigned int y=0; y<h; y++) {
  104. register COLOR_TYPE* tfb = FB+t_offset;
  105. register uint8_t* ptr = pixels+s_offset;
  106. for (unsigned int x=0; x<16; x++) {
  107. register COLOR_TYPE px = (1-*ptr) - 1;
  108. //px |= (px<<8);
  109. //px |= (px<<16);
  110. *tfb = px&color;
  111. tfb++;
  112. ptr++;
  113. }
  114. s_offset += pitch;
  115. t_offset += SCREEN_W;
  116. }
  117. return 0;
  118. }
  119. #else
  120. // blits b+w bitmaps
  121. //int blit_vector1(void* pixels, uint sx, uint sy, uint pitch, uint w, uint h, uint dx, uint dy, uint color)
  122. int blit_vector1(uint color, uint dy, uint dx, uint h, uint w, uint pitch, uint sy, uint sx, uint8_t* pixels)
  123. {
  124. for (unsigned int y=0; y<h; y++) {
  125. unsigned int ty = dy+y;
  126. for (unsigned int x=0; x<w; x++) {
  127. unsigned int px = pixels[((sy+y)*pitch+sx+x)];
  128. unsigned int tx = dx+x*8;
  129. // unpack byte into 8 pixels
  130. put_pixel(tx++,ty,((px>>7)&1)?color:0);
  131. put_pixel(tx++,ty,((px>>6)&1)?color:0);
  132. put_pixel(tx++,ty,((px>>5)&1)?color:0);
  133. put_pixel(tx++,ty,((px>>4)&1)?color:0);
  134. put_pixel(tx++,ty,((px>>3)&1)?color:0);
  135. put_pixel(tx++,ty,((px>>2)&1)?color:0);
  136. put_pixel(tx++,ty,((px>>1)&1)?color:0);
  137. put_pixel(tx,ty,(px&1)?color:0);
  138. }
  139. }
  140. return 0;
  141. }
  142. int blit_vector1_invert(uint color, uint dy, uint dx, uint h, uint w, uint pitch, uint sy, uint sx, uint8_t* pixels)
  143. {
  144. for (unsigned int y=0; y<h; y++) {
  145. unsigned int ty = dy+y;
  146. for (unsigned int x=0; x<w; x++) {
  147. unsigned int px = pixels[((sy+y)*pitch+sx+x)];
  148. unsigned int tx = dx+x*8;
  149. // unpack byte into 8 pixels
  150. put_pixel(tx++,ty,((px>>7)&1)?0:color);
  151. put_pixel(tx++,ty,((px>>6)&1)?0:color);
  152. put_pixel(tx++,ty,((px>>5)&1)?0:color);
  153. put_pixel(tx++,ty,((px>>4)&1)?0:color);
  154. put_pixel(tx++,ty,((px>>3)&1)?0:color);
  155. put_pixel(tx++,ty,((px>>2)&1)?0:color);
  156. put_pixel(tx++,ty,((px>>1)&1)?0:color);
  157. put_pixel(tx,ty,(px&1)?0:color);
  158. }
  159. }
  160. return 0;
  161. }
  162. #endif
  163. uint8_t* blitter_speedtest(uint8_t* font) {
  164. printf("speedtest unpacking font\r\n");
  165. uint8_t* font_unpacked = (uint8_t*)malloc(16*16*256*256);
  166. for (int y=0; y<256*16; y++) {
  167. if (y%10==0) {
  168. //printf("speedtest unpacking font row %d/%d\r\n",y,256*16);
  169. }
  170. int tx = 0;
  171. int to = y*256*16;
  172. for (int x=0; x<256*2; x++) {
  173. uint8_t px = font[((4*16+y))*516+(x+4)];
  174. font_unpacked[to+tx] = (((px>>7)&1)?1:0); tx++;
  175. font_unpacked[to+tx] = (((px>>6)&1)?1:0); tx++;
  176. font_unpacked[to+tx] = (((px>>5)&1)?1:0); tx++;
  177. font_unpacked[to+tx] = (((px>>4)&1)?1:0); tx++;
  178. font_unpacked[to+tx] = (((px>>3)&1)?1:0); tx++;
  179. font_unpacked[to+tx] = (((px>>2)&1)?1:0); tx++;
  180. font_unpacked[to+tx] = (((px>>1)&1)?1:0); tx++;
  181. font_unpacked[to+tx] = (((px>>0)&1)?1:0); tx++;
  182. }
  183. }
  184. //free(font);
  185. //font = font_unpacked;
  186. return font_unpacked;
  187. /*
  188. int rune = 0;
  189. while (1) {
  190. printf("speedtest rune: %d\r\n",rune);
  191. for (int y=0; y<60; y++) {
  192. for (int x=0; x<120; x++) {
  193. blit_vector1b(0xffff00,y*16,x*16,16,16,256*16,(rune/256)*16,(rune%256)*16,font_unpacked);
  194. }
  195. }
  196. rune++;
  197. if (rune>=64*256) rune = 0;
  198. }*/
  199. }