From 766d6972b1eb37c4a73a9527d1a94bfc2f2d44d2 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Wed, 22 Jan 2020 22:18:17 -0800 Subject: [PATCH] display fixing typo plugin's files --- components/squeezelite/display.c | 209 ++++++++++++++++++--------- plugin/SqueezeESP32.zip | Bin 4622 -> 4626 bytes plugin/SqueezeESP32/SqueezeESP32.zip | Bin 0 -> 4626 bytes plugin/SqueezeESP32/install.xml | 4 +- plugin/repo.xml | 4 +- 5 files changed, 144 insertions(+), 73 deletions(-) create mode 100644 plugin/SqueezeESP32/SqueezeESP32.zip diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index 58f377b5..442f3470 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -56,16 +56,32 @@ struct grfg_packet { #pragma pack(pop) static struct scroller_s { - TaskHandle_t task; - bool active; + // copy of grfs content u8_t screen, direction; u32_t pause, speed; - u16_t by, mode, width, scroll_width; + u16_t by, mode, full_width, window_width; u16_t max, size; + // scroller management & sharing between grfg and scrolling task + TaskHandle_t task; u8_t *scroll_frame, *back_frame; + bool active, updated; + u8_t *scroll_ptr; + int scroll_len, scroll_step; } scroller; +/* + ANIM_SCREEN_1 => end of first scroll on screen 1 + ANIM_SCREEN_2 => end of first scroll on screen 2 + ANIM_SCROLL_ONCE | ANIM_SCREEN_1 => end of scroll once on screen 1 + ANIM_SCROLL_ONCE | ANIM_SCREEN_2 => end of scroll once on screen 2 +*/ +#define ANIM_TRANSITION 0x01 // A transition animation has finished +#define ANIM_SCROLL_ONCE 0x02 +#define ANIM_SCREEN_1 0x04 +#define ANIM_SCREEN_2 0x08 + #define SCROLL_STACK_SIZE 2048 + #define LINELEN 40 #define HEIGHT 32 @@ -98,12 +114,18 @@ static void scroll_task(void* arg); grfd W: screen number W: width of scrollable area in pixels - -ANIC flags -ANIM_TRANSITION 0x01 # A transition animation has finished -ANIM_SCROLL_ONCE 0x02 # A scrollonce has finished -ANIM_SCREEN_1 0x04 # For scrollonce only, screen 1 was scrolling -ANIM_SCREEN_2 0x08 # For scrollonce only, screen 2 was scrolling + anic ( two versions, don't know what to chose) + B: flag + ANIM_TRANSITION (0x01) - transition animation has finished (previous use of ANIC) + ANIM_SCREEN_1 (0x04) - end of first scroll on screen 1 + ANIM_SCREEN_2 (0x08) - end of first scroll on screen 2 + ANIM_SCROLL_ONCE (0x02) | ANIM_SCREEN_1 (0x04) - end of scroll once on screen 1 + ANIM_SCROLL_ONCE (0x02) | ANIM_SCREEN_2 (0x08) - end of scroll once on screen 2 + - or - + ANIM_TRANSITION 0x01 # A transition animation has finished + ANIM_SCROLL_ONCE 0x02 # A scrollonce has finished + ANIM_SCREEN_1 0x04 # For scrollonce only, screen 1 was scrolling + ANIM_SCREEN_2 0x08 # For scrollonce only, screen 2 was scrolling */ /**************************************************************************************** @@ -282,10 +304,14 @@ static void vfdc_handler( u8_t *_data, int bytes_read) { * Process graphic display data */ static void grfe_handler( u8_t *data, int len) { - scroller.active = false; xSemaphoreTake(display_sem, portMAX_DELAY); + + scroller.active = false; display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT); + xSemaphoreGive(display_sem); + + LOG_DEBUG("grfe frame %u", len); } /**************************************************************************************** @@ -323,21 +349,30 @@ static void grfs_handler(u8_t *data, int len) { htons(pkt->width), // total width of animation htons(pkt->offset) // offset if multiple packets are sent ); + + // new grfs frame, build scroller info + if (!offset) { + // use the display as a general lock + xSemaphoreTake(display_sem, portMAX_DELAY); - // copy scroll parameters - scroller.screen = pkt->screen; - scroller.direction = pkt->direction; - scroller.pause = htonl(pkt->pause); - scroller.speed = htonl(pkt->speed); - scroller.by = htons(pkt->by); - scroller.mode = htons(pkt->mode); - scroller.width = htons(pkt->width); + // copy & set scroll parameters + scroller.screen = pkt->screen; + scroller.direction = pkt->direction; + scroller.pause = htonl(pkt->pause); + scroller.speed = htonl(pkt->speed); + scroller.by = htons(pkt->by); + scroller.mode = htons(pkt->mode); + scroller.full_width = htons(pkt->width); + scroller.updated = scroller.active = true; - // copy scroll frame data + xSemaphoreGive(display_sem); + } + + // copy scroll frame data (no semaphore needed) if (scroller.size + size < scroller.max) { memcpy(scroller.scroll_frame + offset, data + sizeof(struct grfs_packet), size); scroller.size = offset + size; - LOG_INFO("scroller size now %u", scroller.size); + LOG_INFO("scroller current size %u", scroller.size); } else { LOG_INFO("scroller too larger %u/%u", scroller.size + size, scroller.max); } @@ -349,76 +384,112 @@ static void grfs_handler(u8_t *data, int len) { static void grfg_handler(u8_t *data, int len) { struct grfg_packet *pkt = (struct grfg_packet*) data; - memcpy(scroller.back_frame, data + sizeof(struct grfg_packet), len - sizeof(struct grfg_packet)); - scroller.scroll_width = htons(pkt->width); - scroller.active = true; - vTaskResume(scroller.task); - LOG_INFO("gfrg s:%hu w:%hu (len:%u)", htons(pkt->screen), htons(pkt->width), len); + + memcpy(scroller.back_frame, data + sizeof(struct grfg_packet), len - sizeof(struct grfg_packet)); + scroller.window_width = htons(pkt->width); + + xSemaphoreTake(display_sem, portMAX_DELAY); + + // can't be in grfs as we need full size & scroll_width + if (scroller.updated) { + scroller.scroll_len = display->width * display->height / 8 - (display->width - scroller.window_width) * display->height / 8; + if (scroller.direction == 1) { + scroller.scroll_ptr = scroller.scroll_frame; + scroller.scroll_step = scroller.by * display->height / 8; + } else { + scroller.scroll_ptr = scroller.scroll_frame + scroller.size - scroller.scroll_len; + scroller.scroll_step = -scroller.by * display->height / 8; + } + + scroller.updated = false; + } + + if (!scroller.active) { + // this is a background update and scroller has been finished, so need to update here + u8_t *frame = malloc(display->width * display->height / 8); + memcpy(frame, scroller.back_frame, display->width * display->height / 8); + for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; + display->draw_cbr(frame, HEIGHT); + free(frame); + LOG_DEBUG("direct drawing"); + } + else { + // if we just got a content update, let the scroller manage the screen + LOG_INFO("resuming scrolling task"); + vTaskResume(scroller.task); + } + + xSemaphoreGive(display_sem); } /**************************************************************************************** * Scroll task */ static void scroll_task(void *args) { - u8_t *scroll_ptr, *frame; - bool active = false; + u8_t *frame = NULL; int len = display->width * display->height / 8; - int scroll_len, scroll_step; - + while (1) { - if (!active) vTaskSuspend(NULL); - - // restart at the beginning - I don't know what right scrolling means ... - scroll_len = len - (display->width - scroller.scroll_width) * display->height / 8; - if (scroller.direction == 1) { - scroll_ptr = scroller.scroll_frame; - scroll_step = scroller.by * display->height / 8; - } else { - scroll_ptr = scroller.scroll_frame + scroller.size - scroll_len; - scroll_step = -scroller.by * display->height / 8; - } - - frame = malloc(display->width * display->height / 8); - - // scroll required amount of columns (within the window) - while (scroller.direction == 1 ? (scroll_ptr <= scroller.scroll_frame + scroller.size - scroll_step - len) : - (scroll_ptr + scroll_step >= scroller.scroll_frame) ) { - // build a combined frame - memcpy(frame, scroller.back_frame, len); - for (int i = 0; i < scroll_len; i++) frame[i] |= scroll_ptr[i]; - scroll_ptr += scroll_step; - + xSemaphoreTake(display_sem, portMAX_DELAY); + + // suspend ourselves if nothing to do, grfg will wake us up + if (!scroller.active) { + xSemaphoreGive(display_sem); + vTaskSuspend(NULL); xSemaphoreTake(display_sem, portMAX_DELAY); - active = scroller.active; - - if (!active) { - LOG_INFO("scrolling interrupted"); - xSemaphoreGive(display_sem); - break; - } + } + + // lock screen & active status + frame = malloc(display->width * display->height / 8); + + // scroll required amount of columns (within the window) + while (scroller.direction == 1 ? (scroller.scroll_ptr <= scroller.scroll_frame + scroller.size - scroller.scroll_step - len) : + (scroller.scroll_ptr + scroller.scroll_step >= scroller.scroll_frame) ) { + // don't do anything if we have aborted + if (!scroller.active) break; + + // scroll required amount of columns (within the window) + memcpy(frame, scroller.back_frame, display->width * display->height / 8); + for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; + scroller.scroll_ptr += scroller.scroll_step; display->draw_cbr(frame, HEIGHT); + xSemaphoreGive(display_sem); usleep(scroller.speed * 1000); + xSemaphoreTake(display_sem, portMAX_DELAY); } - if (active) { - // build default screen + // done with scrolling cycle reset scroller ptr + scroller.scroll_ptr = scroller.scroll_frame + (scroller.direction == 2 ? scroller.size - scroller.scroll_len : 0); + + // scrolling done, update screen and see if we need to continue + if (scroller.active) { memcpy(frame, scroller.back_frame, len); - for (int i = 0; i < scroll_len; i++) frame[i] |= scroller.scroll_frame[i]; - xSemaphoreTake(display_sem, portMAX_DELAY); - display->draw_cbr(frame, HEIGHT); + for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; + display->draw_cbr(frame, HEIGHT); + free(frame); + + // see if we need to pause or if we are done + if (scroller.mode) { + scroller.active = false; + xSemaphoreGive(display_sem); + //sendANIC(ANIM_SCROLL_ONCE | ANIM_SCREEN_1); + LOG_INFO("scroll-once terminated"); + } else { + xSemaphoreGive(display_sem); + usleep(scroller.pause * 1000); + LOG_DEBUG("scroll cycle done, pausing for %u (ms)", scroller.pause); + } + } else { + free(frame); xSemaphoreGive(display_sem); - - // pause for required time and continue (or not) - usleep(scroller.pause * 1000); - active = (scroller.mode == 0); + LOG_INFO("scroll aborted"); } - - free(frame); } } + diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip index d9a2145994414f3786300986e6502a08fd13d15a..0a05ba232c6518c770c4318149bf211ff95a4afa 100644 GIT binary patch delta 356 zcmV-q0h|7gB$6bsN(BkytTj;jCbakxlT!sJf02Q5C!=T)L8KDKg_{!F>ln!Yt1@U+yCpHm#D;9<38bujBJ%5l7B*U2$nNuH$cX@rItB0Ja`=2f3i42r7K% zjr7cOj}$e3lUM=y>kb?$E+nl#gcNm+#d3LV8ZV9cOiH7G^zlG?Zg=Q!>RO7D`_QSk ze?y>zei;U&tKJ%}!{SrtGUh{K5WBnhrLQftse@ zkIO8Q6_8FGs+AVGH|mq)(N9G@p-a}Bj>rUxHK9!@i)47OHWS#TaUVfTu@O26~6OE zdgi%DikiPktbqJ=2M!e%lGYzWin_*Py}mY$m&SZ1rBOiocpyEud-OMTEk((F=+xUG ze^5fd3-p+Xvh)FMms3?;{F|=V*AVKyW$?=w;xk8#h?(QF+3iiCqveztQ z`Q-(WE}8asr4@De=onhuW$YHnNG+w6sTvuI%VsaMOH=mMApT(gCQSz$$UsfgAI4=? z$rX@J%+*SZ+#5^t@q2-cPIoc#?_|GFvwQ|-2?>b-G*C4Em>~|6>klvvML+*jY0uRG y`Oz?g-p!LK5HtaIlU@*70d3Axt5YvXipw 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 SfdJqD_}e7`fNgL%0Q?6sqV^a7 literal 0 HcmV?d00001 diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml index 755b1edd..f0689582 100644 --- a/plugin/SqueezeESP32/install.xml +++ b/plugin/SqueezeESP32/install.xml @@ -3,8 +3,8 @@ enabled philippe_44@outlook.com - * - *.* + 7.5 + * SlimServer PLUGIN_SQUEEZEESP32 diff --git a/plugin/repo.xml b/plugin/repo.xml index 65171627..a98a12ce 100644 --- a/plugin/repo.xml +++ b/plugin/repo.xml @@ -1,10 +1,10 @@ - + https://github.com/sle118/squeezelite-esp32 Philippe - a1d676e7a3a2d241d17a39aff05bcb8377565a76 + 0d5d5101edf534a6eaac8e42cec88532011976a5 philippe_44@outlook.com SqueezeESP32 additional player id (100) http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip