From 7829d932d53ae4a5e699022da8db64509db554f2 Mon Sep 17 00:00:00 2001 From: Viktor Limishenko Date: Wed, 18 Nov 2020 22:36:02 +0200 Subject: [PATCH] Rework render to processing every mode in the own task --- inc/Render.h | 1 + src/ModeConfig.c | 4 +- src/Render.c | 704 +++++++++++++++++++++++++---------------------- 3 files changed, 385 insertions(+), 324 deletions(-) diff --git a/inc/Render.h b/inc/Render.h index 546e807..59e456a 100644 --- a/inc/Render.h +++ b/inc/Render.h @@ -18,6 +18,7 @@ typedef struct matrixModeState { int tail; } matrixModeState; +void Render_changeRenderHandler(); void Render_init(); //setings for the led matrix diff --git a/src/ModeConfig.c b/src/ModeConfig.c index 6d0980c..2480ddd 100644 --- a/src/ModeConfig.c +++ b/src/ModeConfig.c @@ -2,6 +2,7 @@ #include "espressif/esp_common.h" #include "string.h" #include "Common.h" +#include "Render.h" static struct parserData_t s_currentData; @@ -28,6 +29,7 @@ void ModeConfig_setMode(char *uri) { } else if (strstr(uri, "DISABLE")) { s_currentData.currentMode = DISABLE_MODE; } + Render_changeRenderHandler(); } static void ModeConfig_setDirection(char *uri) { @@ -119,7 +121,7 @@ void ModeConfig_setConfig(char *uri, enum ActionType l_type) { void ModeConfig_init() { s_currentData.currentHue = 196; - s_currentData.currentMode = VAGINE_MODE; + s_currentData.currentMode = RAINBOW_MODE; s_currentData.currentSnowLife = DEFAULT_SNOW_LIFE; s_currentData.currentSnowNumber = DEFAULT_SNOW_NUMBER; s_currentData.currentSpeed = FAST; diff --git a/src/Render.c b/src/Render.c index dd1d25d..b857669 100644 --- a/src/Render.c +++ b/src/Render.c @@ -33,11 +33,12 @@ #define SNOW_LIFE 30 * 2 // 5sec; #define SNOW_NUMBER 15 -int s_frame = 0; +static int s_activeRenderMode = NULL; +static TaskHandle_t s_currentRenderTask = NULL; + +QueueHandle_t m_render_queue; +static ws2812_pixel_t s_pixels[LED_NUMBER]; -void Render_resetFrame() { - s_frame = 0; -} static void Render_fillBlack(hsv_t pixels[WIDTH][HEIGHT]) { for (int x = 0; x < WIDTH; x++) { @@ -47,16 +48,6 @@ static void Render_fillBlack(hsv_t pixels[WIDTH][HEIGHT]) { } } -static void Render_flatArray(hsv_t src[WIDTH][HEIGHT], hsv_t *flated) { - for (int x = 0; x < WIDTH; x++) { - for (int y = 0; y < HEIGHT; y++) { - flated[y + HEIGHT * x] = src[x][y]; - } - } -} - -static QueueHandle_t m_render_queue; - static void revertOdd(hsv_t *rawData, ws2812_pixel_t *pixels) { for (int x = 0; x < WIDTH; x++) { @@ -79,391 +70,458 @@ static void Render_revertOdd(hsv_t rawData[WIDTH][HEIGHT], ws2812_pixel_t *pixel } } -static void Render_generateRainbow(int frame, ws2812_pixel_t *pixels, - bool vertical, int speed, bool direction) { - int l_ledsInGradient = vertical ? HEIGHT : WIDTH; - hsv_t l_data; - for (int x = 0; x < WIDTH; x++) { - int l_locX = direction ? x : WIDTH - x - 1; - int l_pos = 0; - if (!vertical) - l_pos = (int)(((double)frame) * speed + - (double)l_locX * 360 / l_ledsInGradient) % - 360; - for (int y = 0; y < HEIGHT; y++) { - int locY = (l_locX % 2) ? y : HEIGHT - y - 1; - locY = direction ? locY : HEIGHT - locY - 1; - if (vertical) - l_pos = (int)(((double)frame) * speed + - (double)locY * 360 / l_ledsInGradient) % - 360; - l_data.h = (double)l_pos; - l_data.s = 1.0; - l_data.v = 1.0; - - pixels[x * HEIGHT + y] = Color_hsv2rgb(l_data); + +static void s_Render_RainbowTask(ws2812_pixel_t *pixels) { + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, 0xffffffffUL)) { + printf("Running rainbow task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); + + + int l_ledsInGradient = l_params->rainbowAlign ? HEIGHT : WIDTH; + hsv_t l_data; + for (int x = 0; x < WIDTH; x++) { + int l_locX = l_params->currentDirection ? x : WIDTH - x - 1; + int l_pos = 0; + if (!l_params->rainbowAlign) + l_pos = (int)(((double)l_frame) * l_params->currentSpeed + + (double)l_locX * 360 / l_ledsInGradient) % + 360; + for (int y = 0; y < HEIGHT; y++) { + int locY = (l_locX % 2) ? y : HEIGHT - y - 1; + locY = l_params->currentDirection ? locY : HEIGHT - locY - 1; + if (l_params->rainbowAlign) + l_pos = (int)(((double)l_frame) * l_params->currentSpeed + + (double)locY * 360 / l_ledsInGradient) % + 360; + l_data.h = (double)l_pos; + l_data.s = 1.0; + l_data.v = 1.0; + + pixels[x * HEIGHT + y] = Color_hsv2rgb(l_data); + } + } + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } } +static void s_Render_WaveTask(ws2812_pixel_t *pixels) { + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); + + + hsv_t data[HEIGHT*WIDTH]; + for (int x = 0; x < WIDTH; x++) { + int l_locX = l_params->currentMirror ? x : WIDTH - x - 1; + for (int y = 0; y < HEIGHT; y++) { + int l_locY = l_params->currentDirection ? HEIGHT - y - 1 : y; + hsv_t l_data; + l_data.h = l_params->currentHue; + l_data.s = 1; + l_data.v = 1; + if (((y + l_frame / (11 - l_params->currentSpeed)) % HEIGHT >= (x / 3 + 3)) && + ((y + l_frame / (11 - l_params->currentSpeed)) % HEIGHT < (x / 3 + 6))) { + } else { + l_data.v = 0; + } + data[l_locX * HEIGHT + l_locY] = l_data; + } + } + revertOdd(data, pixels); -static void Render_generateWave(int frame, ws2812_pixel_t *pixels, - bool direction, int speed, bool mirror, - int hue) { - - hsv_t data[HEIGHT*WIDTH]; - for (int x = 0; x < WIDTH; x++) { - int l_locX = mirror ? x : WIDTH - x - 1; - for (int y = 0; y < HEIGHT; y++) { - int l_locY = direction ? HEIGHT - y - 1 : y; - hsv_t l_data; - l_data.h = hue; - l_data.s = 1; - l_data.v = 1; - if (((y + frame / (11 - speed)) % HEIGHT >= (x / 3 + 3)) && - ((y + frame / (11 - speed)) % HEIGHT < (x / 3 + 6))) { - } else { - l_data.v = 0; - } - data[l_locX * HEIGHT + l_locY] = l_data; + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } - revertOdd(data, pixels); } -static int m_coef = 3; -static int m_matrixOffset = (int)ceil(HEIGHT/3); -static int m_phase = 0; -static int m_speed = 0; -static void Render_generateTapes(int frame, ws2812_pixel_t *pixels, int speed, - int hue) { - hsv_t data[HEIGHT*WIDTH]; - m_speed = speed; - for (int x = 0; x < WIDTH; x++) { - for (int y = 0; y < HEIGHT; y++) { - hsv_t l_data; - l_data.h = hue; - l_data.s = 1; - l_data.v = 0; - if ( - ((frame / (10 / speed) + y) % (m_matrixOffset * 2) == (int)(x / m_coef)) - || ((frame / (10 / speed) + y - 3) % (m_matrixOffset * 2) == (int)((x) / -m_coef) + ceil(HEIGHT / 2 -1)) - ) { - l_data.v = m_phase ? (float)(1 - (float)m_phase / 10) : 1; - if(m_phase > 0 && y > 0) { - data[x * WIDTH + y - 1].v = (float)m_phase / 10; +static void s_Render_TapesTask(ws2812_pixel_t *pixels) { + + static int m_coef = 3; + static int m_matrixOffset = (int)ceil(HEIGHT/3); + static int m_phase = 0; + static int m_speed = 0; + + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); + + + hsv_t data[HEIGHT*WIDTH]; + m_speed = l_params->currentSpeed; + for (int x = 0; x < WIDTH; x++) { + for (int y = 0; y < HEIGHT; y++) { + hsv_t l_data; + l_data.h = l_params->currentHue; + l_data.s = 1; + l_data.v = 0; + if ( + ((l_frame / (10 / l_params->currentSpeed) + y) % (m_matrixOffset * 2) == (int)(x / m_coef)) + || ((l_frame / (10 / l_params->currentSpeed) + y - 3) % (m_matrixOffset * 2) == (int)((x) / -m_coef) + ceil(HEIGHT / 2 -1)) + ) { + l_data.v = m_phase ? (float)(1 - (float)m_phase / 10) : 1; + if(m_phase > 0 && y > 0) { + data[x * WIDTH + y - 1].v = (float)m_phase / 10; + } + } + data[x * HEIGHT + y] = l_data; } } - data[x * HEIGHT + y] = l_data; + revertOdd(data, pixels); + m_phase = (m_phase + l_params->currentSpeed) % 10; + if(m_speed != l_params->currentSpeed) m_phase = 0; + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } - revertOdd(data, pixels); - m_phase = (m_phase + speed) % 10; - if(m_speed != speed) m_phase = 0; } -static struct snow_item m_snowArr[SNOW_NUMBER]; -static bool m_vacantPos[SNOW_NUMBER] = {true, true, true, true, +static void s_Render_SnowTask(ws2812_pixel_t *pixels) { + + static struct snow_item m_snowArr[SNOW_NUMBER]; + static bool m_vacantPos[SNOW_NUMBER] = {true, true, true, true, true, true, true}; -static void Render_generateSnow(ws2812_pixel_t *pixels, int hue) { + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); - int l_vacance = -1; - for (int i = 0; i < SNOW_NUMBER; i++) { - if (m_vacantPos[i]) { - l_vacance = i; - break; - } - } + int l_vacance = -1; - if (l_vacance != -1) { - if ((int)((uint32_t)random()) % 10 > 4) { - ; - } else { - struct snow_item l_item; - - l_item.x = (int)((uint32_t)random()) % WIDTH; - l_item.y = (int)((uint32_t)random()) % HEIGHT; - l_item.age = SNOW_LIFE + (int)((uint32_t)random()) % 35; - l_item.maxAge = l_item.age; - m_snowArr[l_vacance] = l_item; - m_vacantPos[l_vacance] = false; - } - } - for (int x = 0; x < WIDTH; x++) { - for (int y = 0; y < HEIGHT; y++) { - pixels[x * HEIGHT + y] = Color_hexToRGB(0x000000); + for (int i = 0; i < SNOW_NUMBER; i++) { + if (m_vacantPos[i]) { + l_vacance = i; + break; + } + } + + if (l_vacance != -1) { + if ((int)((uint32_t)random()) % 10 > 4) { + ; + } else { + struct snow_item l_item; + + l_item.x = (int)((uint32_t)random()) % WIDTH; + l_item.y = (int)((uint32_t)random()) % HEIGHT; + l_item.age = SNOW_LIFE + (int)((uint32_t)random()) % 35; + l_item.maxAge = l_item.age; + m_snowArr[l_vacance] = l_item; + m_vacantPos[l_vacance] = false; + } + } + for (int x = 0; x < WIDTH; x++) { + for (int y = 0; y < HEIGHT; y++) { + pixels[x * HEIGHT + y] = Color_hexToRGB(0x000000); + } + } + for (int i = 0; i < SNOW_NUMBER; i++) { + if (!m_vacantPos[i]) { + hsv_t l_data; + int l_maxAge = m_snowArr[i].maxAge; + float l_deca = m_snowArr[i].maxAge / 5; + int l_age = m_snowArr[i].age; + int l_maxValueAge = (int)(l_maxAge - l_deca); + if (l_age > l_maxValueAge) + l_data.v = (l_maxAge - l_age) / l_deca; + else + l_data.v = (float)l_age / l_maxValueAge; + l_data.h = l_params->currentHue; + l_data.s = 1; + pixels[m_snowArr[i].x * HEIGHT + m_snowArr[i].y] = + Color_hsv2rgb(l_data); + if (l_age <= 0) + m_vacantPos[i] = true; + else + m_snowArr[i].age--; + } + } + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } - for (int i = 0; i < SNOW_NUMBER; i++) { - if (!m_vacantPos[i]) { +} + +static void s_Render_TornadoTask(ws2812_pixel_t *pixels) { + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); + + + hsv_t data[HEIGHT*WIDTH]; + + for (int x = 0; x < WIDTH; x++) { + for (int y = 0; y < HEIGHT; y++) { + hsv_t l_data; + l_data.h = 0; + l_data.s = 1; + l_data.v = 0; + + data[x * HEIGHT + y] = l_data; + } + } + int l_currentPos = l_frame % (WIDTH * HEIGHT); + int l_currentX = l_currentPos % WIDTH; + int l_currentY = (int)l_currentPos / WIDTH; + for (int i = 0; i < l_params->currentTailLength; i++) { + int l_tailPos = l_currentPos - 1 - i; + if (l_tailPos < 0) + l_tailPos = WIDTH * HEIGHT + l_tailPos; + int l_tailX = l_tailPos % WIDTH; + int l_tailY = (int)l_tailPos / WIDTH; + int l_currTailPos = (l_tailX * HEIGHT + l_tailY) % (WIDTH * HEIGHT); + hsv_t l_data; + l_data.h = l_params->currentTailHue; + l_data.s = 1; + l_data.v = (float)1 / (i * i * 0.5 + 1); + data[l_currTailPos] = l_data; + } hsv_t l_data; - int l_maxAge = m_snowArr[i].maxAge; - float l_deca = m_snowArr[i].maxAge / 5; - int l_age = m_snowArr[i].age; - int l_maxValueAge = (int)(l_maxAge - l_deca); - if (l_age > l_maxValueAge) - l_data.v = (l_maxAge - l_age) / l_deca; - else - l_data.v = (float)l_age / l_maxValueAge; - l_data.h = hue; l_data.s = 1; - pixels[m_snowArr[i].x * HEIGHT + m_snowArr[i].y] = - Color_hsv2rgb(l_data); - if (l_age <= 0) - m_vacantPos[i] = true; - else - m_snowArr[i].age--; + l_data.v = 1; + l_data.h = l_params->currentTailHue; + data[l_currentX * HEIGHT + l_currentY] = l_data; + revertOdd(data, pixels); + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } } -int s_ageDivider = 3; -#define MATRIX_MAX_COUNT 10 -static struct matrixModeState s_matrixItems[MATRIX_MAX_COUNT]; +static void s_Render_ShutdownTask(ws2812_pixel_t *pixels) { + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); -static void Render_generateMatrix(ws2812_pixel_t *pixels, int hue, int tailLength) { - hsv_t data[WIDTH][HEIGHT]; - Render_fillBlack(data); - int l_emptyPos = -1; - for (int i = 0; i < MATRIX_MAX_COUNT; i++) { - if(s_matrixItems[i].age > (HEIGHT - 1)*s_ageDivider + s_matrixItems[i].tail) { - l_emptyPos = i; - break; + + hsv_t data[WIDTH][HEIGHT]; + Render_fillBlack(data); + Render_revertOdd(data, pixels); + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } - if(l_emptyPos != -1) { - if((int)((uint32_t)random()) % 10 > 5) { - s_matrixItems[l_emptyPos].col = (int)((uint32_t)random()) % WIDTH; - s_matrixItems[l_emptyPos].age = 0; - s_matrixItems[l_emptyPos].tail = (int)((uint32_t)random()) % (HEIGHT/2) + 2; - } +} +static void s_Render_MatrixTask(ws2812_pixel_t *pixels) { + + int s_ageDivider = 3; + #define MATRIX_MAX_COUNT 10 + static struct matrixModeState s_matrixItems[MATRIX_MAX_COUNT]; + + for (int i = 0; i < MATRIX_MAX_COUNT; i++) { + s_matrixItems[i].age = 200; + s_matrixItems[i].col = 0; } - for(int i = 0; i < MATRIX_MAX_COUNT; i++) { - hsv_t l_data; - l_data.h = hue; - l_data.s = 1; - l_data.v = 1; - int l_pixelPosition = HEIGHT - 1 - (int)(s_matrixItems[i].age / s_ageDivider); - - if(s_matrixItems[i].col >= 0 && s_matrixItems[i].col < WIDTH) { - - if(l_pixelPosition < HEIGHT && l_pixelPosition >= 0){ - data[s_matrixItems[i].col][l_pixelPosition] = (l_data); - } - for (int j = 1; j <= s_matrixItems[i].tail; j++) { - hsv_t l_tailData; - l_tailData.h = hue; - l_tailData.s = 1; - l_tailData.v = 0.05; - int l_tailPosition = l_pixelPosition + j; - if(l_tailPosition < HEIGHT && l_tailPosition >= 0) { - data[s_matrixItems[i].col][l_tailPosition] = l_tailData; + + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); + + + hsv_t data[WIDTH][HEIGHT]; + Render_fillBlack(data); + int l_emptyPos = -1; + for (int i = 0; i < MATRIX_MAX_COUNT; i++) { + if(s_matrixItems[i].age > (HEIGHT - 1)*s_ageDivider + s_matrixItems[i].tail) { + l_emptyPos = i; + break; } } - } - s_matrixItems[i].age++; - } - Render_revertOdd(data, pixels); -} + if(l_emptyPos != -1) { + if((int)((uint32_t)random()) % 10 > 5) { + s_matrixItems[l_emptyPos].col = (int)((uint32_t)random()) % WIDTH; + s_matrixItems[l_emptyPos].age = 0; + s_matrixItems[l_emptyPos].tail = (int)((uint32_t)random()) % (HEIGHT/2) + 2; + } -const uint8_t s_vaginePixels[WIDTH][HEIGHT] = { - { 0x39, 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }, - { 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc }, - { 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7 }, - { 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8 }, - { 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd }, - { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, - { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xfc, 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, - { 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xfc, 0xfc, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab }, - { 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xfc, 0xfc, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab }, - { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xfc, 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, - { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, - { 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd }, - { 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8 }, - { 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7 }, - { 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc }, - { 0x39, 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }, -}; - -#define VAGINA_FRAMES 13 - -int colorQue[VAGINA_FRAMES] = { 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }; - -static void Render_generateVagine(int frame, ws2812_pixel_t *pixels, int hue, bool direction) { - hsv_t data[WIDTH][HEIGHT]; - Render_fillBlack(data); - int localFrame = direction ? frame % 360 : 360 - frame % 360 - 1; - - int centralHue = (localFrame * 5); - - hsv_t l_data; - for (int x = 0; x < WIDTH; x++) - { - for (int y = 0; y < HEIGHT; y++) - { - l_data.h = centralHue; - l_data.s = 1; - l_data.v = 1; - // if(colorQue[0] == s_vaginePixels[x][y]) { - int pos = 0; - for (int i = 0; i < VAGINA_FRAMES; i++) - { - if (s_vaginePixels[x][y] == colorQue[i]) { - pos = i; - break; + } + for(int i = 0; i < MATRIX_MAX_COUNT; i++) { + hsv_t l_data; + l_data.h = l_params->currentHue; + l_data.s = 1; + l_data.v = 1; + int l_pixelPosition = HEIGHT - 1 - (int)(s_matrixItems[i].age / s_ageDivider); + + if(s_matrixItems[i].col >= 0 && s_matrixItems[i].col < WIDTH) { + + if(l_pixelPosition < HEIGHT && l_pixelPosition >= 0){ + data[s_matrixItems[i].col][l_pixelPosition] = (l_data); + } + for (int j = 1; j <= s_matrixItems[i].tail; j++) { + hsv_t l_tailData; + l_tailData.h = l_params->currentHue; + l_tailData.s = 1; + l_tailData.v = 0.05; + int l_tailPosition = l_pixelPosition + j; + if(l_tailPosition < HEIGHT && l_tailPosition >= 0) { + data[s_matrixItems[i].col][l_tailPosition] = l_tailData; + } } } - l_data.h = (centralHue + pos*(360/VAGINA_FRAMES))%360; - - data[x][y] = l_data; - // } + s_matrixItems[i].age++; + } + Render_revertOdd(data, pixels); + + + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } - } - Render_revertOdd(data, pixels); } -static void Render_generateTornado(int frame, ws2812_pixel_t *pixels, - int tailHue, int tailLength, int hue) { +static void s_Render_VagineTask(ws2812_pixel_t *pixels) { + const uint8_t s_vaginePixels[WIDTH][HEIGHT] = { + { 0x39, 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }, + { 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc }, + { 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7 }, + { 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8 }, + { 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd }, + { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, + { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xfc, 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, + { 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xfc, 0xfc, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab }, + { 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xfc, 0xfc, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab }, + { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xfc, 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, + { 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b }, + { 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0xe5, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd }, + { 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0x80, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8 }, + { 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xdb, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7 }, + { 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0xbf, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc }, + { 0x39, 0xdc, 0xf7, 0xf8, 0xfd, 0x4b, 0xab, 0x77, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }, + }; + + #define VAGINA_FRAMES 13 + + int colorQue[VAGINA_FRAMES] = { 0xfc, 0xe5, 0x80, 0xdb, 0xbf, 0x77, 0xab, 0x4b, 0xfd, 0xf8, 0xf7, 0xdc, 0x39 }; + + int index; + int l_frame = 0; + while (1) { + if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { + printf("Running wave task\n"); + struct parserData_t *l_params = ModeConfig_getCurrentParams(); - hsv_t data[HEIGHT*WIDTH]; - for (int x = 0; x < WIDTH; x++) { - for (int y = 0; y < HEIGHT; y++) { + hsv_t data[WIDTH][HEIGHT]; + Render_fillBlack(data); + int localFrame = l_params->currentDirection ? l_frame % 360 : 360 - l_frame % 360 - 1; + + int centralHue = (localFrame * 5); + hsv_t l_data; - l_data.h = 0; - l_data.s = 1; - l_data.v = 0; + for (int x = 0; x < WIDTH; x++) + { + for (int y = 0; y < HEIGHT; y++) + { + l_data.h = centralHue; + l_data.s = 1; + l_data.v = 1; + int pos = 0; + for (int i = 0; i < VAGINA_FRAMES; i++) + { + if (s_vaginePixels[x][y] == colorQue[i]) { + pos = i; + break; + } + } + l_data.h = (centralHue + pos*(360/VAGINA_FRAMES))%360; + + data[x][y] = l_data; + } + + } + Render_revertOdd(data, pixels); + - data[x * HEIGHT + y] = l_data; + ws2812_i2s_update(pixels, PIXEL_RGB); + l_frame++; } } - int l_currentPos = frame % (WIDTH * HEIGHT); - int l_currentX = l_currentPos % WIDTH; - int l_currentY = (int)l_currentPos / WIDTH; - for (int i = 0; i < tailLength; i++) { - int l_tailPos = l_currentPos - 1 - i; - if (l_tailPos < 0) - l_tailPos = WIDTH * HEIGHT + l_tailPos; - int l_tailX = l_tailPos % WIDTH; - int l_tailY = (int)l_tailPos / WIDTH; - int l_currTailPos = (l_tailX * HEIGHT + l_tailY) % (WIDTH * HEIGHT); - hsv_t l_data; - l_data.h = tailHue; - l_data.s = 1; - l_data.v = (float)1 / (i * i * 0.5 + 1); - data[l_currTailPos] = l_data; - } - hsv_t l_data; - l_data.s = 1; - l_data.v = 1; - l_data.h = hue; - data[l_currentX * HEIGHT + l_currentY] = l_data; - revertOdd(data, pixels); } -static void Render_shutdown(ws2812_pixel_t *pixels) { - hsv_t data[WIDTH][HEIGHT]; - Render_fillBlack(data); - Render_revertOdd(data, pixels); +static void Render_timerINterruptHandler(void *arg) { + int l_index = 1; + xQueueSendFromISR(m_render_queue, &l_index, NULL); } -static void Render_render(int frame, ws2812_pixel_t *pixels) { - +void Render_changeRenderHandler() { struct parserData_t *l_params = ModeConfig_getCurrentParams(); - + if(l_params->currentMode == s_activeRenderMode) { + return; + } + s_activeRenderMode = l_params->currentMode; + if(s_currentRenderTask != NULL) { + vTaskDelete(s_currentRenderTask); + } + printf("CHANGING MODE: %d\n\n", l_params->currentMode); switch (l_params->currentMode) { case RAINBOW_MODE: - Render_generateRainbow( - frame, - pixels, - l_params->rainbowAlign, - l_params->currentSpeed, - l_params->currentDirection - ); + xTaskCreate(&s_Render_RainbowTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case WAVE_MODE: - Render_generateWave( - frame, - pixels, - l_params->currentMirror, - l_params->currentSpeed, - l_params->currentDirection, - l_params->currentHue - ); + xTaskCreate(&s_Render_WaveTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case TAPES_MODE: - Render_generateTapes( - frame, - pixels, - l_params->currentSpeed, - l_params->currentHue - ); + xTaskCreate(&s_Render_TapesTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case SNOW_MODE: - Render_generateSnow(pixels, l_params->currentHue); + xTaskCreate(&s_Render_SnowTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case TORNADO_MODE: - Render_generateTornado( - frame, - pixels, - l_params->currentTailHue, - l_params->currentTailLength, - l_params->currentHue - ); + xTaskCreate(&s_Render_TornadoTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case DISABLE_MODE: - Render_shutdown(pixels); + xTaskCreate(&s_Render_ShutdownTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case MATRIX_MODE: - Render_generateMatrix(pixels, l_params->currentHue, l_params->currentTailLength); + xTaskCreate(&s_Render_MatrixTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; case VAGINE_MODE: - Render_generateVagine(frame, pixels, l_params->currentHue, l_params->currentDirection); + xTaskCreate(&s_Render_VagineTask, "ws2812_i2s", 2048, s_pixels, 10, &s_currentRenderTask); break; default: - Render_generateRainbow( - frame, - pixels, - l_params->rainbowAlign, - l_params->currentSpeed, - l_params->currentDirection - ); + xTaskCreate(&s_Render_RainbowTask, "ws2812_i2s", 2048, s_pixels, 10, s_currentRenderTask); break; } } -static void Render_loop(void *pvParameters) { - ws2812_pixel_t l_pixels[LED_NUMBER]; - int head_index = 0; - +void Render_init() { ws2812_i2s_init(LED_NUMBER, PIXEL_RGB); + memset(s_pixels, 0, sizeof(ws2812_pixel_t) * LED_NUMBER); - memset(l_pixels, 0, sizeof(ws2812_pixel_t) * LED_NUMBER); - - while (1) { - int index; - if (xQueueReceive(m_render_queue, &index, portMAX_DELAY)) { - Render_render(s_frame, &l_pixels[0]); - ws2812_i2s_update(l_pixels, PIXEL_RGB); - s_frame++; - } - } -} - -static void Render_timerINterruptHandler(void *arg) { - int l_index = 1; - xQueueSendFromISR(m_render_queue, &l_index, NULL); -} - -void Render_init() { - for (int i = 0; i < MATRIX_MAX_COUNT; i++) { - s_matrixItems[i].age = 200; - s_matrixItems[i].col = 0; - } timer_set_interrupts(FRC1, false); timer_set_run(FRC1, false); _xt_isr_attach(INUM_TIMER_FRC1, Render_timerINterruptHandler, NULL); @@ -471,5 +529,5 @@ void Render_init() { timer_set_interrupts(FRC1, true); timer_set_run(FRC1, true); m_render_queue = xQueueCreate(10, sizeof(int)); - xTaskCreate(&Render_loop, "ws2812_i2s", 2048, NULL, 10, NULL); + Render_changeRenderHandler(); } \ No newline at end of file