From 8cb74438bc7c282f1ac9803afd1d1f9e68af17ae Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Wed, 2 Sep 2009 02:55:33 +0000 Subject: Almost the last of the skin ram wastage fixing... This one moved the line/subline handling into the alloced buffer and links them more sensibly with their viewports. now it works something like this: a skin is a list of viewports, each viewport has a list of lines, each line is a list of sublines, each subline has an *index* of its first and last tokens... git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22602 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_buffer.c | 2 + apps/gui/skin_engine/skin_display.c | 196 +++++++++++------------------------ apps/gui/skin_engine/skin_parser.c | 137 ++++++++++++++++-------- apps/gui/skin_engine/skin_tokens.c | 2 + apps/gui/skin_engine/wps_debug.c | 28 ++--- apps/gui/skin_engine/wps_internals.h | 43 +++----- 6 files changed, 188 insertions(+), 220 deletions(-) (limited to 'apps/gui/skin_engine') diff --git a/apps/gui/skin_engine/skin_buffer.c b/apps/gui/skin_engine/skin_buffer.c index c7e01ba5cd..1d18fb9431 100644 --- a/apps/gui/skin_engine/skin_buffer.c +++ b/apps/gui/skin_engine/skin_buffer.c @@ -118,6 +118,8 @@ void* skin_buffer_alloc(size_t size) buffer_back -= size; /* 32-bit aligned */ buffer_back = (void *)(((unsigned long)buffer_back) & ~3); + + memset(buffer_back, 0, size); return buffer_back; } diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 409984494c..4aeafb595d 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -391,41 +391,6 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) #endif /* HAVE_LCD_CHARCELL */ -/* Returns the index of the subline in the subline array - line - 0-based line number - subline - 0-based subline number within the line - */ -static int subline_index(struct wps_data *data, int line, int subline) -{ - return data->lines[line].first_subline_idx + subline; -} - -/* Returns the index of the first subline's token in the token array - line - 0-based line number - subline - 0-based subline number within the line - */ -static int first_token_index(struct wps_data *data, int line, int subline) -{ - int first_subline_idx = data->lines[line].first_subline_idx; - return data->sublines[first_subline_idx + subline].first_token_idx; -} - -int skin_last_token_index(struct wps_data *data, int line, int subline) -{ - int first_subline_idx = data->lines[line].first_subline_idx; - int idx = first_subline_idx + subline; - if (idx < data->num_sublines - 1) - { - /* This subline ends where the next begins */ - return data->sublines[idx+1].first_token_idx - 1; - } - else - { - /* The last subline goes to the end */ - return data->num_tokens - 1; - } -} - /* Return the index to the end token for the conditional token at index. The conditional token can be either a start token or a separator (i.e. option) token. @@ -541,7 +506,7 @@ struct skin_viewport* find_viewport(char label, struct wps_data *data) The return value indicates whether the line needs to be updated. */ static bool get_line(struct gui_wps *gwps, - int line, int subline, + struct wps_subline *subline, struct align_pos *align, char *linebuf, int linebuf_size) @@ -551,8 +516,8 @@ static bool get_line(struct gui_wps *gwps, char temp_buf[128]; char *buf = linebuf; /* will always point to the writing position */ char *linebuf_end = linebuf + linebuf_size - 1; - int i, last_token_idx; bool update = false; + int i; /* alignment-related variables */ int cur_align; @@ -562,11 +527,9 @@ static bool get_line(struct gui_wps *gwps, align->left = NULL; align->center = NULL; align->right = NULL; - /* Process all tokens of the desired subline */ - last_token_idx = skin_last_token_index(data, line, subline); - for (i = first_token_index(data, line, subline); - i <= last_token_idx; i++) + for (i = subline->first_token_idx; + i <= subline->last_token_idx; i++) { switch(data->tokens[i].type) { @@ -685,18 +648,14 @@ static bool get_line(struct gui_wps *gwps, return update; } - -static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) +static void get_subline_timeout(struct gui_wps *gwps, struct wps_subline *subline) { struct wps_data *data = gwps->data; int i; - int subline_idx = subline_index(data, line, subline); - int last_token_idx = skin_last_token_index(data, line, subline); + subline->time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; - data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; - - for (i = first_token_index(data, line, subline); - i <= last_token_idx; i++) + for (i = subline->first_token_idx; + i <= subline->last_token_idx; i++) { switch(data->tokens[i].type) { @@ -712,7 +671,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) break; case WPS_TOKEN_SUBLINE_TIMEOUT: - data->sublines[subline_idx].time_mult = data->tokens[i].value.i; + subline->time_mult = data->tokens[i].value.i; break; default: @@ -723,77 +682,37 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) /* 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 line) +static bool update_curr_subline(struct gui_wps *gwps, struct wps_line *line) { - struct wps_data *data = gwps->data; - - int search, search_start, num_sublines; - bool reset_subline; - bool new_subline_refresh; - bool only_one_subline; - - num_sublines = data->lines[line].num_sublines; - reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET); - new_subline_refresh = false; - only_one_subline = false; - + /* shortcut this whole thing if we need to reset the line completly */ + if (line->curr_subline == NULL) + { + int next_refresh = current_tick; + line->curr_subline = &line->sublines; + if (!line->curr_subline->next) + next_refresh += 100*HZ; + line->subline_expire_time = next_refresh; + return true; + } /* if time to advance to next sub-line */ - if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) || - reset_subline) + if (TIME_AFTER(current_tick, line->subline_expire_time - 1)) { - /* search all sublines until the next subline with time > 0 - is found or we get back to the subline we started with */ - if (reset_subline) - search_start = 0; - else - search_start = data->lines[line].curr_subline; - - for (search = 0; search < num_sublines; search++) + /* if there is only one subline, there is no need to search for a new one */ + if (&line->sublines == line->curr_subline && + line->curr_subline->next == NULL) { - data->lines[line].curr_subline++; - - /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */ - if (data->lines[line].curr_subline == num_sublines) - { - if (data->lines[line].curr_subline == 1) - only_one_subline = true; - 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->lines[line].curr_subline == search_start)) || - only_one_subline) - { - /* no other subline with a time > 0 exists */ - data->lines[line].subline_expire_time = (reset_subline ? - current_tick : - data->lines[line].subline_expire_time) + 100 * HZ; - break; - } - else - { - /* get initial time multiplier for this subline */ - get_subline_timeout(gwps, line, data->lines[line].curr_subline); - - int subline_idx = 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->lines[line].subline_expire_time = (reset_subline ? - current_tick : data->lines[line].subline_expire_time) + - TIMEOUT_UNIT*data->sublines[subline_idx].time_mult; - break; - } - } + line->subline_expire_time += 100 * HZ; + return true; } + if (line->curr_subline->next) + line->curr_subline = line->curr_subline->next; + else + line->curr_subline = &line->sublines; + get_subline_timeout(gwps, line->curr_subline); + line->subline_expire_time += TIMEOUT_UNIT*line->curr_subline->time_mult; + return true; } - - return new_subline_refresh; + return false; } /* Display a line appropriately according to its alignment format. @@ -971,8 +890,7 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) if (!id3) return false; - - int line, i, subline_idx; + unsigned flags; char linebuf[MAX_PATH]; @@ -980,6 +898,9 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) align.left = NULL; align.center = NULL; align.right = NULL; + + + struct skin_token_list *viewport_list; bool update_line, new_subline_refresh; @@ -999,12 +920,20 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) /* reset to first subline if refresh all flag is set */ if (refresh_mode == WPS_REFRESH_ALL) { + struct wps_line *line; + display->set_viewport(&find_viewport(VP_DEFAULT_LABEL, data)->vp); display->clear_viewport(); - - for (i = 0; i <= data->num_lines; i++) + + for (viewport_list = data->viewports; + viewport_list; viewport_list = viewport_list->next) { - data->lines[i].curr_subline = SUBLINE_RESET; + struct skin_viewport *skin_viewport = + (struct skin_viewport *)viewport_list->token->value.data; + for(line = skin_viewport->lines; line; line = line->next) + { + line->curr_subline = NULL; + } } } @@ -1017,7 +946,6 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) #endif /* disable any viewports which are conditionally displayed */ - struct skin_token_list *viewport_list; for (viewport_list = data->viewports; viewport_list; viewport_list = viewport_list->next) { @@ -1069,25 +997,27 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) { display->clear_viewport(); } + + /* loop over the lines for this viewport */ + struct wps_line *line; + int line_count = 0; - for (line = skin_viewport->first_line; - line <= skin_viewport->last_line; line++) + for (line = skin_viewport->lines; line; line = line->next, line_count++) { + struct wps_subline *subline; memset(linebuf, 0, sizeof(linebuf)); update_line = false; /* get current subline for the line */ new_subline_refresh = update_curr_subline(gwps, line); - - subline_idx = subline_index(data, line, - data->lines[line].curr_subline); - flags = data->sublines[subline_idx].line_type; + subline = line->curr_subline; + flags = line->curr_subline->line_type; if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) || new_subline_refresh) { /* get_line tells us if we need to update the line */ - update_line = get_line(gwps, line, data->lines[line].curr_subline, + update_line = get_line(gwps, subline, &align, linebuf, sizeof(linebuf)); } #ifdef HAVE_LCD_BITMAP @@ -1098,19 +1028,19 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) update_line = false; int h = font_get(skin_viewport->vp.font)->height; - int peak_meter_y = (line - skin_viewport->first_line)* h; + int peak_meter_y = line_count* h; /* The user might decide to have the peak meter in the last line so that it is only displayed if no status bar is visible. If so we neither want do draw nor enable the peak meter. */ - if (peak_meter_y + h <= display->getheight()) { + if (peak_meter_y + h <= skin_viewport->vp.y+skin_viewport->vp.height) { /* found a line with a peak meter -> remember that we must enable it later */ enable_pm = true; peak_meter_enabled = true; peak_meter_screen(gwps->display, 0, peak_meter_y, - MIN(h, display->getheight() - peak_meter_y)); + MIN(h, skin_viewport->vp.y+skin_viewport->vp.height - peak_meter_y)); } else { @@ -1143,10 +1073,10 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) /* if the line is a scrolling one we don't want to update too often, so that it has the time to scroll */ if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) - write_line(display, &align, line - skin_viewport->first_line, true); + write_line(display, &align, line_count, true); } else - write_line(display, &align, line - skin_viewport->first_line, false); + write_line(display, &align, line_count, false); } } diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 68bddf6205..f8c9b75a87 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -72,11 +72,13 @@ static int condindex[WPS_MAX_COND_LEVEL]; /* number of condtional options in current level */ static int numoptions[WPS_MAX_COND_LEVEL]; -/* the current line in the file */ -static int line; +/* line number, debug only */ +static int line_number; /* the current viewport */ static struct skin_viewport *curr_vp; +/* the current line, linked to the above viewport */ +static struct wps_line *curr_line; #ifdef HAVE_LCD_BITMAP @@ -397,7 +399,7 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, immediately after the first eol, i.e. to the start of the next line */ static int skip_end_of_line(const char *wps_bufptr) { - line++; + line_number++; int skip = 0; while(*(wps_bufptr + skip) != '\n') skip++; @@ -405,11 +407,59 @@ 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) +static bool wps_start_new_subline(struct wps_line *line, int curr_token) { - data->num_sublines++; - data->sublines[data->num_sublines].first_token_idx = data->num_tokens; - data->lines[data->num_lines].num_sublines++; + struct wps_subline *subline = skin_buffer_alloc(sizeof(struct wps_subline)); + if (!subline) + return false; + + subline->first_token_idx = curr_token; + subline->next = NULL; + + subline->line_type = 0; + subline->time_mult = 0; + + line->curr_subline->last_token_idx = curr_token-1; + line->curr_subline->next = subline; + line->curr_subline = subline; + return true; +} + +static bool wps_start_new_line(struct skin_viewport *vp, int curr_token) +{ + struct wps_line *line = skin_buffer_alloc(sizeof(struct wps_line)); + struct wps_subline *subline = NULL; + if (!line) + return false; + + /* init the subline */ + subline = &line->sublines; + subline->first_token_idx = curr_token; + subline->next = NULL; + subline->line_type = 0; + subline->time_mult = 0; + + /* init the new line */ + line->curr_subline = &line->sublines; + line->next = NULL; + line->subline_expire_time = 0; + + /* connect to curr_line and vp pointers. + * 1) close the previous lines subline + * 2) connect to vp pointer + * 3) connect to curr_line global pointer + */ + if (curr_line) + { + curr_line->curr_subline->last_token_idx = curr_token - 1; + curr_line->next = line; + curr_line->curr_subline = NULL; + } + curr_line = line; + if (!vp->lines) + vp->lines = line; + line_number++; + return true; } #ifdef HAVE_LCD_BITMAP @@ -617,6 +667,12 @@ static int parse_viewport(const char *wps_bufptr, skin_vp->hidden_flags = 0; skin_vp->label = VP_NO_LABEL; skin_vp->pb = NULL; + skin_vp->lines = NULL; + + curr_line = NULL; + if (!wps_start_new_line(skin_vp, wps_data->num_tokens)) + return WPS_ERROR_INVALID_PARAM; + if (*ptr == 'l') { @@ -647,18 +703,6 @@ static int parse_viewport(const char *wps_bufptr, if (*ptr != '|') return WPS_ERROR_INVALID_PARAM; - curr_vp->last_line = wps_data->num_lines - 1; - - skin_vp->first_line = wps_data->num_lines; - - if (wps_data->num_sublines < WPS_MAX_SUBLINES) - { - wps_data->lines[wps_data->num_lines].first_subline_idx = - wps_data->num_sublines; - - wps_data->sublines[wps_data->num_sublines].first_token_idx = - wps_data->num_tokens; - } struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp); if (!list) @@ -826,8 +870,15 @@ static int parse_progressbar(const char *wps_bufptr, #else int font_height = 8; #endif - int line_num = wps_data->num_lines - curr_vp->first_line; - + /* we need to know what line number (viewport relative) this pb is, + * so count them... */ + int line_num = -1; + struct wps_line *line = curr_vp->lines; + while (line) + { + line_num++; + line = line->next; + } pb->have_bitmap_pb = false; pb->bm.data = NULL; /* no bitmap specified */ @@ -1241,8 +1292,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; token->type = tag->type; - wps_data->sublines[wps_data->num_sublines].line_type |= - tag->refresh_type; + curr_line->curr_subline->line_type |= tag->refresh_type; /* if the tag has a special parsing function, we call it */ if (tag->parse_func) @@ -1282,7 +1332,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) int ret; int max_tokens = TOKEN_BLOCK_SIZE; size_t buf_free = 0; - line = 1; + line_number = 1; level = -1; /* allocate enough RAM for a reasonable skin, grow as needed. @@ -1293,8 +1343,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) skin_buffer_increment(max_tokens * sizeof(struct wps_token), false); data->num_tokens = 0; - while(*wps_bufptr && !fail - && data->num_lines < WPS_MAX_LINES) + while (*wps_bufptr && !fail) { /* first make sure there is enough room for tokens */ if (max_tokens -1 == data->num_tokens) @@ -1337,9 +1386,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) break; } - if (data->num_sublines+1 < WPS_MAX_SUBLINES) - wps_start_new_subline(data); - else + if (!wps_start_new_subline(curr_line, data->num_tokens)) fail = PARSE_FAIL_LIMITS_EXCEEDED; break; @@ -1419,19 +1466,16 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) fail = PARSE_FAIL_UNCLOSED_COND; break; } + /* add a new token for the \n so empty lines are correct */ + data->tokens[data->num_tokens].type = WPS_TOKEN_CHARACTER; + data->tokens[data->num_tokens].value.c = '\n'; + data->tokens[data->num_tokens].next = false; + data->num_tokens++; - line++; - wps_start_new_subline(data); - data->num_lines++; /* Start a new line */ - - if ((data->num_lines < WPS_MAX_LINES) && - (data->num_sublines < WPS_MAX_SUBLINES)) - { - data->lines[data->num_lines].first_subline_idx = - data->num_sublines; - - data->sublines[data->num_sublines].first_token_idx = - data->num_tokens; + if (!wps_start_new_line(curr_vp, data->num_tokens)) + { + fail = PARSE_FAIL_LIMITS_EXCEEDED; + break; } break; @@ -1511,11 +1555,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) /* freeup unused tokens */ skin_buffer_free_from_front(sizeof(struct wps_token) * (max_tokens - data->num_tokens)); - curr_vp->last_line = data->num_lines - 1; + /* close the last subline */ + curr_line->curr_subline->last_token_idx = data->num_tokens; #if defined(DEBUG) || defined(SIMULATOR) if (debug) - print_debug_info(data, fail, line); + print_debug_info(data, fail, line_number); #else (void)debug; #endif @@ -1658,6 +1703,12 @@ bool skin_data_load(struct wps_data *wps_data, curr_vp->vp.height = display->getheight(); curr_vp->pb = NULL; curr_vp->hidden_flags = 0; + curr_vp->lines = NULL; + + curr_line = NULL; + if (!wps_start_new_line(curr_vp, 0)) + return false; + switch (statusbar_position(display->screen_type)) { case STATUSBAR_OFF: diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 386dc5ded8..1254900844 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -164,6 +164,8 @@ const char *get_token_value(struct gui_wps *gwps, switch (token->type) { case WPS_TOKEN_CHARACTER: + if (token->value.c == '\n') + return NULL; return &(token->value.c); case WPS_TOKEN_STRING: diff --git a/apps/gui/skin_engine/wps_debug.c b/apps/gui/skin_engine/wps_debug.c index 78f58c42b1..8e0727516a 100644 --- a/apps/gui/skin_engine/wps_debug.c +++ b/apps/gui/skin_engine/wps_debug.c @@ -60,8 +60,11 @@ static char *get_token_desc(struct wps_token *token, char *buf, int bufsize) break; case WPS_TOKEN_CHARACTER: - snprintf(buf, bufsize, "Character '%c'", - token->value.c); + if (token->value.c == '\n') + snprintf(buf, bufsize, "Character '\\n'"); + else + snprintf(buf, bufsize, "Character '%c'", + token->value.c); break; case WPS_TOKEN_STRING: @@ -486,7 +489,6 @@ static void dump_wps_tokens(struct wps_data *data) static void print_line_info(struct wps_data *data) { - int i, j; struct wps_line *line; struct wps_subline *subline; if (wps_verbose_level > 0) @@ -498,16 +500,14 @@ static void print_line_info(struct wps_data *data) struct skin_viewport *v = (struct skin_viewport *)viewport_list->token->value.data; DEBUGF("vp Label:'%c' Hidden flags:%x\n", v->label, v->hidden_flags); - DEBUGF(" First line: %d\n", v->first_line); - DEBUGF(" Last line: %d\n", v->last_line); } - DEBUGF("Number of sublines : %d\n", data->num_sublines); DEBUGF("Number of tokens : %d\n", data->num_tokens); DEBUGF("\n"); } if (wps_verbose_level > 1) { + int line_number = 0; struct skin_token_list *viewport_list; for (viewport_list = data->viewports; viewport_list; viewport_list = viewport_list->next) @@ -516,17 +516,15 @@ static void print_line_info(struct wps_data *data) (struct skin_viewport *)viewport_list->token->value.data; DEBUGF("Viewport '%c' - +%d+%d (%dx%d)\n",v->label, v->vp.x, v->vp.y, v->vp.width, v->vp.height); - for (i = v->first_line, line = &data->lines[v->first_line]; i <= v->last_line; i++,line++) + for (line = v->lines; line; line = line->next, line_number++) { - DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n", - i, line->num_sublines, line->first_subline_idx); - - for (j = 0, subline = data->sublines + line->first_subline_idx; - j < line->num_sublines; j++, subline++) + DEBUGF("Line %2d\n", line_number); + int subline_number = 0; + subline = &line->sublines; + while (subline) { DEBUGF(" Subline %d: first_token=%3d, last_token=%3d", - j, subline->first_token_idx, - skin_last_token_index(data, i, j)); + subline_number, subline->first_token_idx,subline->last_token_idx); if (subline->line_type & WPS_REFRESH_SCROLL) DEBUGF(", scrolled"); @@ -536,6 +534,8 @@ static void print_line_info(struct wps_data *data) DEBUGF(", peakmeter"); DEBUGF("\n"); + subline = subline->next; + subline_number++; } } } diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index fbd18b9f73..bcc68a88f0 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -160,12 +160,16 @@ struct wps_subline { Tokens of this subline end where tokens for the next subline begin. */ unsigned short first_token_idx; + unsigned short last_token_idx; /* Bit or'ed WPS_REFRESH_xxx */ unsigned char line_type; /* How long the subline should be displayed, in 10ths of sec */ unsigned char time_mult; + + /* pointer to the next subline in this line */ + struct wps_subline *next; }; /* Description of a line on the WPS. A line is a set of sublines. @@ -173,19 +177,18 @@ struct wps_subline { the next subline of the line is displayed. And so on. */ struct wps_line { - /* Number of sublines in this line */ - signed char num_sublines; - - /* Number (0-based) of the subline within this line currently being displayed */ - signed char curr_subline; - - /* Index of the first subline of this line in the subline array. - Sublines for this line end where sublines for the next line begin. */ - unsigned short first_subline_idx; + /* Linked list of all the sublines on this line, + * a line *must* have at least one subline so no need to add an extra pointer */ + struct wps_subline sublines; + /* pointer to the current subline */ + struct wps_subline *curr_subline; /* When the next subline of this line should be displayed (absolute time value in ticks) */ long subline_expire_time; + + /* pointer to the next line */ + struct wps_line *next; }; #define VP_DRAW_HIDEABLE 0x1 @@ -196,9 +199,7 @@ struct wps_line { struct skin_viewport { struct viewport vp; /* The LCD viewport struct */ struct progressbar *pb; - /* Indexes of the first and last lines belonging to this viewport in the - lines[] array */ - int first_line, last_line; + struct wps_line *lines; char hidden_flags; char label; }; @@ -259,20 +260,8 @@ 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 */ struct skin_token_list *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; - struct wps_subline sublines[WPS_MAX_SUBLINES]; - /* Total number of tokens in the WPS. During WPS parsing, this is the index of the token being parsed. */ int num_tokens; @@ -286,12 +275,6 @@ struct wps_data unsigned int button_time_volume; }; -/* Returns the index of the last subline's token in the token array. - line - 0-based line number - subline - 0-based subline number within the line - */ -int skin_last_token_index(struct wps_data *data, int line, int subline); - /* wps_data end */ /* wps_state -- cgit v1.2.3