implemented demoscene waving text mode

This commit is contained in:
true 2024-10-26 05:25:34 -07:00
parent 4d8e037000
commit 0d9e96180a
5 changed files with 137 additions and 49 deletions

View File

@ -20,8 +20,8 @@ const MenuItem menu_0 = {7, MENU_FLAG_SCROLL,
0, 0, &menu_0_disp, &menu_0_enter};
// name menu
// set name, display mode, flip mode, font select, char spacing, half-width, color invert
const MenuItem menu_1 = {7, MENU_FLAG_SCROLL | MENU_FLAG_SAVE_ON_EXIT,
// set name, display mode, flip mode, font select, char spacing, y-offset, half-width, color invert
const MenuItem menu_1 = {8, MENU_FLAG_SCROLL | MENU_FLAG_SAVE_ON_EXIT,
(MenuItem *)&menu_0, 1, &menu_1_disp, &menu_1_enter};
// led menu

View File

@ -19,8 +19,8 @@
#include <stdio.h>
#define ROTATE_TARGET_WIDTH 40
#define ROTATE_TARGET_HEIGHT 32
#define ROTATE_TARGET_WIDTH 40
#define ROTATE_TARGET_HEIGHT 32
#define ROTATE_NAME_LEN_FULLRATE 15 // set to length in characters of name to run at
#define ROTATE_NAME_LEN_HALFRATE 15 // the specified rate, max. exceeding half rate
@ -29,6 +29,12 @@
// if no i2c DMA, then set based on reported CPU
// usage per update rate, and tweak update rate.
#define DEMOWAVE_SPD1 3 // how much to add each wave frame (max 256)
#define DEMOWAVE_ADD1 13 // how much to add to each character during rendering
#define DEMOWAVE_SPD2 5
#define DEMOWAVE_ADD2 25
uint8_t rotsrc_fb[(ROTATE_TARGET_WIDTH * (ROTATE_TARGET_HEIGHT >> 3)) + 1];
uint8_t rotdst_fb[(ROTATE_TARGET_WIDTH * (ROTATE_TARGET_HEIGHT >> 3)) + 1];
@ -37,6 +43,7 @@ SSD1306 rotdst;
uint8_t wiggle = 1;
int8_t waves = 0;
static void menu_none_init()
@ -103,10 +110,16 @@ void menu_none_disp(uint8_t idx)
uint16_t w;
int8_t left, top;
int8_t rot;
int8_t rot;
int8_t v, s;
int8_t add, speed;
uint8_t disp_mode;
char txt[6];
menu_none_init();
// total width and left / starting boundary
@ -124,12 +137,14 @@ void menu_none_disp(uint8_t idx)
left = (oled.width >> 1) - (w >> 1);
top = oled.height - ssd1306fb_get_font_height(font_table[uconf.font_idx].font) - 1;
top += uconf.y_offset;
// get rotation
rot = accel_get_rotation(&accel);
// render modes
switch (uconf.nameconf & UCONF_NAME_DISP_MASK) {
disp_mode = uconf.nameconf & UCONF_NAME_DISP_MASK;
switch (disp_mode) {
case UCONF_NAME_DISP_STATIC_HORIZ: {
menu_none_set_flipmirror(SYS_OLED_ROTATE_X);
@ -151,7 +166,7 @@ void menu_none_disp(uint8_t idx)
case UCONF_NAME_DISP_WIGGLE: {
menu_none_set_flipmirror(SYS_OLED_ROTATE_X);
// why this value? why the fuck not. value is the "speed" of the wiggle
// why this value? why not. value is the "speed" of the wiggle
wiggle += MISC_WIGGLE_RATE;
wiggle += (uconf.framemod == UCONF_FRAMERATE_FULL) ? 0 : MISC_WIGGLE_RATE;
// the shift is the maximum "angle" of the wiggle
@ -229,6 +244,47 @@ MENU_0_DISP_CHAR_ROTATE:
break;
}
case UCONF_NAME_DISP_DEMOWAVE1:
case UCONF_NAME_DISP_DEMOWAVE2: {
add = (disp_mode == UCONF_NAME_DISP_DEMOWAVE1) ? DEMOWAVE_ADD1 : DEMOWAVE_ADD2;
speed = (disp_mode == UCONF_NAME_DISP_DEMOWAVE1) ? DEMOWAVE_SPD1 : DEMOWAVE_SPD2;
menu_none_set_flipmirror(SYS_OLED_ROTATE_X);
// set pixel printing color - only set it on the output, not on rotation buffers
ssd1306fb_set_target(&oled);
ssd1306fb_set_color(uconf.nameconf & UCONF_NAME_MODE_COLOR_INVERT ?
SSD1306_STATE_INVERT_PIXEL : SSD1306_STATE_SET_PIXEL);
j = strlen(uconf.name);
v = waves; // per-character angle
v = (uint8_t)v + (uint8_t)speed;
waves = v; // per-frame starting angle
ssd1306fb_set_target(&oled);
top -= (ssd1306fb_get_font_height(font_table[uconf.font_idx].font) - 1) >> 2;
top--;
for (j = 0; j < strlen(uconf.name); j++) {
txt[0] = uconf.name[j];
o = ssd1306fb_get_str_width(font_table[uconf.font_idx].font, txt, 1, 0);
v = (uint8_t)v + (uint8_t)add;
s = sin7(v); // get character's position on y
s += 0x7f; // offset center
s = (uint8_t)s >> 4; // decrease magnitude
ssd1306fb_set_cursor(left, top + s);
ssd1306fb_draw_str(font_table[uconf.font_idx].font, txt, 0);
left += o + uconf.char_spacing; // next character
}
break;
}
}
ssd1306fb_set_target(&oled);

View File

@ -19,6 +19,15 @@
#define EDIT_MODE_IDLE 0x01
#define EDIT_MODE_EDIT 0x02
#define LI_NAME_SET 0
#define LI_ORIENTATION 1
#define LI_FLIP 2
#define LI_FONT 3
#define LI_CHAR_SPACING 4
#define LI_Y_OFFSET 5
#define LI_HALFWIDTH 6
#define LI_PIXEL_DRAWMODE 7
static uint8_t menu_last;
static uint8_t edit_mode = 0;
@ -115,17 +124,6 @@ void menu_1_btn_exit(uint8_t idx)
edit_mode = EDIT_MODE_OFF;
menu_btn_use_std();
} else {
// delete
/*
if (strlen(uconf.name)) {
if (edit_pos) {
for (i = edit_pos; i < strlen(uconf.name) - 1; i++) {
uconf.name[i] = uconf.name[i+1];
}
uconf.name[i] = 0x00;
}
}*/
// backspace
if (edit_pos && (uconf.name[0] != 0)) {
for (i = edit_pos - 1; i < strlen(uconf.name); i++) {
@ -221,12 +219,12 @@ void menu_1_disp(uint8_t idx)
// which item selected?
switch (idx) {
case 0: {
case LI_NAME_SET: {
ssd1306fb_draw_str(font_table[0].font, "Set Your Name", 1);
strcpy(txt, "Set>");
break;
}
case 1: {
case LI_ORIENTATION: {
MENU_0_ORIENTATION:
ssd1306fb_draw_str(font_table[0].font, "Nametag Orientation", 1);
switch (uconf.nameconf & UCONF_NAME_DISP_MASK) {
@ -247,10 +245,18 @@ MENU_0_ORIENTATION:
strcpy(txt, "Always UP");
break;
}
case UCONF_NAME_DISP_DEMOWAVE1: {
strcpy(txt, "Waves1");
break;
}
case UCONF_NAME_DISP_DEMOWAVE2: {
strcpy(txt, "Waves2");
break;
}
}
break;
}
case 2: {
case LI_FLIP: {
if ((uconf.nameconf & UCONF_NAME_DISP_MASK) != UCONF_NAME_DISP_CHAR_ROTATE) {
ssd1306fb_draw_str(font_table[0].font, "Nametag Flip", 1);
@ -274,7 +280,7 @@ MENU_0_ORIENTATION:
}
break;
}
case 3: {
case LI_FONT: {
MENU_0_FONT:
ssd1306fb_draw_str(font_table[0].font, "Font", 1);
@ -288,17 +294,22 @@ MENU_0_FONT:
goto MENU_0_DRAW_TEXT_DONE;
break;
}
case 4: {
case LI_CHAR_SPACING: {
ssd1306fb_draw_str(font_table[0].font, "Character Spacing (px)", 1);
sprintf(txt, "%d", (int8_t)uconf.char_spacing);
break;
}
case 5: {
case LI_Y_OFFSET: {
ssd1306fb_draw_str(font_table[0].font, "Render Y Offset (px)", 1);
sprintf(txt, "%d", (int8_t)uconf.y_offset);
break;
}
case LI_HALFWIDTH: {
ssd1306fb_draw_str(font_table[0].font, "Render at Half Width?", 1);
strcpy(txt, (uconf.nameconf & UCONF_NAME_MODE_HALFWIDTH) ? "Yes" : "No");
break;
}
case 6: {
case LI_PIXEL_DRAWMODE: {
ssd1306fb_draw_str(font_table[0].font, "Pixel Draw Mode", 1);
strcpy(txt, (uconf.nameconf & UCONF_NAME_MODE_COLOR_INVERT) ? "Invert" : "Bright");
break;
@ -336,25 +347,31 @@ void menu_1_enter(uint8_t idx)
int8_t a;
switch (idx) {
case 0: {
case LI_NAME_SET: {
// start the name editor...
edit_mode = EDIT_MODE_IDLE;
edit_pos = 0;
return;
}
case 1: { // display mode
case LI_ORIENTATION: { // display mode
a = (uconf.nameconf & UCONF_NAME_DISP_MASK) >> UCONF_NAME_DISP_OFFSET;
if (++a >= UCONF_NAME_DISP_COUNT) {
a = 0;
}
// currently unimplemented modes
switch (a) {
case 4: a++; break;
case 7: a = 0; break;
}
uconf.nameconf &= ~UCONF_NAME_DISP_MASK;
uconf.nameconf |= (a << UCONF_NAME_DISP_OFFSET) & UCONF_NAME_DISP_MASK;
return;
}
case 2: { // char flip mode
case LI_FLIP: { // char flip mode
if ((uconf.nameconf & UCONF_NAME_DISP_MASK) != UCONF_NAME_DISP_CHAR_ROTATE) {
if (uconf.nameconf & UCONF_NAME_MODE_AUTOROTATE) {
uconf.nameconf &= ~(UCONF_NAME_MODE_ROTATE180 | UCONF_NAME_MODE_AUTOROTATE);
@ -368,18 +385,25 @@ void menu_1_enter(uint8_t idx)
return;
}
case 3: { // font
case LI_FONT: { // font
menu_1_font_next();
break;
}
case 4: {
case LI_CHAR_SPACING: {
if (++uconf.char_spacing > 9) {
uconf.char_spacing = -1;
}
break;
}
case 5: {
case LI_Y_OFFSET: {
if (++uconf.y_offset > 8) {
uconf.y_offset = -4;
}
break;
}
case LI_HALFWIDTH: {
if (uconf.nameconf & UCONF_NAME_MODE_HALFWIDTH) {
uconf.nameconf &= ~UCONF_NAME_MODE_HALFWIDTH;
} else {
@ -387,7 +411,7 @@ void menu_1_enter(uint8_t idx)
}
break;
}
case 6: {
case LI_PIXEL_DRAWMODE: {
if (uconf.nameconf & UCONF_NAME_MODE_COLOR_INVERT) {
uconf.nameconf &= ~UCONF_NAME_MODE_COLOR_INVERT;
} else {

View File

@ -39,12 +39,14 @@ static void uconf_defaults()
uconf.ver = UCONF_VER;
uconf.flags = UCONF_FLAGS_LEDS_ENABLE;
uconf.framemod = UCONF_FRAMERATE_FULL;
uconf.nameconf = UCONF_NAME_DISP_CHAR_ROTATE | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT;
uconf.nameconf = UCONF_NAME_DISP_DEMOWAVE1 | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT;
// UCONF_NAME_DISP_DEMOWAVES1 | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT;
if (uconf_flash_offset == 0xf0) {
uconf.iter = 0;
}
uconf.font_idx = 3;
uconf.font_idx = 4;
uconf.char_spacing = 2;
uconf.y_offset = 0;
// todo: add LUT
strcpy(uconf.name, "Supercon");

View File

@ -24,12 +24,13 @@
// system state stuff
#define SYS_OLED_ROTATE_X (1 << 0)
#define SYS_OLED_ROTATE_Y (1 << 1)
#define SYS_OLED_REVERSE_CHARS (1 << 2)
#define SYS_OLED_REVERSE_CHARS (1 << 2) // todo: figure out wtf this is
// user configuration stuff
#define UCONF_VER 0x03
#define UCONF_FLAGS_AUTOROTATE_ENA (1 << 0)
#define UCONF_FLAGS_AD_BANNER (1 << 1) // show conference banner text
#define UCONF_FLAGS_LEDS_DISABLE (1 << 3) // used by programs to temporarily disable LEDs
#define UCONF_FLAGS_FAVOR_SPEED (1 << 4) // todo: increase clock rather than reduce framerate
#define UCONF_FLAGS_LEDS_ENABLE (1 << 5) // used by user in options menu to enable / disable RGBLEDs
@ -46,13 +47,16 @@
#define UCONF_NAME_MODE_HALFWIDTH (1 << 2) // render only every other line of fonts
#define UCONF_NAME_MODE_COLOR_INVERT (1 << 3) // use pixel invert instead of set
#define UCONF_NAME_DISP_MASK 0x30
#define UCONF_NAME_DISP_COUNT 4
#define UCONF_NAME_DISP_MASK 0x70
#define UCONF_NAME_DISP_COUNT 8
#define UCONF_NAME_DISP_OFFSET 4
#define UCONF_NAME_DISP_STATIC_HORIZ 0x00 // unchanging name
#define UCONF_NAME_DISP_STATIC_VERT 0x10 // unchanging name, each char rotated 90deg
#define UCONF_NAME_DISP_WIGGLE 0x20 // sine-wiggling name
#define UCONF_NAME_DISP_CHAR_ROTATE 0x30 // auto-rotating characters
#define UCONF_NAME_DISP_STATIC_HORIZ 0x00 // unchanging name
#define UCONF_NAME_DISP_STATIC_VERT 0x10 // unchanging name, each char rotated 90deg
#define UCONF_NAME_DISP_WIGGLE 0x20 // sine-wiggling name
#define UCONF_NAME_DISP_CHAR_ROTATE 0x30 // auto-rotating characters
#define UCONF_NAME_DISP_CHAR_ROTATE_WIG 0x40 // auto-rotating characters plus wiggle (not implemented)
#define UCONF_NAME_DISP_DEMOWAVE1 0x50 // waving letters like in demoscene stuff
#define UCONF_NAME_DISP_DEMOWAVE2 0x60
@ -65,19 +69,21 @@ typedef struct UserConf {
uint32_t iter; // 8
uint8_t font_idx;
int8_t char_spacing; // 10
char name[UCONF_NAME_MAXLEN + 1]; // 26
char name2[UCONF_NAME_MAXLEN + 1]; // 42
int8_t y_offset; // 11
uint8_t pad12; // 12
char name[UCONF_NAME_MAXLEN + 1]; // 28
char name2[UCONF_NAME_MAXLEN + 1]; // 44
uint8_t favcolor_hue;
uint8_t favcolor_sat;
uint8_t favcolor_val; // 45
uint8_t favcolor_val; // 47
uint8_t altcolor_hue;
uint8_t altcolor_sat;
uint8_t altcolor_val; // 48
uint8_t altcolor_val; // 50
uint8_t ledprog_rgb_idx;
uint8_t padding0; // 50
uint8_t ledprog_rgb[16]; // 66
uint8_t ledprog_rgb_data[16][8]; // 194
uint8_t padding1[54]; // 248
uint8_t padding0; // 52
uint8_t ledprog_rgb[16]; // 68
uint8_t ledprog_rgb_data[16][8]; // 196
uint8_t padding1[52]; // 248
uint16_t lsens_dark_thresh; // 250
uint16_t sleep_timeout; // 252
uint16_t tempcx10_offset; // 253-254