You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
atmega-geiger/src/graphic_loading.c

278 lines
6.2 KiB

/**
* Loading
*/
#include <stdint.h>
#include <stdbool.h>
#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 >> (8 - (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 -= 8 - 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;
}
}
}
cell += FBW;
// 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_bitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t color) {
// TODO
}
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();
#if 0
int a = 0, b = 0, ai = 1, bi = 1;
int c = 50, d = 5, ci = -1, di = 1;
int e = 70, f = 10, ei = 1, fi = -1;
int w=15;
int W=20;
for(;;){
fb_clear();
fb_rect(a, b, w, w, 1);
fb_rect(c, d, w, w, 1);
fb_rect(e, f, W, W, 1);
fb_rect(a+1, b+1, w-2, w-2, 0);
fb_rect(c+1, d+1, w-2, w-2, 0);
fb_rect(e+1, f+1, W-2, W-2, 0);
a += ai;
if (a == FBW-1-w) ai = -1;
if (a == 0) ai = 1;
b += bi;
if (b == FBH-1-w) bi = -1;
if (b == 0) bi = 1;
c += ci;
if (c == FBW-1-w) ci = -1;
if (c == 0) ci = 1;
d += di;
if (d == FBH-1-w) di = -1;
if (d == 0) di = 1;
e += ei;
if (e == FBW-1-W) ei = -1;
if (e == 0) ei = 1;
f += fi;
if (f == FBH-1-W) fi = -1;
if (f == 0) fi = 1;
fb_blit();
_delay_ms(5);
}
#endif
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
);
}