Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2000:
[Freeciv-Dev] alpha patch to provide wonder creation eye-candy
Home

[Freeciv-Dev] alpha patch to provide wonder creation eye-candy

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] alpha patch to provide wonder creation eye-candy
From: John Heidemann <johnh@xxxxxxx>
Date: Thu, 30 Nov 2000 18:07:39 -0800

Attached is an alpha-quality patch to provide wonder creation
eye-candy (the PR I submitted last weekend).  The patch is against the
current CVS archive.  To use this you need to apply it and rebuild
both the client and the server, and get some sample graphics from
<http://www.isi.edu/~johnh/PUBLIC/build.tar.gz> (extract them into the
new directory misc/build).  Then, when you build a wonder that has a
corresponding graphic a window will pop up with the special graphic.

This patch is preliminary in a few ways:

1. Probably the graphic filenames should be defined in the
buildings.ruleset, or at least the path where the graphics live should
be specified in a .spec somewhere.  Advice about what/where?
(Currently the filenames are just numbers
and the directory is hardcoded to misc/build.)

2. More graphics are needed.  I've found 11 that are clearly free.
I've got about 11 more that I need to get permission to use.

3. I didn't look at any backends other than gtk.

4. Other things?

Please let me know if its patch is OK.  I think it can be committed in
its current form (there are no serious bugs), but I expect I'll need
to add to it wrt the above points.

   -John Heidemann


Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.38
diff -u -u -r1.38 tilespec.c
--- tilespec.c  2000/10/27 22:20:00     1.38
+++ tilespec.c  2000/12/01 02:03:00
@@ -182,7 +182,7 @@
   Returns the correct name of the gfx file (with path and extension)
   Must be free'd when no longer used
 ***********************************************************************/
-static char *tilespec_gfx_filename(const char *gfx_filename)
+char *tilespec_gfx_filename(const char *gfx_filename)
 {
   char **gfx_fileexts;
   char *full_name,*real_full_name,*gfx_current_fileext;
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.16
diff -u -u -r1.16 tilespec.h
--- tilespec.h  2000/10/27 22:20:01     1.16
+++ tilespec.h  2000/12/01 02:03:01
@@ -28,6 +28,7 @@
 struct player;
 
 void tilespec_read_toplevel(const char *tileset_name);
+char *tilespec_gfx_filename(const char *gfx_filename);
 void tilespec_load_tiles(void);
 
 void tilespec_setup_unit_type(int id);
Index: client/gui-gtk/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/dialogs.c,v
retrieving revision 1.62
diff -u -u -r1.62 dialogs.c
--- dialogs.c   2000/08/31 13:32:40     1.62
+++ dialogs.c   2000/12/01 02:03:06
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <assert.h>
 
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -145,18 +146,94 @@
 /****************************************************************
 ...
 *****************************************************************/
-static void notify_command_callback(GtkWidget *w, GtkWidget *t)
+struct notify_dialog_data {
+  int validity;
+  GtkWidget *shell;
+  SPRITE *sprite;
+};
+
+static gint notify_command_deleted_callback( GtkWidget *widget, GdkEvent 
*event,  struct notify_dialog_data *data )
 {
-  gtk_widget_destroy( t );
+  assert(data->validity == 0xfeedbeef);  /* check for double calls */
+  data->validity = 0;
+
+  if (data->shell) {
+    gtk_widget_destroy( data->shell );
+    data->shell = NULL;
+  };
+  if (data->sprite) {
+    free_sprite(data->sprite);
+    data->sprite = NULL;
+  };
+  free(data);
+
   gtk_widget_set_sensitive( toplevel, TRUE );
+  return FALSE;
+}
+
+static void notify_command_callback(GtkWidget *w, struct notify_dialog_data 
*data)
+{
+  (void) notify_command_deleted_callback(w, NULL, data);
 }
 
+
 gint deleted_callback( GtkWidget *widget, GdkEvent *event, gpointer data )
 {
   gtk_widget_set_sensitive( toplevel, TRUE );
   return FALSE;
 }
 
+SPRITE *get_build_graphics(char *lines)
+{
+  char *cp = lines, *next;
+  int build_number, random_number;
+  SPRITE *sprite;
+  char filename[256], *found_filename;
+
+  /* Parse the text... I wish this was perl */
+
+  assert(lines[0] == '@');
+  cp++;
+
+  next = index(cp, ':');
+  assert(next != NULL);
+  if (strncmp(cp, "GRAPHIC", next-cp) != 0)
+    return NULL;
+  cp = next+1;
+
+  next = index(cp, ':');
+  assert(next != NULL);
+  if (strncmp(cp, "build", next-cp) != 0)
+    return NULL;
+  cp = next+1;
+
+  next = index(cp, ',');
+  build_number = atoi(cp);
+  cp = next+1;
+
+  /*
+   * The intent is that random number lets us select from several
+   * images for a given build, and to do so consistently across
+   * all of the same kind of client (which is why the sever sends
+   * it to us).  Ignored for now.
+   */
+  random_number = atoi(cp);
+
+  /*
+   * Now find the graphic.
+   * The "a" is to allow for multiple graphics someday.
+   */
+  snprintf(filename, sizeof(filename), "misc/build/%da", build_number);
+  found_filename = tilespec_gfx_filename(filename);
+  if (!found_filename)
+    return NULL;  /* no image for this wonder, that's ok */
+  sprite = load_gfxfile(found_filename);
+  assert(sprite);   /* If it's there we must load it! */
+  free(found_filename);
+  found_filename = NULL;
+
+  return sprite;
+}
 
 /****************************************************************
 ...
@@ -165,11 +242,16 @@
 {
   GtkWidget *notify_dialog_shell, *notify_command;
   GtkWidget *notify_label, *notify_headline, *notify_scrolled;
+  int desired_height = 265;
+  GtkWidget *notify_pixmap;
+  char *adjusted_lines;
   GtkAccelGroup *accel=gtk_accel_group_new();
+  struct notify_dialog_data *callback_data = fc_calloc(1, sizeof(struct 
notify_dialog_data));
+  callback_data->validity = 0xfeedbeef;
   
   notify_dialog_shell = gtk_dialog_new();
   gtk_signal_connect( GTK_OBJECT(notify_dialog_shell),"delete_event",
-       GTK_SIGNAL_FUNC(deleted_callback),NULL );
+       GTK_SIGNAL_FUNC(notify_command_deleted_callback), callback_data );
   gtk_accel_group_attach(accel, GTK_OBJECT(notify_dialog_shell));
   gtk_widget_set_name(notify_dialog_shell, "Freeciv");
 
@@ -186,21 +268,60 @@
 
   gtk_label_set_justify( GTK_LABEL( notify_headline ), GTK_JUSTIFY_LEFT );
   gtk_misc_set_alignment(GTK_MISC(notify_headline), 0.0, 0.0);
-
-  notify_scrolled=gtk_scrolled_window_new(NULL,NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(notify_scrolled),
-                                GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-  notify_label = gtk_label_new( lines );  
-  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW (notify_scrolled),
-                                       notify_label);
-
-  gtk_widget_set_name(notify_label, "notify label");
-  gtk_label_set_justify( GTK_LABEL( notify_label ), GTK_JUSTIFY_LEFT );
-  gtk_misc_set_alignment(GTK_MISC(notify_label), 0.0, 0.0);
-
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(notify_dialog_shell)->vbox ),
-       notify_scrolled, TRUE, TRUE, 0 );
 
+  /*
+   * Try to build a pixmap if one is asked for.
+   * If not, fall back on text.
+   */
+  notify_pixmap = NULL;
+  adjusted_lines = lines;
+  if (lines[0] == '@') {
+    SPRITE *build_sprite = get_build_graphics(lines);
+    if (build_sprite == NULL) {
+      /* failed, so fall back on text */
+      adjusted_lines = "Photo not available at press time.\n";
+    } else {
+      GtkRequisition req;
+      notify_pixmap = gtk_pixmap_new(build_sprite->pixmap, NULL);
+      /* should I call gtk_pixmap_set_build_insensitive? */
+
+      gtk_widget_set_name(notify_pixmap, "notify pixmap");
+      gtk_misc_set_alignment(GTK_MISC(notify_pixmap), 4.0, 4.0);
+      gtk_widget_set_usize(notify_pixmap, build_sprite->width, 
build_sprite->height);
+      desired_height = build_sprite->height + 80;
+      gtk_box_pack_start( GTK_BOX( GTK_DIALOG(notify_dialog_shell)->vbox ),
+                         notify_pixmap, TRUE, TRUE, 0 );
+      /*
+       * Succeeded, so don't do any text.
+       * xxx: In future, could allow additional text.
+       */
+      adjusted_lines = NULL;
+
+      /* arrange for the data to be freed */
+      callback_data->sprite = build_sprite;
+    };
+  };
+
+  /*
+   * Now make the text.
+   * This is either the real text, or if an image was called
+   * for but couldn't be loaded, it's fake text assigned above.
+   */
+  if (adjusted_lines) {
+    notify_scrolled = gtk_scrolled_window_new(NULL,NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(notify_scrolled),
+                                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+    notify_label = gtk_label_new( adjusted_lines );  
+    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW 
(notify_scrolled),
+                                         notify_label);
+
+    gtk_widget_set_name(notify_label, "notify label");
+    gtk_label_set_justify( GTK_LABEL( notify_label ), GTK_JUSTIFY_LEFT );
+    gtk_misc_set_alignment(GTK_MISC(notify_label), 0.0, 0.0);
+         
+    gtk_box_pack_start( GTK_BOX( GTK_DIALOG(notify_dialog_shell)->vbox ),
+                       notify_scrolled, TRUE, TRUE, 0 );
+  };
 
   notify_command = gtk_button_new_with_label( _("Close") );
   gtk_box_pack_start( GTK_BOX( GTK_DIALOG(notify_dialog_shell)->action_area ),
@@ -210,14 +331,15 @@
   gtk_widget_add_accelerator(notify_command, "clicked",
        accel, GDK_Escape, 0, 0);
 
+  callback_data->shell = notify_dialog_shell;
   gtk_signal_connect( GTK_OBJECT( notify_command ), "clicked",
-       GTK_SIGNAL_FUNC( notify_command_callback ), notify_dialog_shell );
+       GTK_SIGNAL_FUNC( notify_command_callback ), callback_data );
 
   
   gtk_widget_show_all( GTK_DIALOG(notify_dialog_shell)->vbox );
   gtk_widget_show_all( GTK_DIALOG(notify_dialog_shell)->action_area );
 
-  gtk_widget_set_usize(notify_dialog_shell, 0, 265);
+  gtk_widget_set_usize(notify_dialog_shell, 0, desired_height);
   gtk_set_relative_position (toplevel, notify_dialog_shell, 10, 10);
   gtk_widget_show( notify_dialog_shell );
 
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.74
diff -u -u -r1.74 capstr.c
--- capstr.c    2000/10/27 22:20:07     1.74
+++ capstr.c    2000/12/01 02:03:07
@@ -73,7 +73,8 @@
 #define CAPABILITY "+1.11 diplomat_investigate_fix production_change_fix" \
 " game_ruleset nuclear_fallout land_channel_requirement event_wonder_obsolete" 
\
 " event00_fix conn_info gen_impr_oversights diplo_move_city packet_short_city" 
\
-" indef_impr_types worklist_true_ids shared_vision activity_patrol"
+" indef_impr_types worklist_true_ids shared_vision activity_patrol" \
+" build_graphics"
 
 /* "+1.11" is protocol for 1.11.0 stable release.
 
@@ -129,6 +130,9 @@
 
    "activity_patrol" is the patrol activity and the ability to send a goto
    route from the client to the server (for both goto and patrol activities).
+
+   "build_graphics" is the ability for the client to pop up graphics
+   when things are built (like wonders)
 */
 
 void init_our_capability(void)
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.125
diff -u -u -r1.125 cityturn.c
--- cityturn.c  2000/09/18 02:43:05     1.125
+++ cityturn.c  2000/12/01 02:03:10
@@ -28,8 +28,10 @@
 #include "player.h"
 #include "rand.h"
 #include "shared.h"
+#include "support.h"
 #include "tech.h"
 #include "unit.h"
+#include "capability.h"
 
 #include "cityhand.h"
 #include "citytools.h"
@@ -41,6 +43,7 @@
 #include "srv_main.h"
 #include "unitfunc.h"
 #include "unittools.h"
+#include "report.h"
 
 #include "advdomestic.h"
 #include "aicity.h"
@@ -1234,6 +1237,9 @@
   struct government *g = get_gov_pplayer(pplayer);
   int space_part;
   int city_built_city_builder;
+  char headline[256];
+  char lines[256];
+  int random_number = myrand(10000);
 
   while (pcity->shield_surplus<0) {
     unit_list_iterate(pcity->units_supported, punit) {
@@ -1307,6 +1313,13 @@
                    _("Game: %s has finished building %s."), pcity->name, 
                    improvement_types[pcity->currently_building].name
                    );
+      my_snprintf(headline, sizeof(headline), _("%s has finished building 
%s."), pcity->name, 
+                 improvement_types[pcity->currently_building].name);
+      my_snprintf(lines, sizeof(lines), "@GRAPHIC:build:%d,%d\n", 
pcity->currently_building, random_number);
+      conn_list_iterate(pplayer->connections, pconn) {
+       if (has_capability("build_graphics", pconn->capability))
+               page_conn(&pconn->self, _("Wonder Completion Report:"), 
headline, lines);
+      } conn_list_iterate_end;
 
       if (pcity->currently_building==B_DARWIN) {
        notify_player(pplayer, 



[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] alpha patch to provide wonder creation eye-candy, John Heidemann <=