On Thu, Jul 31, 2003 at 11:50:28PM -0700, Mark Wedel wrote: > Depends on how you mean mix them. The server would combine that into 2 > messages - one '2 times ball lightning zaps' and '2 times ball ... > electrocutes'. There is some number of buffers which the server has for this, > so changes that result in a larger set of messages can start to mess that up. Ok, I've never noticed it, but I've not played much with output-sync due to the way it is implemented right now. > As said, I think the server already does most of what you want. It wouldn't > be hard for the server to send the first message when it shows up. And the > server already handles collapsing multiple messages. What I really want is to scroll back one page and see the password the NPC told me, not having to scroll back ten (or more pages) looking for it. output-sync really doesn't help me here unless I change it to a really high value and I wouldn't want that for other reasons. My patch fixes this (if only gtk was working...). I get no noticable delays between the messages being generated and me noticing them which I find important for noticing lag. I don't believe it is possible to fix purely on the server side. I've improved my patch so it parses "X times ..." messages, removes the "X times " part and adds the X to the message count number. With output-sync set to 4, I don't notice much perceived lag (if only the first message was sent immediatly) and still enjoy good message collapsing. I've also changed the default repeat value to 0 (so it should be safe to commit to CVS since it won't be used unless one activates it). > The other reason to handle collapsing on the server is to reduce bandwidth > some, but not likely much an issue. I'm using an ADSL link (500kpbs), playing from Telia in Sweden to Funet in Finland. I believe they have pretty good connections between them, but the game feels a bit lagged when I spend all my spellpoints on balls of lightning, so I think the bandwidth saving is worth it if my other issues with output-sync were fixed. The lower the bandwidth usage is, the lower the latency is too it seems. Regards, /Sebastian The new patch: ----------------------8<----------------------- Index: common/client.h =================================================================== RCS file: /cvsroot/crossfire/client/common/client.h,v retrieving revision 1.12 diff -u -r1.12 client.h --- common/client.h 8 Jul 2003 12:52:35 -0000 1.12 +++ common/client.h 1 Aug 2003 08:37:02 -0000 @@ -163,7 +163,8 @@ #define CONFIG_RESISTS 27 #define CONFIG_SMOOTH 28 #define CONFIG_SPLASH 29 -#define CONFIG_NUMS 30 +#define CONFIG_REPEAT 30 +#define CONFIG_NUMS 31 /* CONFIG_LIGHTING can have several possible values - set them accordingly */ #define CFG_LT_TILE 1 Index: common/init.c =================================================================== RCS file: /cvsroot/crossfire/client/common/init.c,v retrieving revision 1.12 diff -u -r1.12 init.c --- common/init.c 25 Jun 2003 17:13:58 -0000 1.12 +++ common/init.c 1 Aug 2003 08:37:02 -0000 @@ -42,7 +42,7 @@ "mapscale", "popups", "sdl", "showicon", "tooltips", "sound", "splitinfo", "split", "show_grid", "lighting", "trim_info_window", "map_width", "map_height", "foodbeep", "darkness", "port", -"grad_color_bars", "resists", "smoothing", "nosplash" +"grad_color_bars", "resists", "smoothing", "nosplash", "repeat" }; sint16 want_config[CONFIG_NUMS], use_config[CONFIG_NUMS]; @@ -192,6 +192,7 @@ want_config[CONFIG_RESISTS] = 0; want_config[CONFIG_SMOOTH] = 0; want_config[CONFIG_SPLASH] = TRUE; + want_config[CONFIG_REPEAT] = 0; for (i=0; i<CONFIG_NUMS; i++) use_config[i] = want_config[i]; Index: gtk/gx11.c =================================================================== RCS file: /cvsroot/crossfire/client/gtk/gx11.c,v retrieving revision 1.32 diff -u -r1.32 gx11.c --- gtk/gx11.c 25 Jun 2003 17:13:58 -0000 1.32 +++ gtk/gx11.c 1 Aug 2003 08:37:12 -0000 @@ -1895,19 +1895,111 @@ * good - otherewise, performance slowly degrades. */ +#define MAX_LINES (10) + +struct s_old_lines { + char str[MAXSOCKBUF]; + guint start; + int length; + int num; + int color; +}; + void draw_info(const char *str, int color) { int ncolor = color; - + static struct s_old_lines old_lines[MAX_LINES]; + GtkWidget *info_text = NULL; + int i; + int n_times = 1; + char small_buffer[10]; + if (ncolor==NDI_WHITE) { ncolor=NDI_BLACK; } + if (use_config[CONFIG_REPEAT] > MAX_LINES) { + use_config[CONFIG_REPEAT] = MAX_LINES; + } + strcpy (last_str, str); + + /* Freeze it */ + if (use_config[CONFIG_SPLITINFO] && color != NDI_BLACK) { - if (!draw_info_freeze2){ - gtk_text_freeze (GTK_TEXT (gtkwin_info_text2)); - draw_info_freeze2=TRUE; + info_text = gtkwin_info_text2; + if (!draw_info_freeze2) { + gtk_text_freeze (GTK_TEXT (gtkwin_info_text2)); + draw_info_freeze2=TRUE; + } + } else { + info_text = gtkwin_info_text; + if (!draw_info_freeze1) { + gtk_text_freeze (GTK_TEXT (gtkwin_info_text)); + draw_info_freeze1=TRUE; } + } + + /* XXX If the message contains a LF, it should be split and resent + * to draw_info */ + + /* Less then five characters is probably a prompt... */ + if (use_config[CONFIG_REPEAT]) { + if (strlen(str) > 5 && !strchr(str, '\n')) { + char c; + if(sscanf(str, "%u times %c", &i, &c) == 2) { + str = strstr(str, " times ") + 7; + n_times = i; + } + for(i = 0; i < use_config[CONFIG_REPEAT]; i++) { + if (!strcmp(str, old_lines[i].str)) { + int old_size; + int j; + + gtk_text_set_point(GTK_TEXT(info_text),old_lines[i].start); + + if (old_lines[i].num == 1) { + old_size = 0; + } else { + sprintf(small_buffer, "(%i) ", old_lines[i].num); + old_size = strlen(small_buffer); + } + gtk_text_forward_delete(GTK_TEXT(info_text), + old_size + 1 + old_lines[i].length); + + info2_num_chars = gtk_text_get_length(GTK_TEXT(info_text)); + gtk_text_set_point(GTK_TEXT(info_text), info2_num_chars); + old_lines[i].num += n_times; + sprintf(small_buffer, "(%i) ", old_lines[i].num); + gtk_text_insert (GTK_TEXT (info_text), NULL, + &root_color[old_lines[i].color], NULL, + small_buffer , -1); + /* XXX Not correct, should move them around, not just + * adjusting the starting positions. */ + for(j = 0; j < use_config[CONFIG_REPEAT]; j++) { + if (old_lines[j].start > old_lines[i].start) + old_lines[j].start -= + old_size + 1 + old_lines[i].length; + } + old_lines[i].start = info2_num_chars; + gtk_text_insert (GTK_TEXT (info_text), NULL, &root_color[ncolor], NULL, str , -1); + gtk_text_insert (GTK_TEXT (info_text), NULL, &root_color[ncolor], NULL, "\n" , -1); + + return; + } + } + + memmove(&old_lines[0], &old_lines[1], + sizeof(old_lines[1]) * (use_config[CONFIG_REPEAT]-1)); + strcpy(old_lines[use_config[CONFIG_REPEAT]-1].str, str); + old_lines[use_config[CONFIG_REPEAT]-1].length = strlen(str); + old_lines[use_config[CONFIG_REPEAT]-1].start = + gtk_text_get_length(GTK_TEXT(info_text)); + old_lines[use_config[CONFIG_REPEAT]-1].color = ncolor; + old_lines[use_config[CONFIG_REPEAT]-1].num = n_times; + } + } + + if (use_config[CONFIG_SPLITINFO] && color != NDI_BLACK) { if (use_config[CONFIG_TRIMINFO]) { info2_num_chars += strlen(str) + 1; /* Limit size of scrollback buffer. To be more efficient, delete a good @@ -1917,20 +2009,16 @@ if (info2_num_chars > info2_max_chars ) { gtk_text_set_point(GTK_TEXT(gtkwin_info_text2),0); gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text2), (info2_num_chars - info2_max_chars) + 5000); + for(i=0; i < use_config[CONFIG_REPEAT]; i++) { + old_lines[i].start -= (info2_num_chars - info2_max_chars) + 5000; + } info2_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text2)); gtk_text_set_point(GTK_TEXT(gtkwin_info_text2), info2_num_chars); fprintf(stderr,"reduced output buffer2 to %d chars\n", info1_num_chars); } } - gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, str , -1); - gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, "\n" , -1); - } else { /* all nootes in the above section apply here also */ - if (!draw_info_freeze1){ - gtk_text_freeze (GTK_TEXT (gtkwin_info_text)); - draw_info_freeze1=TRUE; - } if (use_config[CONFIG_TRIMINFO]) { info1_num_chars += strlen(str) + 1; if (info1_num_chars > info1_max_chars ) { @@ -1941,6 +2029,9 @@ to_delete++; gtk_text_set_point(GTK_TEXT(gtkwin_info_text),0); gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text), to_delete); + for(i=0; i < use_config[CONFIG_REPEAT]; i++) { + old_lines[i].start -= (info1_num_chars - info1_max_chars) + 5000; + } info1_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text)); gtk_text_set_point(GTK_TEXT(gtkwin_info_text), info1_num_chars); fprintf(stderr,"trim_info_window, deleted %d characters, %d remaining\n", to_delete, info1_num_chars); @@ -1955,10 +2046,16 @@ } } - - gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, str , -1); - gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, "\n" , -1); } + if(n_times > 1) { + sprintf(small_buffer, "(%i) ", n_times); + gtk_text_insert (GTK_TEXT (info_text), NULL, + &root_color[ncolor], NULL, + small_buffer , -1); + } + gtk_text_insert (GTK_TEXT (info_text), NULL, &root_color[ncolor], NULL, str , -1); + gtk_text_insert (GTK_TEXT (info_text), NULL, &root_color[ncolor], NULL, "\n" , -1); + } @@ -5109,6 +5206,7 @@ puts("-popups - Use pop up windows for input (default)"); puts("-nopopups - Don't use pop up windows for input"); puts("-port <number> - Use port <number> instead of the standard port number"); + puts("-repeat <num> - How far back the client looks for repeated text to join."); puts("-sdl - Use sdl for drawing png (may not work on all hardware"); puts("-server <name> - Connect to <name> instead of localhost."); puts("-showicon - Print status icons in inventory window"); @@ -5353,6 +5451,14 @@ } else if (!strcmp(argv[on_arg],"-nosplash")) { want_config[CONFIG_SPLASH] = FALSE; + continue; + } + else if (!strcmp(argv[on_arg],"-repeat")) { + if (++on_arg == argc) { + fprintf(stderr,"-repeat requires a value\n"); + return 1; + } + want_config[CONFIG_REPEAT]=atoi(argv[on_arg]); continue; } else { ----------------------8<----------------------- _______________________________________________ crossfire-devel mailing list crossfire-devel at lists.real-time.com https://mailman.real-time.com/mailman/listinfo/crossfire-devel