diff options
-rw-r--r-- | gradient.h | 1 | ||||
-rw-r--r-- | led_gradient.c | 140 | ||||
-rw-r--r-- | makefile | 2 |
3 files changed, 115 insertions, 28 deletions
@@ -8,6 +8,7 @@ #define MODIFY_SIZE 6 #define EXITED 7 + typedef struct splits { unsigned int color; unsigned int size; diff --git a/led_gradient.c b/led_gradient.c index 40c3fc5..b09708f 100644 --- a/led_gradient.c +++ b/led_gradient.c @@ -11,7 +11,7 @@ void refresh_strip(ws2811_t *ledstring, segment_t *segments, unsigned int segment_amount) { unsigned int s = 0; - unsigned int led; + unsigned int led = 0; for(; s < segment_amount; s++) { for(; led < segments[s].size; led++) { ledstring->channel[0].leds[led] = segments[s].color; @@ -33,13 +33,27 @@ unsigned int find_starting_pos(segment_t *segments, unsigned int index) { int main() { + initscr(); + clear(); + noecho(); + cbreak(); + keypad(stdscr, TRUE); + + ws2811_return_t ret; + if((ret = ws2811_init(&ledstring)) != WS2811_SUCCESS) { + printf("Error initilizing ws8211 strip: %s\n", ws2811_get_return_t_str(ret)); + return(ret); + } + + segment_t *segments = malloc(sizeof(segment_t)); //just start with one segments[0].size = LED_COUNT - 1; + segments[0].color = 0; - int prev_program_state = VIEW_MODE; + int prev_program_state = EXITED; int program_state = VIEW_MODE; int ui_selection = 0; - unsigned int i; + unsigned int i = 0; unsigned int starting_pos; unsigned int segment_selection = 0; unsigned int segment_quanity = 1; @@ -50,50 +64,63 @@ int main() { int user_key; + char *main_msg = "Press the arrow keys to select the segment, and enter to edit it.\nTo create new segments, select the segment you want to divide.\n"; - char *modification_menu[6] = { + char *modification_menu[7] = { "Change red", "Change green", "Change blue", "Change size", "Subdivide (create segment)", + "Delete", "Go back" }; - int modification_menu_items = 6; + int modification_menu_items = 7; for(;;) { + //prev_program_state = program_state; if(prev_program_state != program_state) { switch(program_state) { case MODIFY_MODE: + clear(); for(i = 0; i < modification_menu_items; i++) { cbreak(); - if(ui_selection = i) attron(A_STANDOUT); - printw("%s\n", modification_menu); - if(ui_selection = i) attroff(A_STANDOUT); + if(ui_selection == i) attron(A_STANDOUT); + printw("%s, %i, %i\n", modification_menu[i], ui_selection, user_key); + if(ui_selection == i) attroff(A_STANDOUT); } refresh(); break; case MODIFY_R: printw("Modifying red value.\n"); + refresh_strip(&ledstring, segments, segment_quanity); refresh(); break; case MODIFY_G: printw("Modifying green value.\n"); + refresh_strip(&ledstring, segments, segment_quanity); refresh(); break; case MODIFY_B: printw("Modifying blue value.\n"); + refresh_strip(&ledstring, segments, segment_quanity); refresh(); break; case MODIFY_SIZE: printw("Modifying size.\n"); + refresh_strip(&ledstring, segments, segment_quanity); refresh(); break; case VIEW_MODE: + clear(); + refresh_strip(&ledstring, segments, segment_quanity); + printw("%s\n", main_msg); cbreak(); break; case SELECT_MODE: - halfdelay(1); + clear(); + printw("Press enter to modify segment %i, or [q] to return.\n", segment_selection); + halfdelay(10); break; case EXITED: for(i = 0; i < LED_COUNT; i++) { @@ -114,6 +141,7 @@ int main() { if((user_key = getch()) != ERR) { switch(user_key) { + case KEY_UP: case KEY_LEFT: switch(program_state) { case VIEW_MODE: @@ -123,11 +151,27 @@ int main() { case SELECT_MODE: if(segment_selection < segment_quanity) segment_selection++; break; + case MODIFY_MODE: + if(ui_selection < modification_menu_items) ui_selection++; + break; + case MODIFY_R: + if ((segments[segment_selection].color >> 16) < 0xff) segments[segment_selection].color += 0x10000; + break; + case MODIFY_G: + if ((segments[segment_selection].color >> 8 & 0xff) < 0xff) segments[segment_selection].color += 0x100; + break; + case MODIFY_B: + if ((segments[segment_selection].color & 0xff) < 0xff) segments[segment_selection].color += 1; + break; + case MODIFY_SIZE: + if(find_starting_pos(segments, segment_quanity - 1) < LED_COUNT - 1) segments[segment_selection].size++; + break; default: break; } break; + case KEY_DOWN: case KEY_RIGHT: switch(program_state) { case VIEW_MODE: @@ -137,39 +181,82 @@ int main() { case SELECT_MODE: if(segment_selection > 0) segment_selection--; break; - default: - break; - } - break; - - case KEY_UP: - switch(program_state) { + case MODIFY_MODE: + if(ui_selection > 0) ui_selection--; case MODIFY_R: - if ((segments[segment_selection].color >> 16) < 0xff) segments[segment_selection].color += 0x10000; + if (!(segments[segment_selection].color >> 16)) segments[segment_selection].color -= 0x10000; break; case MODIFY_G: - if ((segments[segment_selection].color >> 8 & 0xff) < 0xff) segments[segment_selection].color += 0x100; + if (!(segments[segment_selection].color >> 8 & 0xff)) segments[segment_selection].color -= 0x100; break; case MODIFY_B: - if ((segments[segment_selection].color & 0xff) < 0xff) segments[segment_selection].color += 1; + if (!(segments[segment_selection].color & 0xff)) segments[segment_selection].color -= 1; break; case MODIFY_SIZE: - default: + if(segments[segment_selection].size >= 4) segments[segment_selection].size--; break; - } - break; - case KEY_DOWN: - switch(program_state) { default: break; } break; - case KEY_ENTER: + + case 10: switch(program_state) { case VIEW_MODE: program_state = SELECT_MODE; + break; + case SELECT_MODE: + program_state = MODIFY_MODE; + break; + case MODIFY_MODE: + switch(ui_selection) { + case 0: + program_state = MODIFY_R; + break; + case 1: + program_state = MODIFY_G; + break; + case 2: + program_state = MODIFY_B; + break; + case 3: + program_state = MODIFY_SIZE; + break; + case 4: + //create new segment + //TODO: prevent user stupidity + program_state = MODIFY_MODE; + segments[segment_selection].size = segments[segment_selection].size / 2; + segment_quanity++; + segments = realloc(segments, sizeof(segment_t) * segment_quanity); + memmove(&segments[segment_selection + 2], + &segments[segment_selection] + sizeof(segment_t), + &segments[segment_quanity - 1] - &segments[segment_selection + 1]); + memcpy(&segments[segment_selection + 1], &segments[segment_selection], sizeof(segment_t)); + segment_selection++; + break; + case 5: + program_state = VIEW_MODE; + segments[segment_selection + 1].size += segments[segment_selection].size; + memmove(&segments[segment_selection], &segments[segment_selection + 1], &segments[segment_quanity] - &segments[segment_selection + 1]); + segment_quanity--; + segments = realloc(&segments, &segments[segment_quanity] - &segments[0]); + break; + case 6: + program_state = VIEW_MODE; + break; + default: + break; + } + break; + case MODIFY_R: + case MODIFY_G: + case MODIFY_B: + case MODIFY_SIZE: + program_state = MODIFY_MODE; + break; default: break; } @@ -199,14 +286,13 @@ int main() { default: break; } - prev_program_state = program_state; } else if(program_state = SELECT_MODE) { starting_pos = find_starting_pos(segments, segment_selection); for(i = starting_pos; i <= starting_pos + segments[segment_selection].size; i++) { ledstring.channel[0].leds[i] = (selection_state ? (i % 2) : ((i+1) % 2)) ? 0xffffff : 0; } - selection_state ? 0 : 1; + selection_state = selection_state ? 0 : 1; ws2811_render(&ledstring); } } @@ -3,4 +3,4 @@ make tester: make clear: gcc -o led_clear led_clear.c -lws2811 -lm make grad: - gcc -o grad led_gradient.c -lws2811 -lm -lncurses + gcc -o grad led_gradient.c -lws2811 -lm -lncurses -ggdb |