[CF-Devel] Re: Repeated line supression for the gtk client.

crossfire-devel-admin at archives.real-time.com crossfire-devel-admin at archives.real-time.com
Fri Aug 1 07:11:58 CDT 2003


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
     
     
    


More information about the crossfire mailing list