Compare commits

...

2 Commits

  1. 301
      src/framebuffer.c
  2. 20
      src/framebuffer.h
  3. 243
      src/graphic_loading.c
  4. 5
      src/main.c

@ -0,0 +1,301 @@
//
// 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
uint8_t mapc0 = 0;
// 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;
mapc0 += w0;
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
}
// last
mapc0 += w0;
cell += FBW;
// last
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0] & (0xFF >> (8-h));
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
} else {
uint8_t mapc0 = 0;
while (h > 0) {
// First
for (uint8_t i = 0; i < w; i++) {
uint8_t mask = (map[i + mapc0] & (0xFF >> (rowrem))) << rowrem;
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
//mapc0 += w0;
cell += FBW;
// leftover of the first row in map
// last
for (uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0] >> (8 - rowrem);
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
if (h > 8) {
h -= 8;
} else {
break;
}
mapc0 += w0;
}
#if 0
// Middle
uint8_t whole_cells = h / 8;
h -= whole_cells * 8;
for(uint8_t j = 0; j < whole_cells; j++) {
cell += FBW;
mapc0 += w0;
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
}
// last
mapc0 += w0;
cell += FBW;
// last
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0] & (0xFF >> (8-h));
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
#endif
}
}
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,121 @@
#include <stdbool.h>
#include "ssd1306.h"
#include "user_interface.h"
#include "framebuffer.h"
/* Tiny framebuffer */
#define FBW DISPLAY_W
#define FBH DISPLAY_H
void show_loading_screen(uint8_t progress_percent, bool clear) {
// HACKS - GUI dev here
#define MIN(a,b) ((a)>(b)?(b):(a))
#define MAX(a,b) ((a)>(b)?(a):(b))
fb_clear();
fb_blit();
static uint8_t fb[(FBH/8)*FBW];
const uint8_t ryba[14] = {
0b11000011,
0b01100110,
0b01111110,
0b00111100,
0b00011000,
0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111011,
0b11111111,
0b01111110,
0b00111100,
0b00011000,
};
/** Fill with a vertical pattern, 1 byte */
void fb_fill(uint8_t pattern) {
memset(fb, pattern, sizeof(fb));
}
void fb_clear() {
fb_fill(0);
}
#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_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++;
}
}
#if 1
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 pos=0;
for(;;) {
fb_clear();
//fb_bitmap(0, pos, 14, 8, ryba, 1);
fb_bitmap(0, pos, ZIR_W, ZIR_H, zirafa, 1);
fb_blit();
_delay_ms(500);
pos++;
if (pos>31) {
pos = 0;
}
}
}
#endif
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;
}
int a = 10;
int b = 40;
for (;;) {
fb_bitmap(a, 0, ZIR_W, ZIR_H*8, zirafa, 0);
fb_bitmap(b, 16, 14, 8, ryba, 0);
a++;
b++;
if(a>127) {
a = 0;
}
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;
}
if(b>127) {
b = 0;
}
fb_bitmap(a, 0, ZIR_W, ZIR_H*8, zirafa, 1);
fb_bitmap(b, 16, 14, 8, ryba, 1);
fb_blit();
_delay_ms(5);
}
}
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 +167,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