summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2005-12-07 20:42:06 +0000
committerMagnus Holmgren <magnushol@gmail.com>2005-12-07 20:42:06 +0000
commit1cce533678037e305e28bc3cdd9e5c5c26d7b3fa (patch)
treebb4bfec9abf3593184c7ae2e2533641e67cf4e99 /apps
parentddbf4e51aaabce43dac8d85a3f78d8b9396a6c73 (diff)
downloadrockbox-1cce533678037e305e28bc3cdd9e5c5c26d7b3fa.zip
rockbox-1cce533678037e305e28bc3cdd9e5c5c26d7b3fa.tar.gz
rockbox-1cce533678037e305e28bc3cdd9e5c5c26d7b3fa.tar.bz2
rockbox-1cce533678037e305e28bc3cdd9e5c5c26d7b3fa.tar.xz
Patch #1367059 by _FireFly_: New wps loader. The wps buffer size can be reduced now, but it isn't done in this patch. Note that %wd, %we, %x| and %xl now need to be on a line on their own.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8193 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/gui/gwps-common.c341
-rw-r--r--apps/gui/gwps-common.h5
-rw-r--r--apps/gui/gwps.c40
-rw-r--r--apps/gui/gwps.h2
4 files changed, 220 insertions, 168 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 665f6f4..a6ef9b0 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -55,11 +55,191 @@ static void draw_player_fullbar(struct gui_wps *gwps,
/* 3% of 30min file == 54s step size */
#define MIN_FF_REWIND_STEP 500
+/*
+ * returns the image_id between
+ * a..z and A..Z
+ */
+#ifdef HAVE_LCD_BITMAP
+static int get_image_id(int c)
+{
+ if(c >= 'a' && c <= 'z')
+ c -= 'a';
+ if(c >= 'A' && c <= 'Z')
+ c = c - 'A' + 26;
+ return c;
+}
+#endif
+/*
+ * parse the given buffer for following static tags:
+ * %x - load image for always display
+ * %xl - preload image
+ * %we - enable statusbar on wps regardless of the global setting
+ * %wd - disable statusbar on wps regardless of the global setting
+ * and also for:
+ * # - a comment line
+ *
+ * it returns true if one of these tags is found and handled
+ * false otherwise
+ */
+bool wps_data_preload_tags(struct wps_data *data, unsigned char *buf,
+ const char *bmpdir, size_t bmpdirlen)
+{
+ if(!data || !buf) return false;
+
+ char c;
+#ifndef HAVE_LCD_BITMAP
+ /* no bitmap-lcd == no bitmap loading */
+ (void)bmpdir;
+ (void)bmpdirlen;
+#endif
+ /* jump over the UTF-8 BOM(Byte Order Mark) if exist
+ * the BOM for UTF-8 is 3 bytes long and looks like so:
+ * 1. Byte: 0xEF
+ * 2. Byte: 0xBB
+ * 3. Byte: 0xBF
+ */
+ if(buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
+ buf+=3;
+
+ if(*buf == '#')
+ return true;
+ if('%' != *buf)
+ return false;
+ buf++;
+
+ c = *buf;
+ switch (c)
+ {
+#ifdef HAVE_LCD_BITMAP
+ case 'w':
+ /*
+ * if tag found then return because these two tags must be on
+ * must be on their own line
+ */
+ if(*(buf+1) == 'd' || *(buf+1) == 'e')
+ {
+ data->wps_sb_tag = true;
+ if( *(buf+1) == 'e' )
+ data->show_sb_on_wps = true;
+ return true;
+ }
+ break;
+
+ case 'x':
+ /* Preload images so the %xd# tag can display it */
+ {
+ int ret = 0;
+ int n;
+ char *ptr = buf+1;
+ char *pos = NULL;
+ char imgname[MAX_PATH];
+ char qual = *ptr;
+
+ if (qual == 'l' || qual == '|') /* format:
+ %x|n|filename.bmp|x|y|
+ or
+ %xl|n|filename.bmp|x|y|
+ */
+ {
+ ptr = strchr(ptr, '|') + 1;
+ pos = strchr(ptr, '|');
+ if (pos)
+ {
+ /* get the image ID */
+ n = get_image_id(*ptr);
+
+ if(n < 0 || n >= MAX_IMAGES)
+ {
+ /* Skip the rest of the line */
+ while(*buf != '\n')
+ buf++;
+ return false;
+ }
+ ptr = pos+1;
+
+ /* check the image number and load state */
+ if (data->img[n].loaded)
+ {
+ /* Skip the rest of the line */
+ while(*buf != '\n')
+ buf++;
+ return false;
+ }
+ else
+ {
+ /* get filename */
+ pos = strchr(ptr, '|');
+ if ((pos - ptr) <
+ (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2)
+ {
+ memcpy(imgname, bmpdir, bmpdirlen);
+ imgname[bmpdirlen] = '/';
+ memcpy(&imgname[bmpdirlen+1],
+ ptr, pos - ptr);
+ imgname[bmpdirlen+1+pos-ptr] = 0;
+ }
+ else
+ /* filename too long */
+ imgname[0] = 0;
+
+ ptr = pos+1;
+
+ /* get x-position */
+ pos = strchr(ptr, '|');
+ if (pos)
+ data->img[n].x = atoi(ptr);
+ else
+ {
+ /* weird syntax, bail out */
+ buf++;
+ return false;
+ }
+
+ /* get y-position */
+ ptr = pos+1;
+ pos = strchr(ptr, '|');
+ if (pos)
+ data->img[n].y = atoi(ptr);
+ else
+ {
+ /* weird syntax, bail out */
+ buf++;
+ return false;
+ }
+
+ /* load the image */
+ ret = read_bmp_file(imgname, &data->img[n].w,
+ &data->img[n].h, data->img_buf_ptr,
+ data->img_buf_free);
+ if (ret > 0)
+ {
+ data->img[n].ptr = data->img_buf_ptr;
+ data->img_buf_ptr += ret;
+ data->img_buf_free -= ret;
+ data->img[n].loaded = true;
+ if(qual == '|')
+ data->img[n].always_display = true;
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ break;
+#endif
+ }
+ /* no of these tags found */
+ return false;
+}
+
+
/* draws the statusbar on the given wps-screen */
#ifdef HAVE_LCD_BITMAP
static void gui_wps_statusbar_draw(struct gui_wps *wps, bool force)
{
bool draw = global_settings.statusbar;
+
if(wps->data->wps_sb_tag
&& wps->data->show_sb_on_wps)
draw = true;
@@ -781,13 +961,7 @@ static void format_display(struct gui_wps *gwps, char* buf,
case 'x': /* image support */
#ifdef HAVE_LCD_BITMAP
- /* skip preload or regular image tag */
- if ('l' == *(fmt+1) || '|' == *(fmt+1))
- {
- while (*fmt && *fmt != '\n')
- fmt++;
- }
- else if ('d' == *(fmt+1) )
+ if ('d' == *(fmt+1) )
{
fmt+=2;
@@ -925,23 +1099,13 @@ void fade(bool fade_in)
}
/* Set format string to use for WPS, splitting it into lines */
-void gui_wps_format(struct wps_data *data, const char *bmpdir,
- size_t bmpdirlen)
+void gui_wps_format(struct wps_data *data)
{
char* buf = data->format_buffer;
char* start_of_line = data->format_buffer;
int line = 0;
int subline;
- char c, lastc = 0;
-#ifndef HAVE_LCD_BITMAP
- /* no bitmap lcd == no bitmap loading */
- (void)bmpdir;
- (void)bmpdirlen;
-#else
- unsigned char* img_buf_ptr = data->img_buf; /* where in image buffer */
-
- int img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
-#endif
+ char c;
if(!data)
return;
@@ -955,16 +1119,11 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
data->subline_expire_time[line] = 0;
data->curr_subline[line] = SUBLINE_RESET;
}
-
+
line = 0;
subline = 0;
data->format_lines[line][subline] = buf;
-#ifdef HAVE_LCD_BITMAP
- bool wps_tag_found = false;
- data->wps_sb_tag = false;
- data->show_sb_on_wps = false;
-#endif
while ((*buf) && (line < WPS_MAX_LINES))
{
c = *buf;
@@ -976,18 +1135,7 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
* don't skip %x lines (pre-load bitmaps)
*/
case '%':
-#ifdef HAVE_LCD_BITMAP
- if(*(buf+1) == 'w' && (*(buf+2) == 'd' || *(buf+2) == 'e')
- && !wps_tag_found)
- {
- data->wps_sb_tag = true;
- if( *(buf+1) == 'w' && *(buf+2) == 'e' )
- data->show_sb_on_wps = true;
- wps_tag_found = true;
- }
- if (*(buf+1) != 'x')
-#endif
- buf++;
+ buf++;
break;
case '\r': /* CR */
@@ -1029,126 +1177,7 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
subline = 0;
}
break;
-
- case 'x':
-#ifdef HAVE_LCD_BITMAP
- /* Preload images so the %xd# tag can display it */
- {
- int ret = 0;
- int n;
- char *ptr = buf+1;
- char *pos = NULL;
- char imgname[MAX_PATH];
- char qual = *ptr;
-
- if(lastc != '%')
- break;
-
- if (qual == 'l' || qual == '|') /* format:
- %x|n|filename.bmp|x|y|
- or
- %xl|n|filename.bmp|x|y|
- */
- {
- ptr = strchr(ptr, '|') + 1;
- pos = strchr(ptr, '|');
- if (pos)
- {
- /* get the image ID */
- n = *ptr;
- if(n >= 'a' && n <= 'z')
- n -= 'a';
- if(n >= 'A' && n <= 'Z')
- n = n - 'A' + 26;
-
- if(n < 0 || n >= MAX_IMAGES)
- {
- /* Skip the rest of the line */
- while(*buf != '\n')
- buf++;
- break;
- }
- ptr = pos+1;
-
- /* check the image number and load state */
- if (data->img[n].loaded)
- {
- /* Skip the rest of the line */
- while(*buf != '\n')
- buf++;
- break;
- }
- else
- {
- /* get filename */
- pos = strchr(ptr, '|');
- if ((pos - ptr) <
- (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2)
- {
- memcpy(imgname, bmpdir, bmpdirlen);
- imgname[bmpdirlen] = '/';
- memcpy(&imgname[bmpdirlen+1],
- ptr, pos - ptr);
- imgname[bmpdirlen+1+pos-ptr] = 0;
- }
- else
- /* filename too long */
- imgname[0] = 0;
-
- ptr = pos+1;
-
- /* get x-position */
- pos = strchr(ptr, '|');
- if (pos)
- data->img[n].x = atoi(ptr);
- else
- {
- /* weird syntax, bail out */
- buf++;
- break;
- }
-
- /* get y-position */
- ptr = pos+1;
- pos = strchr(ptr, '|');
- if (pos)
- data->img[n].y = atoi(ptr);
- else
- {
- /* weird syntax, bail out */
- buf++;
- break;
- }
-
- pos++;
-
- /* reposition buf pointer to next WPS element */
- while (*pos && *pos != ';' && *pos != '\n')
- pos++;
-
- buf = pos;
-
- /* load the image */
- ret = read_bmp_file(imgname, &data->img[n].w,
- &data->img[n].h, (char *)img_buf_ptr,
- img_buf_free);
- if (ret > 0)
- {
- data->img[n].ptr = img_buf_ptr;
- img_buf_ptr += ret;
- img_buf_free -= ret;
- data->img[n].loaded = true;
- if(qual == '|')
- data->img[n].always_display = true;
- }
- }
- }
- }
- }
-#endif
- break;
}
- lastc = c;
buf++;
}
}
diff --git a/apps/gui/gwps-common.h b/apps/gui/gwps-common.h
index e9c1a42..7909270 100644
--- a/apps/gui/gwps-common.h
+++ b/apps/gui/gwps-common.h
@@ -25,8 +25,7 @@
void gui_wps_format_time(char* buf, int buf_size, long time);
void fade(bool fade_in);
-void gui_wps_format(struct wps_data *data, const char *bmpdir,
- size_t bmpdirlen);
+void gui_wps_format(struct wps_data *data);
bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset,
unsigned char refresh_mode);
bool gui_wps_display(void);
@@ -34,6 +33,8 @@ void setvol(void);
bool update_onvol_change(struct gui_wps * gwps);
bool update(struct gui_wps *gwps);
bool ffwd_rew(int button);
+bool wps_data_preload_tags(struct wps_data *data, unsigned char *buf,
+ const char *bmpdir, size_t bmpdirlen);
#ifdef WPS_KEYLOCK
void display_keylock_text(bool locked);
void waitfor_nokey(void);
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 52242d8..bd7591f 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -734,6 +734,8 @@ static void wps_clear(struct wps_data *data )
data->img[i].display = false;
data->img[i].always_display = false;
}
+ data->wps_sb_tag = false;
+ data->show_sb_on_wps = false;
}
#else
#define wps_clear(a)
@@ -764,7 +766,7 @@ bool wps_data_load(struct wps_data *wps_data,
wps_clear(wps_data);
strncpy(wps_data->format_buffer, buf, sizeof(wps_data->format_buffer));
wps_data->format_buffer[sizeof(wps_data->format_buffer) - 1] = 0;
- gui_wps_format(wps_data, NULL, 0);
+ gui_wps_format(wps_data);
return true;
}
else
@@ -798,16 +800,34 @@ bool wps_data_load(struct wps_data *wps_data,
if (fd >= 0)
{
- int numread = read(fd, wps_data->format_buffer,
- sizeof(wps_data->format_buffer) - 1);
-
- if (numread > 0)
- {
+ unsigned int start = 0;
+
+ wps_reset(wps_data);
#ifdef HAVE_LCD_BITMAP
- wps_clear(wps_data);
+ wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
+
+ wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
#endif
- wps_data->format_buffer[numread] = 0;
- gui_wps_format(wps_data, buf, bmpdirlen);
+ while( ( read_line(fd, &wps_data->format_buffer[start],
+ sizeof(wps_data->format_buffer)-start) ) > 0 )
+ {
+ if(!wps_data_preload_tags(wps_data,
+ &wps_data->format_buffer[start],
+ buf, bmpdirlen))
+ {
+ start += strlen(&wps_data->format_buffer[start]);
+
+ if (start < sizeof(wps_data->format_buffer) - 1)
+ {
+ wps_data->format_buffer[start++] = '\n';
+ wps_data->format_buffer[start] = 0;
+ }
+ }
+ }
+
+ if (start > 0)
+ {
+ gui_wps_format(wps_data);
}
close(fd);
@@ -853,7 +873,7 @@ bool wps_data_load(struct wps_data *wps_data,
}
wps_data->wps_loaded = true;
- return numread > 0;
+ return start > 0;
}
}
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 66199bc..4072e17 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -255,6 +255,8 @@ struct wps_data
#ifdef HAVE_LCD_BITMAP
struct gui_img img[MAX_IMAGES];
unsigned char img_buf[IMG_BUFSIZE];
+ unsigned char* img_buf_ptr;
+ int img_buf_free;
bool wps_sb_tag;
bool show_sb_on_wps;
#endif