diff --git a/src/sdl-instead/game.c b/src/sdl-instead/game.c index aba9220..8ff9409 100644 --- a/src/sdl-instead/game.c +++ b/src/sdl-instead/game.c @@ -148,6 +148,7 @@ static int motion_y = 0; static char *last_pict = NULL; static char *last_title = NULL; static char *last_music = NULL; +static char *last_cmd = NULL; static int mx, my; static img_t menubg = NULL; static img_t menu = NULL; @@ -602,7 +603,9 @@ void free_last(void) free(last_pict); if (last_title) free(last_title); - last_pict = last_title = NULL; + if (last_cmd) + free(last_cmd); + last_pict = last_title = last_cmd = NULL; game_stop_mus(500); sounds_free(); } @@ -1186,8 +1189,41 @@ char *horiz_inv(char *invstr) return invstr; } +static int find_diff_pos(const char *p1, const char *p2) +{ + int pos = 0; + if (!p1 || !p2) + return -1; + + while ((*p1 == *p2) && *p1) { + p1 ++; + p2 ++; + pos ++; + } + if (!*p1) + return -1; + return pos; +} + +static void scroll_to_diff(const char *cmdstr, int cur_off) +{ + int off = 0; + int pos = 0; + int h = 0; + pos = find_diff_pos(cmdstr, last_cmd); + if (pos == -1) + off = cur_off; + else + off = txt_layout_pos2off(txt_box_layout(el_box(el_scene)), pos); + el_size(el_scene, NULL, &h); + if (cur_off <= off && (cur_off + h) > off) + off = cur_off; + txt_box_scroll(el_box(el_scene), off); +} + int game_cmd(char *cmd) { + int old_off; int new_pict = 0, new_place = 0; int title_h = 0, ways_h = 0, pict_h = 0; char buf[1024]; @@ -1278,14 +1314,8 @@ int game_cmd(char *cmd) txt_layout_set(el_layout(el_ways), waystr); txt_layout_size(el_layout(el_ways), NULL, &ways_h); } - + old_off = txt_box_off(el_box(el_scene)); if (game_theme.gfx_mode == GFX_MODE_EMBEDDED) { - int off = 0; - if (!new_pict && !new_place) { - off = txt_box_off(el_box(el_scene)); - if (off > pict_h) - off = pict_h; - } pict_h = 0; /* to fake code bellow */ txt_layout_set(txt_box_layout(el_box(el_scene)), ""); /* hack, to null layout, but not images */ if (el_img(el_spic)) { @@ -1296,15 +1326,16 @@ int game_cmd(char *cmd) txt_layout_add(txt_box_layout(el_box(el_scene)), "\n"); /* small hack */ txt_layout_add(txt_box_layout(el_box(el_scene)), cmdstr); txt_box_set(el_box(el_scene), txt_box_layout(el_box(el_scene))); - if (!new_pict && !new_place) - txt_box_scroll(el_box(el_scene), off); } else { if (game_theme.gfx_mode == GFX_MODE_FLOAT) pict_h = 0; txt_layout_set(txt_box_layout(el_box(el_scene)), cmdstr); txt_box_set(el_box(el_scene), txt_box_layout(el_box(el_scene))); } - free(cmdstr); + if (!new_pict && !new_place) + scroll_to_diff(cmdstr, old_off); + FREE(last_cmd); + last_cmd = cmdstr; el(el_ways)->y = el(el_title)->y + title_h + pict_h; if (waystr) diff --git a/src/sdl-instead/graphics.c b/src/sdl-instead/graphics.c index 3871ce0..973f578 100644 --- a/src/sdl-instead/graphics.c +++ b/src/sdl-instead/graphics.c @@ -1090,6 +1090,7 @@ struct line { int w; int num; int align; + int pos; struct word *words; struct line *next; struct line *prev; @@ -1111,6 +1112,7 @@ struct line *line_new(void) l->num = 0; l->layout = NULL; l->align = 0; + l->pos = 0; return l; } @@ -2327,6 +2329,19 @@ int get_unbrakable_len(struct layout *layout, const char *ptr) return w; } +int txt_layout_pos2off(layout_t lay, int pos) +{ + int off = 0; + struct line *line; + struct layout *layout = (struct layout*)lay; + if (!layout) + return 0; + for (line = layout->lines; line && (line->pos <= pos); line = line->next) { + off = line->y; + } + return off; +} + void _txt_layout_add(layout_t lay, char *txt) { int sp = 0; @@ -2345,8 +2360,10 @@ void _txt_layout_add(layout_t lay, char *txt) TTF_SetFontStyle((TTF_Font *)(layout->fn), 0); TTF_SizeUTF8((TTF_Font *)(layout->fn), " ", &spw, &h); - for (line = layout->lines; line; line = line->next) + for (line = layout->lines; line; line = line->next) { lastline = line; + lastline->pos = 0; + } if (!lastline) { line = line_new(); @@ -2415,6 +2432,7 @@ void _txt_layout_add(layout_t lay, char *txt) } free(p); // ptr = eptr; + line->pos = (int)(ptr - txt); continue; } if (h > line->h) diff --git a/src/sdl-instead/graphics.h b/src/sdl-instead/graphics.h index 08962f8..55c266d 100644 --- a/src/sdl-instead/graphics.h +++ b/src/sdl-instead/graphics.h @@ -111,6 +111,7 @@ typedef void (*clear_fn)(int x, int y, int w, int h); extern void txt_box_update_links(textbox_t tbox, int x, int y, clear_fn); extern void txt_layout_update_links(layout_t layout, int x, int y, clear_fn clear); extern void txt_layout_real_size(layout_t lay, int *w, int *h); +extern int txt_layout_pos2off(layout_t lay, int pos); extern img_t txt_box_render(textbox_t tbox);