gui-dev
Ondřej Hruška 2 years ago
parent 79232c5d2c
commit fb7002e68b
  1. 232
      src/framebuffer.c
  2. 20
      src/framebuffer.h
  3. 235
      src/graphic_loading.c
  4. 5
      src/main.c

@ -0,0 +1,232 @@
//
// Created by MightyPork on 2022/11/12.
//
#include "user_interface.h"
#include "framebuffer.h"
#include "ssd1306.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) {
if (x >= FBW || y >= FBH) return;
const uint8_t w0 = w;
const uint8_t h0 = h;
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) {
for(uint8_t i = 0; i < w; i++) {
// all within one cell
uint8_t mask = (map[i] & (0xFF >> (8-h))) << rowrem;
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
return;
} else if (rowrem == 0) {
// Optimization
// First
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
h -= 8;
// Middle
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++) {
uint8_t mask = map[i + (j+1)*w0];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
}
// last
cell += FBW;
// last
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + (whole_cells+1)*w0] & (0xFF >> (8-h));
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
} else {
// TODO wild combination, unaligned multi-row
}
}
void fb_blit() {
ssd1306_drawBuffer(0, 0, FBW, FBH, fb);
}

@ -0,0 +1,20 @@
//
// Created by MightyPork on 2022/11/12.
//
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include <stdbool.h>
#include <stdint.h>
void fb_fill(uint8_t pattern);
void fb_clear(void);
void fb_px(uint8_t x, uint8_t y, uint8_t color);
void fb_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t color);
void fb_vline(uint8_t x, uint8_t y, uint8_t h, uint8_t color);
void fb_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color);
void fb_bitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t color);
void fb_blit(void);
#endif //FRAMEBUFFER_H

@ -6,174 +6,103 @@
#include <stdbool.h>
#include "ssd1306.h"
#include "user_interface.h"
#include "framebuffer.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 show_loading_screen(uint8_t progress_percent, bool clear) {
// HACKS - GUI dev here
void fb_clear() {
fb_fill(0);
}
fb_clear();
fb_blit();
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);
}
}
const uint8_t icon[14] = {
0b11000011,
0b01100110,
0b01111110,
0b00111100,
0b00011000,
0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111011,
0b11111111,
0b01111110,
0b00111100,
0b00011000,
};
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++;
}
}
#define ZIR_W 12
#define ZIR_H 3
const uint8_t zirafa[ZIR_H * ZIR_W] = {
// levo
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000, // vrsek
0b00011000,
0b00011111,
0b11111000,
0b00011111,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b11111111,
0b00000000,
0b00000000,
0b00010000,
0b00001000,
0b11111000,
0b00011000,
0b11111000, // spodek
0b00011000,
0b00011000,
0b00011000,
0b11111000,
0b00011111,
0b11111000,
0b00000000,
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;
int a = 10;
int b = 40;
for (;;) {
fb_bitmap(a, 0, ZIR_W, ZIR_H*8, zirafa, 0);
fb_bitmap(b, 16, 14, 8, icon, 0);
a++;
b++;
if(a>127) {
a = 0;
}
}
}
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;
}
}
if(b>127) {
b = 0;
}
fb_bitmap(a, 0, ZIR_W, ZIR_H*8, zirafa, 1);
fb_bitmap(b, 16, 14, 8, icon, 1);
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;
}
}
fb_blit();
_delay_ms(100);
}
}
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
for(;;) {}
fb_clear();
fb_blit();
//
#if 0
int a = 0, b = 0, ai = 1, bi = 1;
@ -220,8 +149,6 @@ void show_loading_screen(uint8_t progress_percent, bool clear)
}
#endif
for(;;) {}
if (clear) {
ssd1306_clearScreen();

@ -20,6 +20,9 @@ void __attribute__((noreturn)) main()
init_user_interface();
show_loading_screen(0, true);
while(1){}
#if 0
init_timebase();
init_radiation();
@ -48,6 +51,8 @@ void __attribute__((noreturn)) main()
shutdown_due_to_weak_battery();
}
}
#endif
}

Loading…
Cancel
Save