slightly better rle variant, implement the cell based one on the pico, 16fps fits and works
This commit is contained in:
parent
c5f7c245d2
commit
f05d146af7
6 changed files with 123434 additions and 79213 deletions
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13...3.27)
|
|||
# note: this must happen before project()
|
||||
include(pico_sdk_import.cmake)
|
||||
|
||||
project(Bad_Apple!!_Pico)
|
||||
project(Bad_Apple_Pico)
|
||||
|
||||
# initialize the Raspberry Pi Pico SDK
|
||||
pico_sdk_init()
|
||||
|
|
202153
pico_decoder/src/data.h
202153
pico_decoder/src/data.h
File diff suppressed because it is too large
Load diff
|
@ -14,12 +14,18 @@
|
|||
#define HEIGHT ILI9341_TFTHEIGHT
|
||||
#define WIDTH ILI9341_TFTWIDTH
|
||||
|
||||
// #define DEBUG_STUFF
|
||||
|
||||
#define FPS 16
|
||||
|
||||
#define MICROS_PER_FRAME (1000000/FPS)
|
||||
|
||||
// todo pack as bits instead
|
||||
#define AREA (HEIGHT * WIDTH)
|
||||
u8 frame[AREA];
|
||||
|
||||
u32 reader;
|
||||
bool error = false;
|
||||
u8 error = 0;
|
||||
u8 last_frame_type;
|
||||
u32 last_frame_start;
|
||||
|
||||
|
@ -29,21 +35,21 @@ void set_pixel(u16 x, u16 y, u8 color);
|
|||
|
||||
void draw_digit(u16 x, u16 y, u8 digit) {
|
||||
const u16 digit_font[10] = {
|
||||
0b111101101101111, // 0
|
||||
0b010110010010111, // 1
|
||||
0b111001111100111, // 2
|
||||
0b111001111001111, // 3
|
||||
0b101101111001001, // 4
|
||||
0b111100111001111, // 5
|
||||
0b111100111101111, // 6
|
||||
0b111001001001001, // 7
|
||||
0b111101111101111, // 8
|
||||
0b111101111001111, // 9
|
||||
};
|
||||
0b111101101101111, // 0
|
||||
0b010110010010111, // 1
|
||||
0b111001111100111, // 2
|
||||
0b111001111001111, // 3
|
||||
0b101101111001001, // 4
|
||||
0b111100111001111, // 5
|
||||
0b111100111101111, // 6
|
||||
0b111001001001001, // 7
|
||||
0b111101111101111, // 8
|
||||
0b111101111001111, // 9
|
||||
};
|
||||
// background square
|
||||
for (int xx = 0; xx < 5; xx++)
|
||||
for (int yy = 0; yy < 7; yy++){
|
||||
set_pixel(x+xx-1, y+yy-1, 0);
|
||||
}
|
||||
for (int yy = 0; yy < 7; yy++)
|
||||
set_pixel(x+xx-1, y+yy-1, 0);
|
||||
|
||||
u16 pixels = digit_font[digit];
|
||||
set_pixel(x + 0, y + 0, (pixels >> 14) & 1);
|
||||
|
@ -64,8 +70,9 @@ void draw_digit(u16 x, u16 y, u8 digit) {
|
|||
}
|
||||
|
||||
void draw_num(u16 x, u16 y, u32 num) {
|
||||
if (num == 0) draw_digit(x, y, num);
|
||||
while (num) {
|
||||
u8 digit = num%10;
|
||||
u8 digit = num % 10;
|
||||
num /= 10;
|
||||
draw_digit(x, y, digit);
|
||||
x -= 4;
|
||||
|
@ -77,21 +84,35 @@ int main() {
|
|||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
tft_init_display(100 * 1000 * 1000); // max is 62.5MHz
|
||||
|
||||
u32 next_frame = time_us_32();
|
||||
|
||||
while (!error) {
|
||||
sleep_until(next_frame);
|
||||
next_frame += MICROS_PER_FRAME;
|
||||
decode_next_frame();
|
||||
#ifdef DEBUG_STUFF
|
||||
draw_num(50, 2, error);
|
||||
draw_num(25, 2, reader - 1);
|
||||
draw_num(25, 8, video[reader - 1]);
|
||||
draw_num(50, 8, video[reader]);
|
||||
draw_num(25, 16, last_frame_start);
|
||||
draw_num(25, 22, last_frame_type);
|
||||
#endif
|
||||
refresh_screen();
|
||||
// sleep_ms(100);
|
||||
if (reader >= sizeof(video))
|
||||
error = true;
|
||||
error = 1;
|
||||
// reader = 0;
|
||||
}
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
draw_num(30, 2, reader-1);
|
||||
draw_num(15, 8, video[reader-1]);
|
||||
draw_num(30, 16, last_frame_start);
|
||||
draw_num(15, 22, last_frame_type);
|
||||
refresh_screen();
|
||||
while(1){};
|
||||
#ifdef DEBUG_STUFF
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
draw_num(30, 2, reader-1);
|
||||
draw_num(15, 8, video[reader-1]);
|
||||
draw_num(30, 16, last_frame_start);
|
||||
draw_num(15, 22, last_frame_type);
|
||||
refresh_screen();
|
||||
#endif
|
||||
// while(1){};
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,14 +154,20 @@ void fill_frame(u8 color) {
|
|||
|
||||
void set_pixel(u16 x, u16 y, u8 color)
|
||||
{
|
||||
// if (x >= WIDTH || y >= HEIGHT){
|
||||
// while (1){
|
||||
// gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
// sleep_ms(50);
|
||||
// gpio_put(PICO_DEFAULT_LED_PIN, 0);
|
||||
// sleep_ms(50);
|
||||
// }
|
||||
// }
|
||||
#ifdef DEBUG_STUFF
|
||||
if (x >= WIDTH || y >= HEIGHT){
|
||||
draw_num(30, 30, x);
|
||||
draw_num(30, 36, y);
|
||||
draw_num(30, 42, color);
|
||||
refresh_screen();
|
||||
while (1) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
sleep_ms(50);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 0);
|
||||
sleep_ms(50);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
x = (WIDTH-1) - x;
|
||||
const u32 index = x * HEIGHT + y;
|
||||
frame[index] = color;
|
||||
|
@ -148,9 +175,10 @@ void set_pixel(u16 x, u16 y, u8 color)
|
|||
|
||||
void rle_horizontal();
|
||||
void rle_vertical();
|
||||
void rle_vertical_ext();
|
||||
void rle_vertical_ext_2();
|
||||
void rle_horizontal_ext_2();
|
||||
void bg_strips_h();
|
||||
void cell_diff_4vv();
|
||||
void cell_diff_8();
|
||||
|
||||
void decode_next_frame()
|
||||
{
|
||||
|
@ -178,9 +206,14 @@ void decode_next_frame()
|
|||
rle_vertical();
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_RLEVerticalExt
|
||||
case Encoding_RLEVerticalExt:
|
||||
rle_vertical_ext();
|
||||
#ifdef USE_RLEVerticalExt2
|
||||
case Encoding_RLEVerticalExt2:
|
||||
rle_vertical_ext_2();
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_RLEHorizontalExt2
|
||||
case Encoding_RLEHorizontalExt2:
|
||||
rle_horizontal_ext_2();
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_BGStripsH24
|
||||
|
@ -188,13 +221,14 @@ void decode_next_frame()
|
|||
bg_strips_h();
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_CellDiff4VV
|
||||
case Encoding_CellDiff4VV:
|
||||
cell_diff_4vv();
|
||||
#ifdef USE_CellDiff8VBig
|
||||
case Encoding_CellDiff8VBig:
|
||||
cell_diff_8();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = true;
|
||||
error = 99;
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||
return;
|
||||
}
|
||||
last_frame_type = encoding;
|
||||
|
@ -227,11 +261,9 @@ void rle_vertical() {
|
|||
u16 x = 0;
|
||||
u16 y = 0;
|
||||
u8 color = 0;
|
||||
while (x < WIDTH)
|
||||
{
|
||||
while (x < WIDTH) {
|
||||
u16 run = next_byte();
|
||||
for (u16 i = 0; i < run; i++)
|
||||
{
|
||||
while (run--) {
|
||||
set_pixel(x, y, color);
|
||||
y += 1;
|
||||
if (y == HEIGHT) {
|
||||
|
@ -244,25 +276,22 @@ void rle_vertical() {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_RLEVerticalExt
|
||||
void rle_vertical_ext() {
|
||||
#ifdef USE_RLEVerticalExt2
|
||||
void rle_vertical_ext_2() {
|
||||
u16 x = 0;
|
||||
u16 y = 0;
|
||||
u8 color = 0;
|
||||
while (x < WIDTH) {
|
||||
u8 byte = next_byte();
|
||||
u16 run = byte;
|
||||
if (byte == 0 && video[reader] == 0) {
|
||||
if (byte == 255) {
|
||||
// 16 bit run length
|
||||
u16 upper = video[reader + 1] << 8;
|
||||
if (upper) {
|
||||
u16 lower = video[reader + 2];
|
||||
run = upper | lower;
|
||||
reader += 3;
|
||||
}
|
||||
u16 upper = (u16)video[reader] << 8;
|
||||
u16 lower = video[reader + 1];
|
||||
reader += 2;
|
||||
run = upper | lower;
|
||||
}
|
||||
for (u16 i = 0; i < run; i++) {
|
||||
while (run--) {
|
||||
set_pixel(x, y, color);
|
||||
y += 1;
|
||||
if (y == HEIGHT) {
|
||||
|
@ -275,6 +304,34 @@ void rle_vertical_ext() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_RLEHorizontalExt2
|
||||
void rle_horizontal_ext_2() {
|
||||
u16 x = 0;
|
||||
u16 y = 0;
|
||||
u8 color = 0;
|
||||
while (y < HEIGHT) {
|
||||
u8 byte = next_byte();
|
||||
u16 run = byte;
|
||||
if (byte == 255) {
|
||||
// 16 bit run length
|
||||
u16 upper = (u16)video[reader] << 8;
|
||||
u16 lower = video[reader + 1];
|
||||
reader += 2;
|
||||
run = upper | lower;
|
||||
}
|
||||
while (run--) {
|
||||
set_pixel(x, y, color);
|
||||
x += 1;
|
||||
if (x == WIDTH) {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
color = !color;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BGStripsH24
|
||||
void bg_strips_h() {
|
||||
u8 head = next_byte();
|
||||
|
@ -295,15 +352,49 @@ void bg_strips_h() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_CellDiff4VV
|
||||
void cell_diff_4vv() {
|
||||
const u32 cells_x = WIDTH/4;
|
||||
const u32 cells_y = HEIGHT/4;
|
||||
bool modified_cells[cells_x*cells_y];
|
||||
|
||||
#ifdef USE_CellDiff8VBig
|
||||
void cell_diff_8() {
|
||||
const u32 cells_x = WIDTH / 8;
|
||||
const u32 cells_y = HEIGHT / 8;
|
||||
u8 modified_cells[cells_x * cells_y];
|
||||
|
||||
for (u16 x = 0; x < WIDTH; x++) {
|
||||
for (u16 y = 0; y < HEIGHT; y++) {
|
||||
u16 cx = 0;
|
||||
u16 cy = 0;
|
||||
u8 filled = 0;
|
||||
while (cx < cells_x) {
|
||||
u8 run = next_byte();
|
||||
while (run--) {
|
||||
u32 index = cx * cells_y + cy;
|
||||
modified_cells[index] = filled;
|
||||
cy += 1;
|
||||
if (cy == cells_y) {
|
||||
cy = 0;
|
||||
cx += 1;
|
||||
}
|
||||
}
|
||||
filled = !filled;
|
||||
}
|
||||
|
||||
u16 run = 0;
|
||||
u16 x = 0;
|
||||
u16 y = 0;
|
||||
u8 color = 1;
|
||||
while (x < WIDTH) {
|
||||
u16 ccx = x / 8;
|
||||
u16 ccy = y / 8;
|
||||
if (modified_cells[ccx * cells_y + ccy]) {
|
||||
while (run == 0) {
|
||||
run = next_byte();
|
||||
color = !color;
|
||||
}
|
||||
run -= 1;
|
||||
set_pixel(x, y, color);
|
||||
}
|
||||
y += 1;
|
||||
if (y == HEIGHT) {
|
||||
y = 0;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue