Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color text example #48

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions software/apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(bad_apple)
add_subdirectory(colortext)
add_subdirectory(colour_terminal)
add_subdirectory(christmas_snowflakes)
add_subdirectory(dht_logging)
Expand Down
30 changes: 30 additions & 0 deletions software/apps/colortext/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
add_executable(colortext
main.c
font.h
gen.h
gen.c
scanout.h
scanout.S
text.h
text.c
)

# TODO this should work ok with DVI_N_TMDS_BUFFERS=2 (perhaps need to
# rearrange some pushes/pops) and also as we are monochrome the buffers are 3x
# as big as they need to be
target_compile_definitions(colortext PRIVATE
DVI_DEFAULT_SERIAL_CONFIG=${DVI_DEFAULT_SERIAL_CONFIG}
DVI_VERTICAL_REPEAT=1
DVI_N_TMDS_BUFFERS=3
DVI_MONOCHROME_TMDS=0
)

target_link_libraries(colortext
pico_stdlib
pico_multicore
pico_util
libdvi
)

# create map/bin/hex file etc.
pico_add_extra_outputs(colortext)
76 changes: 76 additions & 0 deletions software/apps/colortext/font.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#define FONT_STRIDE 100
#define FONT_HEIGHT 16
static const uint16_t font_x_offsets[] = {
0, 4, 9, 16, 24, 32, 46, 59, 64, 69, 74, 82, 91, 95, 104, 108, 113,
121, 129, 137, 145, 153, 161, 169, 177, 185, 193, 197, 201, 210, 219,
228, 235, 250, 262, 273, 284, 296, 306, 315, 327, 339, 344, 350, 362,
372, 387, 399, 411, 420, 432, 443, 452, 462, 474, 486, 502, 514, 526,
536, 541, 546, 551, 559, 567, 572, 579, 587, 594, 602, 609, 615, 623,
631, 636, 640, 648, 653, 666, 674, 682, 690, 698, 704, 710, 715, 723,
731, 743, 751, 759, 766, 774, 777, 785
};
static const uint8_t font_widths[] = {
4, 5, 7, 8, 8, 14, 13, 5, 5, 5, 8, 9, 4, 9, 4, 5, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 4, 4, 9, 9, 9, 7, 15, 12, 11, 11, 12, 10, 9, 12, 12, 5, 6, 12,
10, 15, 12, 12, 9, 12, 11, 9, 10, 12, 12, 16, 12, 12, 10, 5, 5, 5, 8,
8, 5, 7, 8, 7, 8, 7, 6, 8, 8, 5, 4, 8, 5, 13, 8, 8, 8, 8, 6, 6, 5, 8,
8, 12, 8, 8, 7, 8, 3, 8, 9
};
static const uint32_t font_bits[] = {
0x8000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e482440,
0x200c0138, 0x2008, 0x10390000, 0xf8403838, 0x3818fee0, 0x0,
0x801f01c0, 0xf5f01f80, 0x83fcff03, 0x9c39c397, 0xc0701de7, 0xf8381c39,
0xe03f0701, 0x1ce1dff2, 0xc1dc39dc, 0xe7fdc1d, 0x200041c, 0x800010,
0x42010030, 0x404, 0x0, 0x0, 0x0, 0x64c, 0x49482440, 0x201201e4,
0xa824, 0x18450000, 0x8604444, 0x44248218, 0x0, 0x8060c220, 0x260c3101,
0x6208820c, 0x8108118, 0xc0600841, 0x10c60830, 0x104218c2, 0x8409113,
0x80881088, 0x22204808, 0x1000a10, 0xc00018, 0x42018048, 0x606, 0x0,
0x80, 0x0, 0x842, 0x49482440, 0x101201a2, 0x7042, 0x14450000,
0x8504282, 0x82424204, 0x30018000, 0x40802220, 0x24042101, 0x10080210,
0x8108110, 0xa0a00821, 0x10820850, 0x8821044, 0x10409112, 0x41042104,
0x22104410, 0x1000a10, 0x800010, 0x10008, 0x404, 0x0, 0x80, 0x0, 0x842,
0x9fe0040, 0x1200a2, 0x407042, 0x10828000, 0x4502080, 0x82424004,
0xc0006044, 0x40ac1200, 0x24022103, 0x8080220, 0x8108100, 0xa0a00811,
0x11010850, 0x8822024, 0x10408100, 0x22042104, 0x42080220, 0xc0001110,
0x70b0e1d1, 0x421d3608, 0xe8668474, 0x6970e870, 0xbf3b1bde, 0x1ff7bbf3,
0x842, 0xa240040, 0x1cc00d2, 0x40a881, 0x10828000, 0x3c481080,
0x82242032, 0x1044, 0x21331101, 0x20021102, 0x9084220, 0x8108100,
0x91200809, 0x11010890, 0x30422022, 0x20408100, 0x14046202, 0x42080220,
0x20001110, 0x88c91132, 0x6333193c, 0x9c99c424, 0x5d999c89, 0x12121091,
0x10a11121, 0x842, 0x1c240040, 0x870e4c, 0x402081, 0x10824000,
0x40443840, 0xc418204e, 0x1fc0c00, 0x21110886, 0x20021f06, 0x9f87e20,
0x810ff3c, 0x91200807, 0xf1010890, 0xc03e2021, 0x20408101, 0x8025202,
0x82040140, 0x20002090, 0x84850a12, 0x42211088, 0x8888414, 0x9090905,
0x12121081, 0x8210a21, 0x11c0842, 0x287f0040, 0x488960, 0x83f80081,
0x1082403f, 0x80444020, 0xb8241082, 0x200, 0x11108888, 0x20023104,
0x9084220, 0x8108110, 0x91200809, 0x11010910, 0x122020, 0x20408102,
0x14025202, 0x82020080, 0x80002090, 0xfc840a13, 0x42211088, 0x888840c,
0x9090905, 0x2122108e, 0x4120412, 0x1321041, 0x48120000, 0x3048a0,
0x400081, 0x10824000, 0x80428010, 0x40421082, 0xc00, 0xf1108806,
0x20024107, 0x8080220, 0x8108110, 0x8a200811, 0x11010a10, 0x222020,
0x40408104, 0x22029401, 0x2010080, 0x60000011, 0x4840a12, 0x42210908,
0x8888414, 0x9090905, 0x21221090, 0x2120a12, 0xe20842, 0x49120000,
0x21048b0, 0x400081, 0x10442000, 0x80fe8008, 0x40421082, 0x1fc1000,
0x8988801, 0x2404410c, 0x10080210, 0x9108110, 0x8a200821, 0x10820a10,
0x8421040, 0x40408104, 0x41029401, 0x2010080, 0x20000011, 0x4840a12,
0x42210708, 0x8888424, 0x9090905, 0x41421091, 0x1140a15, 0x842,
0x49120040, 0x1288490, 0x20400081, 0x10442200, 0x62404684, 0x30240844,
0xc0006044, 0x8948880, 0x230c6108, 0x6009020c, 0x9108118, 0x84220841,
0x10c60c10, 0x188218c0, 0x80210102, 0x80810800, 0x2408080, 0x20000012,
0x89c91133, 0x42210088, 0x8888444, 0x9991889, 0x80c71293, 0x10881108,
0x842, 0x3e120040, 0xc70310, 0x20000042, 0x38382200, 0x1c403c7e,
0xe180838, 0x30018044, 0x1c631080, 0xf0f03fbc, 0x801cff03, 0x8639c387,
0xc471fde7, 0x38380879, 0xeb870780, 0x801e0381, 0xc1c10800, 0x23fc1c1,
0xc0000012, 0x70b0e0e6, 0x47739f3c, 0x9dddceee, 0x1d70e873, 0x8082e10d,
0x1f883b88, 0x842, 0x8000000, 0x0, 0x10000042, 0x1000, 0x0, 0x0, 0x20,
0x2000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x600, 0x0, 0x0, 0x2000000, 0x10, 0x0,
0x40002080, 0x0, 0x1000800, 0x0, 0x40000, 0x802, 0x0, 0x0, 0x24,
0x1000, 0x0, 0x0, 0x0, 0x60c000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc00, 0x0,
0x0, 0x2000000, 0x7f8010, 0x0, 0x40002080, 0x0, 0x1000800, 0x0,
0x40000, 0x802, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x1f0000, 0x0, 0x0,
0x0, 0x0, 0x0, 0x7000, 0x0, 0x0, 0xe000000, 0x1c, 0x0, 0x50001180, 0x0,
0x1000800, 0x0, 0x28000, 0x60c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30000f00, 0x0,
0x3801c00, 0x0, 0x18000, 0x0
};
163 changes: 163 additions & 0 deletions software/apps/colortext/gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#include <stdint.h>
#include "dvi.h"
#include "gen.h"

uint32_t expand_1_to_4_lut[256];

void init_expand_lut() {
for (uint i = 0; i < 256; i++) {
uint32_t out = 0;
for (uint j = 0; j < 8; j++) {
if (i & (1 << j)) {
out |= 15 << (j * 4);
}
}
expand_1_to_4_lut[i] = out;
}
}

// n is number of bytes of input (number of pixels / 8)
void __not_in_flash("main") expand_1_to_4(uint8_t *src, uint32_t *dst, uint n) {
for (unsigned int i = 0; i < n; i++) {
*dst++ = expand_1_to_4_lut[*src++];
}
}

void __not_in_flash("main") apply_colors(uint32_t *src, uint32_t *dst, uint32_t fg, uint32_t bg, uint n) {
fg *= 0x11111111;
bg *= 0x11111111;
uint32_t mask = fg ^ bg;
for (uint i = 0; i < n; i++) {
*dst++ = (*src++ & mask) ^ bg;
}
}

void __not_in_flash("main") process_scanline(const Run *runs, uint32_t y, uint32_t *outp) {
uint32_t outw = 0;
uint32_t outbitix = 0;
for (;;) {
const uint32_t *inp = runs->input;
if (inp == 0) {
break;
}
inp = (const uint32_t *)((const uint8_t *)inp + y * runs->stride);
int count = runs->count;
int inbitix = runs->bit_offset;
runs++;
uint32_t inw = *inp++;
outw |= (inw >> inbitix) << outbitix;
if (inbitix > outbitix) {
count -= 32 - inbitix;
outbitix += 32 - inbitix;
if (count <= 0) {
outbitix += count;
outw = (outw << (32 - outbitix)) >> (32 - outbitix);
continue;
}
} else {
count -= 32 - outbitix;
if (count >= 0) {
*outp++ = outw;
if (count == 0) {
outw = 0;
outbitix = 0;
continue;
}
outbitix -= inbitix;
if (outbitix != 0) {
outw = inw >> (32 - outbitix);
count -= outbitix;
if (count <= 0) {
outbitix += count;
outw = (outw << (32 - outbitix)) >> (32 - outbitix);
continue;
}
} else {
outw = 0;
}
} else {
outbitix = 32 + count;
outw = (outw << (-count)) >> (-count);
continue;
}
}
if (outbitix == 0) {
if ((count & 31) == 0) {
for (;;) {
*outp++ = *inp++;
count -= 32;
if (count == 0) {
break;
}
}
outw = 0;
} else {
for (;;) {
outw = *inp++;
if (count < 32) {
outbitix = count;
outw = (outw << (32 - outbitix)) >> (32 - outbitix);
break;
}
count -= 32;
*outp++ = outw;
}
}
} else {
uint32_t frac = (count & 31) + outbitix;
if (frac < 32) {
for (;;) {
inw = *inp++;
outw |= inw << outbitix;
if (count < 32) {
outbitix += count;
outw = (outw << (32 - outbitix)) >> (32 - outbitix);
break;
}
count -= 32;
*outp++ = outw;
outw = inw >> (32 - outbitix);
}
} else if (frac == 32) {
for (;;) {
inw = *inp++;
outw |= inw << outbitix;
*outp++ = outw;
count -= 32;
if (count < 0) {
break;
}
outw = inw >> (32 - outbitix);
}
outw = 0;
outbitix = 0;
} else {
for (;;) {
inw = *inp++;
outw |= inw << outbitix;
*outp++ = outw;
outw = inw >> (32 - outbitix);
count -= 32;
if (count <= 0) {
outbitix += count;
outw = (outw << (32 - outbitix)) >> (32 - outbitix);
break;
}
}
}
}
}
}

extern const uint32_t tmds_table_4bpp[];

void __not_in_flash("main") make_1bpp_pal(uint32_t pal[16], uint bg, uint fg) {
for (uint chan = 0; chan < 3; chan++) {
uint bg_g = (bg >> (chan * 4)) & 0xf;
uint fg_g = (fg >> (chan * 4)) & 0xf;
pal[chan] = tmds_table_4bpp[bg_g * 0x11];
pal[chan + 4] = tmds_table_4bpp[bg_g * 0x10 + fg_g];
pal[chan + 8] = tmds_table_4bpp[fg_g * 0x10 + bg_g];
pal[chan + 12] = tmds_table_4bpp[fg_g * 0x11];
}
}
16 changes: 16 additions & 0 deletions software/apps/colortext/gen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
void init_expand_lut();
void expand_1_to_4(uint8_t *src, uint32_t *dst, uint n);
void apply_colors(uint32_t *src, uint32_t *dst, uint32_t fg, uint32_t bg, uint n);

void make_1bpp_pal(uint32_t pal[16], uint bg, uint fg);

typedef struct Run {
// NULL for sentinel
const uint32_t *input;
// stride in bytes (must be multiple of 4)
uint32_t stride;
uint16_t bit_offset;
uint16_t count;
} Run;

void process_scanline(const Run *runs, uint32_t y, uint32_t *outp);
Loading