mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 19:47:02 +03:00
display fixing
typo plugin's files
This commit is contained in:
@@ -56,16 +56,32 @@ struct grfg_packet {
|
|||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
static struct scroller_s {
|
static struct scroller_s {
|
||||||
TaskHandle_t task;
|
// copy of grfs content
|
||||||
bool active;
|
|
||||||
u8_t screen, direction;
|
u8_t screen, direction;
|
||||||
u32_t pause, speed;
|
u32_t pause, speed;
|
||||||
u16_t by, mode, width, scroll_width;
|
u16_t by, mode, full_width, window_width;
|
||||||
u16_t max, size;
|
u16_t max, size;
|
||||||
|
// scroller management & sharing between grfg and scrolling task
|
||||||
|
TaskHandle_t task;
|
||||||
u8_t *scroll_frame, *back_frame;
|
u8_t *scroll_frame, *back_frame;
|
||||||
|
bool active, updated;
|
||||||
|
u8_t *scroll_ptr;
|
||||||
|
int scroll_len, scroll_step;
|
||||||
} scroller;
|
} 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 SCROLL_STACK_SIZE 2048
|
||||||
|
|
||||||
#define LINELEN 40
|
#define LINELEN 40
|
||||||
#define HEIGHT 32
|
#define HEIGHT 32
|
||||||
|
|
||||||
@@ -98,8 +114,14 @@ static void scroll_task(void* arg);
|
|||||||
grfd
|
grfd
|
||||||
W: screen number
|
W: screen number
|
||||||
W: width of scrollable area in pixels
|
W: width of scrollable area in pixels
|
||||||
|
anic ( two versions, don't know what to chose)
|
||||||
ANIC flags
|
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_TRANSITION 0x01 # A transition animation has finished
|
||||||
ANIM_SCROLL_ONCE 0x02 # A scrollonce has finished
|
ANIM_SCROLL_ONCE 0x02 # A scrollonce has finished
|
||||||
ANIM_SCREEN_1 0x04 # For scrollonce only, screen 1 was scrolling
|
ANIM_SCREEN_1 0x04 # For scrollonce only, screen 1 was scrolling
|
||||||
@@ -282,10 +304,14 @@ static void vfdc_handler( u8_t *_data, int bytes_read) {
|
|||||||
* Process graphic display data
|
* Process graphic display data
|
||||||
*/
|
*/
|
||||||
static void grfe_handler( u8_t *data, int len) {
|
static void grfe_handler( u8_t *data, int len) {
|
||||||
scroller.active = false;
|
|
||||||
xSemaphoreTake(display_sem, portMAX_DELAY);
|
xSemaphoreTake(display_sem, portMAX_DELAY);
|
||||||
|
|
||||||
|
scroller.active = false;
|
||||||
display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT);
|
display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT);
|
||||||
|
|
||||||
xSemaphoreGive(display_sem);
|
xSemaphoreGive(display_sem);
|
||||||
|
|
||||||
|
LOG_DEBUG("grfe frame %u", len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
@@ -324,20 +350,29 @@ static void grfs_handler(u8_t *data, int len) {
|
|||||||
htons(pkt->offset) // offset if multiple packets are sent
|
htons(pkt->offset) // offset if multiple packets are sent
|
||||||
);
|
);
|
||||||
|
|
||||||
// copy scroll parameters
|
// new grfs frame, build scroller info
|
||||||
|
if (!offset) {
|
||||||
|
// use the display as a general lock
|
||||||
|
xSemaphoreTake(display_sem, portMAX_DELAY);
|
||||||
|
|
||||||
|
// copy & set scroll parameters
|
||||||
scroller.screen = pkt->screen;
|
scroller.screen = pkt->screen;
|
||||||
scroller.direction = pkt->direction;
|
scroller.direction = pkt->direction;
|
||||||
scroller.pause = htonl(pkt->pause);
|
scroller.pause = htonl(pkt->pause);
|
||||||
scroller.speed = htonl(pkt->speed);
|
scroller.speed = htonl(pkt->speed);
|
||||||
scroller.by = htons(pkt->by);
|
scroller.by = htons(pkt->by);
|
||||||
scroller.mode = htons(pkt->mode);
|
scroller.mode = htons(pkt->mode);
|
||||||
scroller.width = htons(pkt->width);
|
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) {
|
if (scroller.size + size < scroller.max) {
|
||||||
memcpy(scroller.scroll_frame + offset, data + sizeof(struct grfs_packet), size);
|
memcpy(scroller.scroll_frame + offset, data + sizeof(struct grfs_packet), size);
|
||||||
scroller.size = offset + size;
|
scroller.size = offset + size;
|
||||||
LOG_INFO("scroller size now %u", scroller.size);
|
LOG_INFO("scroller current size %u", scroller.size);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("scroller too larger %u/%u", scroller.size + size, scroller.max);
|
LOG_INFO("scroller too larger %u/%u", scroller.size + size, scroller.max);
|
||||||
}
|
}
|
||||||
@@ -349,74 +384,109 @@ static void grfs_handler(u8_t *data, int len) {
|
|||||||
static void grfg_handler(u8_t *data, int len) {
|
static void grfg_handler(u8_t *data, int len) {
|
||||||
struct grfg_packet *pkt = (struct grfg_packet*) data;
|
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);
|
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
|
* Scroll task
|
||||||
*/
|
*/
|
||||||
static void scroll_task(void *args) {
|
static void scroll_task(void *args) {
|
||||||
u8_t *scroll_ptr, *frame;
|
u8_t *frame = NULL;
|
||||||
bool active = false;
|
|
||||||
int len = display->width * display->height / 8;
|
int len = display->width * display->height / 8;
|
||||||
int scroll_len, scroll_step;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!active) vTaskSuspend(NULL);
|
xSemaphoreTake(display_sem, portMAX_DELAY);
|
||||||
|
|
||||||
// restart at the beginning - I don't know what right scrolling means ...
|
// suspend ourselves if nothing to do, grfg will wake us up
|
||||||
scroll_len = len - (display->width - scroller.scroll_width) * display->height / 8;
|
if (!scroller.active) {
|
||||||
if (scroller.direction == 1) {
|
xSemaphoreGive(display_sem);
|
||||||
scroll_ptr = scroller.scroll_frame;
|
vTaskSuspend(NULL);
|
||||||
scroll_step = scroller.by * display->height / 8;
|
xSemaphoreTake(display_sem, portMAX_DELAY);
|
||||||
} else {
|
|
||||||
scroll_ptr = scroller.scroll_frame + scroller.size - scroll_len;
|
|
||||||
scroll_step = -scroller.by * display->height / 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lock screen & active status
|
||||||
frame = malloc(display->width * display->height / 8);
|
frame = malloc(display->width * display->height / 8);
|
||||||
|
|
||||||
// scroll required amount of columns (within the window)
|
// scroll required amount of columns (within the window)
|
||||||
while (scroller.direction == 1 ? (scroll_ptr <= scroller.scroll_frame + scroller.size - scroll_step - len) :
|
while (scroller.direction == 1 ? (scroller.scroll_ptr <= scroller.scroll_frame + scroller.size - scroller.scroll_step - len) :
|
||||||
(scroll_ptr + scroll_step >= scroller.scroll_frame) ) {
|
(scroller.scroll_ptr + scroller.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);
|
// don't do anything if we have aborted
|
||||||
active = scroller.active;
|
if (!scroller.active) break;
|
||||||
|
|
||||||
if (!active) {
|
|
||||||
LOG_INFO("scrolling interrupted");
|
|
||||||
xSemaphoreGive(display_sem);
|
|
||||||
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);
|
display->draw_cbr(frame, HEIGHT);
|
||||||
|
|
||||||
xSemaphoreGive(display_sem);
|
xSemaphoreGive(display_sem);
|
||||||
usleep(scroller.speed * 1000);
|
usleep(scroller.speed * 1000);
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
// build default screen
|
|
||||||
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);
|
xSemaphoreTake(display_sem, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i];
|
||||||
display->draw_cbr(frame, HEIGHT);
|
display->draw_cbr(frame, HEIGHT);
|
||||||
xSemaphoreGive(display_sem);
|
|
||||||
|
|
||||||
// pause for required time and continue (or not)
|
|
||||||
usleep(scroller.pause * 1000);
|
|
||||||
active = (scroller.mode == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(frame);
|
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);
|
||||||
|
LOG_INFO("scroll aborted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,3 +496,4 @@ static void scroll_task(void *args) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
BIN
plugin/SqueezeESP32/SqueezeESP32.zip
Normal file
BIN
plugin/SqueezeESP32/SqueezeESP32.zip
Normal file
Binary file not shown.
@@ -3,8 +3,8 @@
|
|||||||
<defaultState>enabled</defaultState>
|
<defaultState>enabled</defaultState>
|
||||||
<email>philippe_44@outlook.com</email>
|
<email>philippe_44@outlook.com</email>
|
||||||
<targetApplication>
|
<targetApplication>
|
||||||
<minVersion>*</minVersion>
|
<minVersion>7.5</minVersion>
|
||||||
<maxVersion>*.*</maxVersion>
|
<maxVersion>*</maxVersion>
|
||||||
<id>SlimServer</id>
|
<id>SlimServer</id>
|
||||||
</targetApplication>
|
</targetApplication>
|
||||||
<name>PLUGIN_SQUEEZEESP32</name>
|
<name>PLUGIN_SQUEEZEESP32</name>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version='1.0' standalone='yes'?>
|
<?xml version='1.0' standalone='yes'?>
|
||||||
<extensions>
|
<extensions>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin version="0.7" name="SqueezeESP32" minTarget="*" maxTarget="7.*">
|
<plugin version="0.7" name="SqueezeESP32" minTarget="7.5" maxTarget="*">
|
||||||
<link>https://github.com/sle118/squeezelite-esp32</link>
|
<link>https://github.com/sle118/squeezelite-esp32</link>
|
||||||
<creator>Philippe</creator>
|
<creator>Philippe</creator>
|
||||||
<sha>a1d676e7a3a2d241d17a39aff05bcb8377565a76</sha>
|
<sha>0d5d5101edf534a6eaac8e42cec88532011976a5</sha>
|
||||||
<email>philippe_44@outlook.com</email>
|
<email>philippe_44@outlook.com</email>
|
||||||
<desc lang="EN">SqueezeESP32 additional player id (100)</desc>
|
<desc lang="EN">SqueezeESP32 additional player id (100)</desc>
|
||||||
<url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>
|
<url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>
|
||||||
|
|||||||
Reference in New Issue
Block a user