/** * Loading */ #include #include #include "ssd1306.h" #include "user_interface.h" /* Tiny framebuffer */ #define FBW DISPLAY_W #define FBH DISPLAY_H #define MIN(a,b) ((a)>(b)?(b):(a)) #define MAX(a,b) ((a)>(b)?(a):(b)) static uint8_t fb[(FBH/8)*FBW]; /** Fill with a vertical pattern, 1 byte */ void fb_fill(uint8_t pattern) { memset(fb, pattern, sizeof(fb)); } void fb_clear() { fb_fill(0); } void fb_px(uint8_t x, uint8_t y, uint8_t color) { if (x >= FBW || y >= FBH) return; const uint8_t row = y / 8; const uint8_t rowrem = y % 8; const uint16_t cell = (uint16_t) x + (uint16_t) row * FBW; if (color) { fb[cell] |= (1 << rowrem); } else { fb[cell] &= ~(1 << rowrem); } } void fb_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t color) { if (x >= FBW || y >= FBH) return; w = MIN(FBW - x, w); const uint8_t row = y / 8; const uint8_t rowrem = y % 8; uint16_t cell = (uint16_t) x + (uint16_t) row * FBW; for(uint8_t i = 0; i < w; i++) { if (color) { fb[cell] |= (1 << rowrem); } else { fb[cell] &= ~(1 << rowrem); } cell++; } } void fb_vline(uint8_t x, uint8_t y, uint8_t h, uint8_t color) { if (x >= FBW || y >= FBH) return; h = MIN(FBH - y - 1, h); const uint8_t row = y / 8; const uint8_t rowrem = y % 8; uint16_t cell = (uint16_t) x + (uint16_t) row * FBW; if (rowrem + h < 8) { // all within one cell uint8_t mask = (0xFF << rowrem) & (0xFF >> (h-rowrem)); if (color) { fb[cell] |= mask; } else { fb[cell] &= ~mask; } return; } else { // First uint8_t mask = (0xFF << rowrem); if (color) { fb[cell] |= mask; } else { fb[cell] &= ~mask; } h -= rowrem; uint8_t whole_cells = h / 8; h -= whole_cells * 8; for(uint8_t i = 0; i < whole_cells; i++) { cell += FBW; if (color) { fb[cell] = 0xFF; } else { fb[cell] = 0; } } // last mask = (0xFF >> (8-h)); if (color) { fb[cell] |= mask; } else { fb[cell] &= ~mask; } } } void fb_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) { if (x >= FBW || y >= FBH) return; w = MIN(FBW - x - 1, w); h = MIN(FBH - y - 1, h); const uint8_t row = y / 8; const uint8_t rowrem = y % 8; uint16_t cell = (uint16_t) x + (uint16_t) row * FBW; if (rowrem + h < 8) { // all within one cell uint8_t mask = (0xFF << rowrem) & (0xFF >> (h-rowrem)); for(uint8_t i = 0; i < w; i++) { if (color) { fb[cell + i] |= mask; } else { fb[cell + i] &= ~mask; } } return; } else { // First uint8_t mask = (0xFF << rowrem); for(uint8_t i = 0; i < w; i++) { if (color) { fb[cell + i] |= mask; } else { fb[cell + i] &= ~mask; } } h -= rowrem; uint8_t whole_cells = h / 8; h -= whole_cells * 8; for(uint8_t j = 0; j < whole_cells; j++) { cell += FBW; for(uint8_t i = 0; i < w; i++) { if (color) { fb[cell + i] = 0xFF; } else { fb[cell + i] = 0; } } } // last mask = (0xFF >> (8-h)); for(uint8_t i = 0; i < w; i++) { if (color) { fb[cell + i] |= mask; } else { fb[cell + i] &= ~mask; } } } } void fb_blit() { ssd1306_drawBuffer(0, 0, FBW, FBH, fb); } void show_loading_screen(uint8_t progress_percent, bool clear) { // HACKS - GUI dev here fb_clear(); fb_blit(); // // fb_hline(3, 3, 30, 1); // fb_hline(3, 15, 35, 1); // fb_hline(3, 30, 40, 1); // // fb_vline(5, 0, 15, 1); // fb_vline(6, 0, 32, 0); fb_rect(10, 10, 30, 3, 1); fb_rect(40, 13, 3, 10, 1); // // fb_rect(0, 0, 10, 10, 1); // // fb_rect(7, 20, 20, 1, 1); // fb_rect(7, 23, 20, 3, 1); //fb_rect(15, 0, 5, 20, 0); fb_blit(); for(;;){} if (clear) { ssd1306_clearScreen(); } // bar in a box #define hei 20 #define wid DISPLAY_W #define thic 2 #define inpad 3 #define ofsx ((DISPLAY_W - wid)/2) #define ofsy ((DISPLAY_H - hei)/2) const uint8_t rects[4][4] = { // top { 0, 0, wid - 1, thic - 1 }, // left { 0, thic, thic - 1, hei - thic - 1 }, // right { wid - thic, thic, wid - 1, hei - thic - 1 }, // bot { 0, hei - thic, wid - 1, hei - 1 }, }; for (int i = 0; i < 4; i++) { ssd1306_fillRect( ofsx + rects[i][0], ofsy + rects[i][1], ofsx + rects[i][2], ofsy + rects[i][3] ); } // ssd1306_fillRect( ofsx + thic + inpad, ofsy + thic + inpad, ofsx + (uint8_t)(((uint16_t)wid * (uint16_t)progress_percent)/(uint16_t)100) - thic - inpad - 1, ofsy + hei - thic - inpad - 1 ); }