Browse Source

display fixing

typo

plugin's files
philippe44 5 years ago
parent
commit
766d6972b1

+ 138 - 67
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 & 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;
+
+		xSemaphoreGive(display_sem);
+	}	
 
-	// 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 scroll frame data
+	// 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;
 	
+	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.scroll_width = htons(pkt->width);
-	scroller.active = true;
-	vTaskResume(scroller.task);
+	scroller.window_width = htons(pkt->width);
 	
-	LOG_INFO("gfrg s:%hu w:%hu (len:%u)", htons(pkt->screen), htons(pkt->width), len);
+	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;
+		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);
 		}	
-			
+		
+		// lock screen & active status
 		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);
-			active = scroller.active;
-			
-			if (!active) {
-				LOG_INFO("scrolling interrupted");
-				xSemaphoreGive(display_sem);
-				break;
-			}
+		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);
 	}	
 }	
+			
 
 
 

BIN
plugin/SqueezeESP32.zip


BIN
plugin/SqueezeESP32/SqueezeESP32.zip


+ 2 - 2
plugin/SqueezeESP32/install.xml

@@ -3,8 +3,8 @@
   <defaultState>enabled</defaultState>
   <email>philippe_44@outlook.com</email>
   <targetApplication>
-    <minVersion>*</minVersion>
-    <maxVersion>*.*</maxVersion>
+    <minVersion>7.5</minVersion>
+    <maxVersion>*</maxVersion>
     <id>SlimServer</id>
   </targetApplication>
   <name>PLUGIN_SQUEEZEESP32</name>

+ 2 - 2
plugin/repo.xml

@@ -1,10 +1,10 @@
 <?xml version='1.0' standalone='yes'?>
 <extensions>
   <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>
       <creator>Philippe</creator>
-      <sha>a1d676e7a3a2d241d17a39aff05bcb8377565a76</sha>
+      <sha>0d5d5101edf534a6eaac8e42cec88532011976a5</sha>
       <email>philippe_44@outlook.com</email>
       <desc lang="EN">SqueezeESP32 additional player id (100)</desc>
       <url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>