|
|
|
@ -7,9 +7,192 @@ |
|
|
|
|
#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(); |
|
|
|
|
} |
|
|
|
|