Browse Source

1st artwork version

philippe44 5 years ago
parent
commit
5e5dc9ba29

+ 4 - 0
components/display/core/gds.c

@@ -60,6 +60,10 @@ void GDS_Clear( struct GDS_Device* Device, int Color ) {
 }
 }
 
 
 void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color ) {
 void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color ) {
+	// -1 means up to width/height
+	if (x2 < 0) x2 = Device->Width - 1;
+	if (y2 < 0) y2 = Device->Height - 1;
+	
 	// driver can provide own optimized clear window
 	// driver can provide own optimized clear window
 	if (Device->ClearWindow) {
 	if (Device->ClearWindow) {
 		Device->ClearWindow( Device, x1, y1, x2, y2, Color );
 		Device->ClearWindow( Device, x1, y1, x2, y2, Color );

+ 3 - 1
components/display/core/gds_image.c

@@ -218,8 +218,10 @@ bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int
 		
 		
 		// then place it
 		// then place it
 		if (Fit & GDS_IMAGE_CENTER_X) Context.XOfs = (Device->Width + x - Context.Width) / 2;
 		if (Fit & GDS_IMAGE_CENTER_X) Context.XOfs = (Device->Width + x - Context.Width) / 2;
+		else if (Fit & GDS_IMAGE_RIGHT) Context.XOfs = Device->Width - Context.Width;
 		if (Fit & GDS_IMAGE_CENTER_Y) Context.YOfs = (Device->Height + y - Context.Height) / 2;
 		if (Fit & GDS_IMAGE_CENTER_Y) Context.YOfs = (Device->Height + y - Context.Height) / 2;
-		
+		else if (Fit & GDS_IMAGE_BOTTOM) Context.YOfs = Device->Height - Context.Height;
+
 		Context.XMin = x - Context.XOfs;
 		Context.XMin = x - Context.XOfs;
 		Context.YMin = y - Context.YOfs;
 		Context.YMin = y - Context.YOfs;
 					
 					

+ 4 - 1
components/display/core/gds_image.h

@@ -9,8 +9,11 @@ struct GDS_Device;
 
 
 enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 };
 enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 };
 
 
-#define GDS_IMAGE_TOP		0x00
+#define GDS_IMAGE_LEFT		0x00
 #define GDS_IMAGE_CENTER_X	0x01
 #define GDS_IMAGE_CENTER_X	0x01
+#define GDS_IMAGE_RIGHT		0x04
+#define GDS_IMAGE_TOP		0x00
+#define GDS_IMAGE_BOTTOM	0x08
 #define GDS_IMAGE_CENTER_Y	0x02
 #define GDS_IMAGE_CENTER_Y	0x02
 #define GDS_IMAGE_CENTER	(GDS_IMAGE_CENTER_X | GDS_IMAGE_CENTER_Y)
 #define GDS_IMAGE_CENTER	(GDS_IMAGE_CENTER_X | GDS_IMAGE_CENTER_Y)
 #define GDS_IMAGE_FIT		0x10
 #define GDS_IMAGE_FIT		0x10

+ 27 - 14
components/squeezelite/display.c

@@ -62,7 +62,9 @@ struct grfg_packet {
 
 
 struct grfa_packet {
 struct grfa_packet {
 	char  opcode[4];
 	char  opcode[4];
-	u32_t length; 
+	u32_t length;
+	u16_t x;
+	u16_t y;	
 	u32_t offset;
 	u32_t offset;
 };
 };
 
 
@@ -140,6 +142,7 @@ static struct scroller_s {
 static struct {
 static struct {
 	u8_t *data;
 	u8_t *data;
 	u32_t size;
 	u32_t size;
+	u16_t x, y;
 } artwork;
 } artwork;
 
 
 #define MAX_BARS	32
 #define MAX_BARS	32
@@ -313,7 +316,7 @@ static void send_server(void) {
 		pkt_header.length = htonl(sizeof(pkt_header) - 8);
 		pkt_header.length = htonl(sizeof(pkt_header) - 8);
 		pkt_header.mode = ANIC_resp;
 		pkt_header.mode = ANIC_resp;
 
 
-		send_packet((u8_t *)&pkt_header, sizeof(pkt_header));
+		send_packet((uint8_t *) &pkt_header, sizeof(pkt_header));
 		
 		
 		ANIC_resp = ANIM_NONE;
 		ANIC_resp = ANIM_NONE;
 	}	
 	}	
@@ -321,18 +324,22 @@ static void send_server(void) {
 	if (SETD_width) {
 	if (SETD_width) {
 		struct SETD_header pkt_header;
 		struct SETD_header pkt_header;
 		
 		
-		LOG_INFO("sending width %u", SETD_width);	
-		
 		memset(&pkt_header, 0, sizeof(pkt_header));
 		memset(&pkt_header, 0, sizeof(pkt_header));
 		memcpy(&pkt_header.opcode, "SETD", 4);
 		memcpy(&pkt_header.opcode, "SETD", 4);
 
 
 		pkt_header.id = 0xfe; // id 0xfe is width S:P:Squeezebox2
 		pkt_header.id = 0xfe; // id 0xfe is width S:P:Squeezebox2
-		pkt_header.length = htonl(sizeof(pkt_header) +  2 - 8);
+		pkt_header.length = htonl(sizeof(pkt_header) +  4 - 8);
+		
+		u16_t height = GDS_GetHeight(display);
+		LOG_INFO("sending dimension %ux%u", SETD_width, height);	
 
 
 		SETD_width = htons(SETD_width);
 		SETD_width = htons(SETD_width);
-		send_packet((u8_t *)&pkt_header, sizeof(pkt_header));
-		send_packet((uint8_t*) &SETD_width, 2);
-
+		height = htons(height);
+		
+		send_packet((uint8_t *) &pkt_header, sizeof(pkt_header));
+		send_packet((uint8_t *) &SETD_width, 2);
+		send_packet((uint8_t *) &height, 2);
+		
 		SETD_width = 0;
 		SETD_width = 0;
 	}	
 	}	
 	
 	
@@ -661,10 +668,10 @@ static void grfa_handler(u8_t *data, int len) {
 	int offset = htonl(pkt->offset);
 	int offset = htonl(pkt->offset);
 	int length = htonl(pkt->length);
 	int length = htonl(pkt->length);
 	
 	
-	LOG_INFO("gfra l:%u o:%u s:%u", length, offset, size);
-				
 	// new grfa artwork, allocate memory
 	// new grfa artwork, allocate memory
 	if (!offset) {	
 	if (!offset) {	
+		artwork.x = htons(pkt->x);
+		artwork.y = htons(pkt->y);
 		if (artwork.data) free(artwork.data);
 		if (artwork.data) free(artwork.data);
 		artwork.data = malloc(length);
 		artwork.data = malloc(length);
 		artwork.size = 0;
 		artwork.size = 0;
@@ -674,8 +681,14 @@ static void grfa_handler(u8_t *data, int len) {
 	memcpy(artwork.data + offset, data + sizeof(struct grfa_packet), size);
 	memcpy(artwork.data + offset, data + sizeof(struct grfa_packet), size);
 	artwork.size += size;
 	artwork.size += size;
 	if (artwork.size == length) {
 	if (artwork.size == length) {
-		GDS_DrawJPEG(display, artwork.data, 0, 32, GDS_IMAGE_CENTER);		
-	}	
+		GDS_ClearWindow(display, artwork.x, artwork.y, -1, -1, GDS_COLOR_BLACK);
+		GDS_DrawJPEG(display, artwork.data, artwork.x, artwork.y, artwork.y < 32 ? (GDS_IMAGE_RIGHT | GDS_IMAGE_TOP) : GDS_IMAGE_CENTER);
+		free(artwork.data);
+		artwork.data = NULL;
+		artwork.size = 0;
+	} 
+	
+	LOG_INFO("gfra l:%u x:%hu, y:%hu, o:%u s:%u", length, artwork.x, artwork.y, offset, size);
 }
 }
 
 
 /****************************************************************************************
 /****************************************************************************************
@@ -820,7 +833,7 @@ static void visu_handler( u8_t *data, int len) {
 	visu.mode = pkt->which;
 	visu.mode = pkt->which;
 	
 	
 	// little trick to clean the taller screens when switching visu 
 	// little trick to clean the taller screens when switching visu 
-	if (visu.row >= SB_HEIGHT) GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
+	if (visu.row >= SB_HEIGHT) GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
 	
 	
 	if (visu.mode) {
 	if (visu.mode) {
 		if (pkt->count >= 4) {
 		if (pkt->count >= 4) {
@@ -878,7 +891,7 @@ static void visu_handler( u8_t *data, int len) {
 		// reset bars maximum
 		// reset bars maximum
 		for (int i = visu.n; --i >= 0;) visu.bars[i].max = 0;
 		for (int i = visu.n; --i >= 0;) visu.bars[i].max = 0;
 				
 				
-		GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
+		GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
 		
 		
 		LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale);
 		LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale);
 	} else {
 	} else {

BIN
plugin/SqueezeESP32.zip


+ 22 - 5
plugin/SqueezeESP32/Graphics.pm

@@ -71,7 +71,12 @@ sub displayWidth {
 	}
 	}
 	
 	
 	if ($display->widthOverride) {
 	if ($display->widthOverride) {
-		return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0);
+		my $artwork = $prefs->client($client)->get('artwork');
+		if ($artwork->{'enable'} && $artwork->{'y'} < 32) {
+			return $artwork->{x} + ($display->modes->[$mode || 0]{_width} || 0);
+		} else {
+			return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0);
+		}	
 	} else {
 	} else {
 		return $display->modes->[$mode || 0]{width};
 		return $display->modes->[$mode || 0]{width};
 	}	
 	}	
@@ -101,9 +106,21 @@ sub build_modes {
 	my $cprefs = $prefs->client($client);
 	my $cprefs = $prefs->client($client);
 	
 	
 	my $width = shift || $cprefs->get('width') || 128;
 	my $width = shift || $cprefs->get('width') || 128;
+	my $artwork = $cprefs->get('artwork');
+	
+	# if artwork is in main display, reduce width
+	$width = $artwork->{'x'} - 1 if $artwork->{'enable'} && $artwork->{y} < 32;
+	
 	my $small_VU = $cprefs->get('small_VU');
 	my $small_VU = $cprefs->get('small_VU');
 	my $spectrum = $cprefs->get('spectrum');
 	my $spectrum = $cprefs->get('spectrum');
 	
 	
+	my $small_spectrum_pos = { x => $width - int ($spectrum->{small}->{size} * $width / 100), 
+						 width => int ($spectrum->{small}->{size} * $width / 100),
+			};
+	my $small_VU_pos = { x => $width - int ($small_VU * $width / 100), 
+						 width => int ($small_VU * $width / 100),
+			};		 				
+	
 	my @modes = (
 	my @modes = (
 		# mode 0
 		# mode 0
 		{ desc => ['BLANK'],
 		{ desc => ['BLANK'],
@@ -135,14 +152,14 @@ sub build_modes {
 		params => [$VISUALIZER_NONE] },
 		params => [$VISUALIZER_NONE] },
 		# mode 7
 		# mode 7
 		{ desc => ['VISUALIZER_VUMETER_SMALL'],
 		{ desc => ['VISUALIZER_VUMETER_SMALL'],
-		bar => 0, secs => 0,  width => $width, _width => int -($small_VU*$width/100),
+		bar => 0, secs => 0,  width => $width, _width => -$small_VU_pos->{'width'},
 		# extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space)
 		# extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space)
-		params => [$VISUALIZER_VUMETER, int ($small_VU*$width/100), 32, int -($small_VU*$width/100), 0, 2] },
+		params => [$VISUALIZER_VUMETER, $small_VU_pos->{'width'}, 32, $small_VU_pos->{'x'}, 0, 2] },
 		# mode 8
 		# mode 8
 		{ desc => ['VISUALIZER_SPECTRUM_ANALYZER_SMALL'],
 		{ desc => ['VISUALIZER_SPECTRUM_ANALYZER_SMALL'],
-		bar => 0, secs => 0,  width => $width, _width => int -($spectrum->{small}->{size}*$width/100),
+		bar => 0, secs => 0,  width => $width, _width => -$small_spectrum_pos->{'width'},
 		# extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space, bars)
 		# extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space, bars)
-		params => [$VISUALIZER_SPECTRUM_ANALYZER, int ($spectrum->{small}->{size}*$width/100), 32, int -($spectrum->{small}->{size}*$width/100), 0, 2, int ($spectrum->{small}->{size}/100*$width/$spectrum->{small}->{band}), $spectrum->{scale}] },  
+		params => [$VISUALIZER_SPECTRUM_ANALYZER, $small_spectrum_pos->{width}, 32, $small_spectrum_pos->{'x'}, 0, 2, $small_spectrum_pos->{'width'} / $spectrum->{small}->{band}, $spectrum->{scale}] },  
 		# mode 9	 
 		# mode 9	 
 		{ desc => ['VISUALIZER_VUMETER'],
 		{ desc => ['VISUALIZER_VUMETER'],
 		bar => 0, secs => 0,  width => $width,
 		bar => 0, secs => 0,  width => $width,

+ 0 - 20
plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html

@@ -1,20 +0,0 @@
-[% PROCESS settings/header.html %]
-
-	[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_BANNER" %]
-		<div>[% "PLUGIN_SQUEEZEESP32_BANNER_TEXT" | string %]</div>
-	[% END %]
-
-	<div class="prefDesc">
-	
-	[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_WIDTH" desc="PLUGIN_SQUEEZEESP32_WIDTH_DESC" %]
-		<input type="text" class="stdedit" name="pref_width" id="pref_width" value="[% prefs.pref_width %]" size="3">
-	[% END %]
-	
-	[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE" desc="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE_DESC" %]
-		<input type="number" min="10" max= "50" step="5" class="stdedit" name="pref_spectrum_scale" id="pref_spectrum_scale" value="[% prefs.pref_spectrum_scale %]" size="3">
-	[% END %]
-	
-	
-	</div>
-
-[% PROCESS settings/footer.html %]

+ 12 - 3
plugin/SqueezeESP32/Player.pm

@@ -20,8 +20,8 @@ sub playerSettingsFrame {
 	
 	
 	my $value;
 	my $value;
 	my $id = unpack('C', $$data_ref);
 	my $id = unpack('C', $$data_ref);
-		        
-	# New SETD command 0xfe for display width
+	
+	# New SETD command 0xfe for display width & height
 	if ($id == 0xfe) { 
 	if ($id == 0xfe) { 
 		$value = (unpack('Cn', $$data_ref))[1];
 		$value = (unpack('Cn', $$data_ref))[1];
 		if ($value > 100 && $value < 400) {
 		if ($value > 100 && $value < 400) {
@@ -30,7 +30,9 @@ sub playerSettingsFrame {
 			$client->display->widthOverride(1, $value);
 			$client->display->widthOverride(1, $value);
 			$client->update;
 			$client->update;
 		} 
 		} 
-		$log->info("Setting player width $value for ", $client->name);
+		my $height = (unpack('Cnn', $$data_ref))[2];
+		$prefs->client($client)->set('height', $height || 0);
+		$log->info("Setting player $value" . "x" . "$height for ", $client->name);
 	}
 	}
 	
 	
 	$client->SUPER::playerSettingsFrame($data_ref);
 	$client->SUPER::playerSettingsFrame($data_ref);
@@ -40,4 +42,11 @@ sub hasScrolling  {
 	return 1;
 	return 1;
 }
 }
 
 
+
+sub directMetadata {
+	my $client = shift;
+	$client->SUPER::directMetadata(@_);
+	Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] );
+}
+
 1;
 1;

+ 8 - 2
plugin/SqueezeESP32/PlayerSettings.pm

@@ -30,7 +30,7 @@ sub page {
 
 
 sub prefs {
 sub prefs {
 	my ($class, $client) = @_;
 	my ($class, $client) = @_;
-	my @prefs = qw(width small_VU spectrum);
+	my @prefs = qw(width small_VU spectrum artwork);
 	return ($prefs->client($client), @prefs);
 	return ($prefs->client($client), @prefs);
 }
 }
 
 
@@ -47,6 +47,11 @@ sub handler {
 							full  => { 	band => $paramRef->{'pref_spectrum_full_band'} },
 							full  => { 	band => $paramRef->{'pref_spectrum_full_band'} },
 				};
 				};
 		$cprefs->set('spectrum', $spectrum);
 		$cprefs->set('spectrum', $spectrum);
+		my $artwork =	{	enable => $paramRef->{'pref_artwork_enable'},
+							x => $paramRef->{'pref_artwork_x'}, 
+							y => $paramRef->{'pref_artwork_y'},
+				};
+		$cprefs->set('artwork', $artwork);				
 		$client->display->modes($client->display->build_modes);
 		$client->display->modes($client->display->build_modes);
 		$client->display->update;
 		$client->display->update;
 	}
 	}
@@ -56,9 +61,10 @@ sub handler {
 	
 	
 	# here I don't know why you need to set again spectrum which is a reference
 	# here I don't know why you need to set again spectrum which is a reference
 	# to a hash. Using $paramRef->{prefs} does not work either. It seems that 
 	# to a hash. Using $paramRef->{prefs} does not work either. It seems that 
-	# soem are copies of value, some are references, can't figure out.This whole
+	# some are copies of value, some are references, can't figure out. This whole
 	# logic of "Settings" is beyond me and I really hate it
 	# logic of "Settings" is beyond me and I really hate it
 	$paramRef->{'pref_spectrum'} = $cprefs->get('spectrum');
 	$paramRef->{'pref_spectrum'} = $cprefs->get('spectrum');
+	$paramRef->{'pref_artwork'} = $cprefs->get('artwork');
 	
 	
 	return $class->SUPER::handler($client, $paramRef);
 	return $class->SUPER::handler($client, $paramRef);
 }
 }

+ 59 - 0
plugin/SqueezeESP32/Plugin.pm

@@ -3,8 +3,12 @@ package Plugins::SqueezeESP32::Plugin;
 use strict;
 use strict;
 
 
 use base qw(Slim::Plugin::Base);
 use base qw(Slim::Plugin::Base);
+
+use Digest::MD5 qw(md5);
+use List::Util qw(min);
 use Slim::Utils::Prefs;
 use Slim::Utils::Prefs;
 use Slim::Utils::Log;
 use Slim::Utils::Log;
+use Slim::Web::ImageProxy;
 
 
 my $prefs = preferences('plugin.squeezeesp32');
 my $prefs = preferences('plugin.squeezeesp32');
 
 
@@ -28,6 +32,61 @@ sub initPlugin {
 	$class->SUPER::initPlugin(@_);
 	$class->SUPER::initPlugin(@_);
 	Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
 	Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
 	$log->info("Added class 100 for SqueezeESP32");
 	$log->info("Added class 100 for SqueezeESP32");
+	
+	Slim::Control::Request::subscribe(\&update_artwork, [ ['newmetadata'] ] );
+	Slim::Control::Request::subscribe(\&update_artwork, [ ['playlist'], ['open', 'newsong'] ]);
+}
+
+sub update_artwork {
+    my $request = shift;
+    my $client  = $request->client;
+	my $cprefs = $prefs->client($client);
+	my $artwork = $cprefs->get('artwork');
+		
+	return unless $client->model eq 'squeezeesp32' && $artwork->{'enable'};
+
+	my $reqstr     = $request->getRequestString();
+	#my $path = $request->getParam('_path');
+
+	my $s = $artwork->{'y'} >= 32 ? $cprefs->get('height') - $artwork->{'y'} : 32;
+	$s = min($s, $cprefs->get('width') - $artwork->{'x'});
+	
+	my $path = 'music/current/cover_' . $s . 'x' . $s . '_o.jpg';
+	my $body = Slim::Web::Graphics::artworkRequest($client, $path, undef, \&send_artwork, undef, HTTP::Response->new);
+	
+	send_artwork($client, undef, \$body) if $body;
+	
+	$log->info("artwork update notification $reqstr with $path");
 }
 }
 
 
+sub send_artwork {
+	my ($client, $params, $dataref) = @_;
+	
+	# I'm not sure why we are called so often, so only send when needed
+	my $md5 = md5($$dataref);
+	return if $client->pluginData('artwork_md5') eq $md5;
+	
+	$client->pluginData('artwork', $dataref);
+	$client->pluginData('artwork_md5', $md5);
+	
+	my $artwork = $prefs->client($client)->get('artwork');
+	my $length = length $$dataref;
+	my $offset = 0;
+	
+	$log->info("got resized artwork (length: ", length $$dataref, ")");
+	
+	my $header = pack('Nnn', $length, $artwork->{'x'}, $artwork->{'y'});
+	
+	while ($length > 0) {
+		$length = 1280 if $length > 1280;
+		$log->info("sending grfa $length");
+			
+		my $data = $header . pack('N', $offset) . substr( $$dataref, 0, $length, '' );
+			
+		$client->sendFrame( grfa => \$data );
+		$offset += $length;			
+		$length = length $$dataref;
+	}
+}	
+
 1;
 1;

+ 0 - 30
plugin/SqueezeESP32/Settings.pm

@@ -1,30 +0,0 @@
-package Plugins::SqueezeESP32::Settings;
-use base qw(Slim::Web::Settings);
-
-use strict;
-
-use Slim::Utils::Prefs;
-use Slim::Utils::Log;
-
-my $log = logger('plugin.squeezeesp32');
-
-sub name {
-	return 'PLUGIN_SQUEEZEESP32';
-}
-
-sub page {
-	return 'plugins/SqueezeESP32/settings/basic.html';
-}
-
-sub prefs {
-	return (preferences('plugin.squeezeesp32'), qw(width spectrum_scale));
-}
-
-sub handler {
-	my ($class, $client, $params, $callback, @args) = @_;
-	
-	$callback->($client, $params, $class->SUPER::handler($client, $params), @args);
-}
-
-	
-1;

BIN
plugin/SqueezeESP32/SqueezeESP32.zip


+ 1 - 1
plugin/SqueezeESP32/install.xml

@@ -10,6 +10,6 @@
   <name>PLUGIN_SQUEEZEESP32</name>
   <name>PLUGIN_SQUEEZEESP32</name>
   <description>PLUGIN_SQUEEZEESP32_DESC</description>
   <description>PLUGIN_SQUEEZEESP32_DESC</description>
   <module>Plugins::SqueezeESP32::Plugin</module>
   <module>Plugins::SqueezeESP32::Plugin</module>
-    <version>0.31</version>
+    <version>0.40</version>
   <creator>Philippe</creator>
   <creator>Philippe</creator>
 </extensions>
 </extensions>

+ 16 - 0
plugin/SqueezeESP32/strings.txt

@@ -53,3 +53,19 @@ PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND
 		
 		
 PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND_DESC
 PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND_DESC
 	EN	The number of bands is the width of the screen divided by this factor
 	EN	The number of bands is the width of the screen divided by this factor
+	
+PLUGIN_SQUEEZEESP32_ARTWORK
+	EN	Artwork
+	
+PLUGIN_SQUEEZEESP32_ARTWORK_DESC
+	EN	When Y position is less than 32, then artwork is display at the right of the main screen and x defines the starting position
+	EN	Using artwork on less than 16-levels grayscale display if really poor quality
+
+PLUGIN_SQUEEZEESP32_ARTWORK_ENABLE
+	EN	Enable
+	
+PLUGIN_SQUEEZEESP32_ARTWORK_X
+	EN	X
+
+PLUGIN_SQUEEZEESP32_ARTWORK_Y
+	EN	Y

+ 2 - 2
plugin/repo.xml

@@ -1,10 +1,10 @@
 <?xml version='1.0' standalone='yes'?>
 <?xml version='1.0' standalone='yes'?>
 <extensions>
 <extensions>
   <plugins>
   <plugins>
-    <plugin version="0.31" name="SqueezeESP32" minTarget="7.5" maxTarget="*">
+    <plugin version="0.40" 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>6dc35a0f9f9b287d205f7532cbb642b08407a284</sha>
+      <sha>aa122a85db949c903ffa978d3e3b4ee3205e4ec2</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>