summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-03-22 00:31:22 +0000
committerDave Chapman <dave@dchapman.com>2008-03-22 00:31:22 +0000
commit45b2d8802d1e8fcc47fd1148adb7b1173ad5b311 (patch)
tree849eea4153daaf7dfafd571ca6b93b6f985b1ff9
parent7ee63e22c58f4a7017136871e7b55dd702c5f460 (diff)
Reduce the shocking amount of RAM my viewports implementation was using. The first version stored an array of lines for each of the 16 possible viewports (MAX_VIEWPORTS * the number of lines on the LCD with a 5-pixel high font). This version reverts back to a single global array of lines, with each viewport specifying the first and last lines as indexes into that array. This also turns out to be simpler, reducing binsize a little as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16735 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c70
-rw-r--r--apps/gui/gwps.h24
-rw-r--r--apps/gui/wps_debug.c7
-rw-r--r--apps/gui/wps_parser.c36
4 files changed, 70 insertions, 67 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index ae5492a66c..3c3bad3056 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -1466,7 +1466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
The return value indicates whether the line needs to be updated.
*/
static bool get_line(struct gui_wps *gwps,
- int v, int line, int subline,
+ int line, int subline,
struct align_pos *align,
char *linebuf,
int linebuf_size)
@@ -1494,8 +1494,8 @@ static bool get_line(struct gui_wps *gwps,
#endif
/* Process all tokens of the desired subline */
- last_token_idx = wps_last_token_index(data, v, line, subline);
- for (i = wps_first_token_index(data, v, line, subline);
+ last_token_idx = wps_last_token_index(data, line, subline);
+ for (i = wps_first_token_index(data, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@@ -1594,16 +1594,16 @@ static bool get_line(struct gui_wps *gwps,
return update;
}
-static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subline)
+static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
{
struct wps_data *data = gwps->data;
int i;
- int subline_idx = wps_subline_index(data, v, line, subline);
- int last_token_idx = wps_last_token_index(data, v, line, subline);
+ int subline_idx = wps_subline_index(data, line, subline);
+ int last_token_idx = wps_last_token_index(data, line, subline);
data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
- for (i = wps_first_token_index(data, v, line, subline);
+ for (i = wps_first_token_index(data, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@@ -1631,7 +1631,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subli
/* Calculates which subline should be displayed for the specified line
Returns true iff the subline must be refreshed */
-static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
+static bool update_curr_subline(struct gui_wps *gwps, int line)
{
struct wps_data *data = gwps->data;
@@ -1640,13 +1640,13 @@ static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
bool new_subline_refresh;
bool only_one_subline;
- num_sublines = data->viewports[v].lines[line].num_sublines;
- reset_subline = (data->viewports[v].lines[line].curr_subline == SUBLINE_RESET);
+ num_sublines = data->lines[line].num_sublines;
+ reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET);
new_subline_refresh = false;
only_one_subline = false;
/* if time to advance to next sub-line */
- if (TIME_AFTER(current_tick, data->viewports[v].lines[line].subline_expire_time - 1) ||
+ if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) ||
reset_subline)
{
/* search all sublines until the next subline with time > 0
@@ -1654,46 +1654,46 @@ static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
if (reset_subline)
search_start = 0;
else
- search_start = data->viewports[v].lines[line].curr_subline;
+ search_start = data->lines[line].curr_subline;
for (search = 0; search < num_sublines; search++)
{
- data->viewports[v].lines[line].curr_subline++;
+ data->lines[line].curr_subline++;
/* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
- if (data->viewports[v].lines[line].curr_subline == num_sublines)
+ if (data->lines[line].curr_subline == num_sublines)
{
- if (data->viewports[v].lines[line].curr_subline == 1)
+ if (data->lines[line].curr_subline == 1)
only_one_subline = true;
- data->viewports[v].lines[line].curr_subline = 0;
+ data->lines[line].curr_subline = 0;
}
/* if back where we started after search or
only one subline is defined on the line */
if (((search > 0) &&
- (data->viewports[v].lines[line].curr_subline == search_start)) ||
+ (data->lines[line].curr_subline == search_start)) ||
only_one_subline)
{
/* no other subline with a time > 0 exists */
- data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
+ data->lines[line].subline_expire_time = (reset_subline ?
current_tick :
- data->viewports[v].lines[line].subline_expire_time) + 100 * HZ;
+ data->lines[line].subline_expire_time) + 100 * HZ;
break;
}
else
{
/* get initial time multiplier for this subline */
- get_subline_timeout(gwps, v, line, data->viewports[v].lines[line].curr_subline);
+ get_subline_timeout(gwps, line, data->lines[line].curr_subline);
- int subline_idx = wps_subline_index(data, v, line,
- data->viewports[v].lines[line].curr_subline);
+ int subline_idx = wps_subline_index(data, line,
+ data->lines[line].curr_subline);
/* only use this subline if subline time > 0 */
if (data->sublines[subline_idx].time_mult > 0)
{
new_subline_refresh = true;
- data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
- current_tick : data->viewports[v].lines[line].subline_expire_time) +
+ data->lines[line].subline_expire_time = (reset_subline ?
+ current_tick : data->lines[line].subline_expire_time) +
BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult;
break;
}
@@ -1909,12 +1909,9 @@ bool gui_wps_refresh(struct gui_wps *gwps,
{
display->clear_display();
- for (v = 0; v < data->num_viewports; v++)
+ for (i = 0; i <= data->num_lines; i++)
{
- for (i = 0; i < data->viewports[v].num_lines; i++)
- {
- data->viewports[v].lines[i].curr_subline = SUBLINE_RESET;
- }
+ data->lines[i].curr_subline = SUBLINE_RESET;
}
}
@@ -1951,23 +1948,24 @@ bool gui_wps_refresh(struct gui_wps *gwps,
}
#endif
- for (line = 0; line < data->viewports[v].num_lines; line++)
+ for (line = data->viewports[v].first_line;
+ line <= data->viewports[v].last_line; line++)
{
memset(linebuf, 0, sizeof(linebuf));
update_line = false;
/* get current subline for the line */
- new_subline_refresh = update_curr_subline(gwps, v, line);
+ new_subline_refresh = update_curr_subline(gwps, line);
- subline_idx = wps_subline_index(data, v, line,
- data->viewports[v].lines[line].curr_subline);
+ subline_idx = wps_subline_index(data, line,
+ data->lines[line].curr_subline);
flags = data->sublines[subline_idx].line_type;
if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
|| new_subline_refresh)
{
/* get_line tells us if we need to update the line */
- update_line = get_line(gwps, v, line, data->viewports[v].lines[line].curr_subline,
+ update_line = get_line(gwps, line, data->lines[line].curr_subline,
&align, linebuf, sizeof(linebuf));
}
@@ -2021,10 +2019,10 @@ bool gui_wps_refresh(struct gui_wps *gwps,
/* if the line is a scrolling one we don't want to update
too often, so that it has the time to scroll */
if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
- write_line(display, &align, line, true);
+ write_line(display, &align, line - data->viewports[v].first_line, true);
}
else
- write_line(display, &align, line, false);
+ write_line(display, &align, line - data->viewports[v].first_line, false);
}
}
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index d31471c2a4..e72b41308b 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -88,7 +88,7 @@ struct align_pos {
+ (2*LCD_HEIGHT*LCD_WIDTH/8))
#define WPS_MAX_VIEWPORTS 16
-#define WPS_MAX_LINES (LCD_HEIGHT/5+1)
+#define WPS_MAX_LINES ((LCD_HEIGHT/5+1) * 2)
#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
#define WPS_MAX_TOKENS 1024
#define WPS_MAX_STRINGS 128
@@ -321,10 +321,9 @@ struct wps_line {
struct wps_viewport {
struct viewport vp; /* The LCD viewport struct */
- /* Number of lines in this viewport. During WPS parsing, this is
- the index of the line being parsed. */
- int num_lines;
- struct wps_line lines[WPS_MAX_LINES];
+ /* Indexes of the first and last lines belonging to this viewport in the
+ lines[] array */
+ int first_line, last_line;
};
/* wps_data
@@ -371,10 +370,16 @@ struct wps_data
bool remote_wps;
#endif
+ /* Number of lines in the WPS. During WPS parsing, this is
+ the index of the line being parsed. */
+ int num_lines;
+
/* Number of viewports in the WPS */
int num_viewports;
struct wps_viewport viewports[WPS_MAX_VIEWPORTS];
+ struct wps_line lines[WPS_MAX_LINES];
+
/* Total number of sublines in the WPS. During WPS parsing, this is
the index of the subline where the parsed tokens are added to. */
int num_sublines;
@@ -403,25 +408,22 @@ bool wps_data_load(struct wps_data *wps_data,
bool isfile);
/* Returns the index of the subline in the subline array
- v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_subline_index(struct wps_data *wps_data, int v, int line, int subline);
+int wps_subline_index(struct wps_data *wps_data, int line, int subline);
/* Returns the index of the first subline's token in the token array
- v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_first_token_index(struct wps_data *data, int v, int line, int subline);
+int wps_first_token_index(struct wps_data *data, int line, int subline);
/* Returns the index of the last subline's token in the token array.
- v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_last_token_index(struct wps_data *data, int v, int line, int subline);
+int wps_last_token_index(struct wps_data *data, int line, int subline);
/* wps_data end */
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 0c13fd2c22..9bff1d23ae 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -502,7 +502,8 @@ static void print_line_info(struct wps_data *data)
DEBUGF("Number of viewports : %d\n", data->num_viewports);
for (v = 0; v < data->num_viewports; v++)
{
- DEBUGF("vp %d: Number of lines: %d\n", v, data->viewports[v].num_lines);
+ DEBUGF("vp %d: First line: %d\n", v, data->viewports[v].first_line);
+ DEBUGF("vp %d: Last line: %d\n", v, data->viewports[v].last_line);
}
DEBUGF("Number of sublines : %d\n", data->num_sublines);
DEBUGF("Number of tokens : %d\n", data->num_tokens);
@@ -517,7 +518,7 @@ static void print_line_info(struct wps_data *data)
data->viewports[v].vp.y,
data->viewports[v].vp.width,
data->viewports[v].vp.height);
- for (i = 0, line = data->viewports[v].lines; i < data->viewports[v].num_lines; i++,line++)
+ for (i = data->viewports[v].first_line, line = &data->lines[data->viewports[v].first_line]; i <= data->viewports[v].last_line; i++,line++)
{
DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
i, line->num_sublines, line->first_subline_idx);
@@ -527,7 +528,7 @@ static void print_line_info(struct wps_data *data)
{
DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
j, subline->first_token_idx,
- wps_last_token_index(data, v, i, j));
+ wps_last_token_index(data, i, j));
if (subline->line_type & WPS_REFRESH_SCROLL)
DEBUGF(", scrolled");
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index c641f2c247..be3d2fb882 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -338,11 +338,9 @@ static int skip_end_of_line(const char *wps_bufptr)
/* Starts a new subline in the current line during parsing */
static void wps_start_new_subline(struct wps_data *data)
{
- struct wps_viewport* vp = &data->viewports[data->num_viewports];
-
data->num_sublines++;
data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
- vp->lines[vp->num_lines].num_sublines++;
+ data->lines[data->num_lines].num_sublines++;
}
#ifdef HAVE_LCD_BITMAP
@@ -585,12 +583,14 @@ static int parse_viewport(const char *wps_bufptr,
}
}
#endif
-
- wps_data->viewports[wps_data->num_viewports].num_lines = 0;
+
+ wps_data->viewports[wps_data->num_viewports-1].last_line = wps_data->num_lines - 1;
+
+ wps_data->viewports[wps_data->num_viewports].first_line = wps_data->num_lines;
if (wps_data->num_sublines < WPS_MAX_SUBLINES)
{
- wps_data->viewports[wps_data->num_viewports].lines[0].first_subline_idx =
+ wps_data->lines[wps_data->num_lines].first_subline_idx =
wps_data->num_sublines;
wps_data->sublines[wps_data->num_sublines].first_token_idx =
@@ -599,7 +599,7 @@ static int parse_viewport(const char *wps_bufptr,
/* Skip the rest of the line */
return skip_end_of_line(wps_bufptr);
- }
+}
static int parse_image_special(const char *wps_bufptr,
@@ -1072,7 +1072,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1
&& data->num_viewports < WPS_MAX_VIEWPORTS
- && data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES)
+ && data->num_lines < WPS_MAX_LINES)
{
switch(*wps_bufptr++)
{
@@ -1180,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
line++;
wps_start_new_subline(data);
- data->viewports[data->num_viewports].num_lines++; /* Start a new line */
+ data->num_lines++; /* Start a new line */
- if ((data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) &&
+ if ((data->num_lines < WPS_MAX_LINES) &&
(data->num_sublines < WPS_MAX_SUBLINES))
{
- data->viewports[data->num_viewports].lines[data->viewports[data->num_viewports].num_lines].first_subline_idx =
+ data->lines[data->num_lines].first_subline_idx =
data->num_sublines;
data->sublines[data->num_sublines].first_token_idx =
@@ -1262,6 +1262,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
if (!fail && level >= 0) /* there are unclosed conditionals */
fail = PARSE_FAIL_UNCLOSED_COND;
+ data->viewports[data->num_viewports].last_line = data->num_lines - 1;
+
/* We have finished with the last viewport, so increment count */
data->num_viewports++;
@@ -1512,20 +1514,20 @@ bool wps_data_load(struct wps_data *wps_data,
}
}
-int wps_subline_index(struct wps_data *data, int v, int line, int subline)
+int wps_subline_index(struct wps_data *data, int line, int subline)
{
- return data->viewports[v].lines[line].first_subline_idx + subline;
+ return data->lines[line].first_subline_idx + subline;
}
-int wps_first_token_index(struct wps_data *data, int v, int line, int subline)
+int wps_first_token_index(struct wps_data *data, int line, int subline)
{
- int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
+ int first_subline_idx = data->lines[line].first_subline_idx;
return data->sublines[first_subline_idx + subline].first_token_idx;
}
-int wps_last_token_index(struct wps_data *data, int v, int line, int subline)
+int wps_last_token_index(struct wps_data *data, int line, int subline)
{
- int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
+ int first_subline_idx = data->lines[line].first_subline_idx;
int idx = first_subline_idx + subline;
if (idx < data->num_sublines - 1)
{