Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2002:
[Freeciv-Dev] Re: switching tilesets at runtime
Home

[Freeciv-Dev] Re: switching tilesets at runtime

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: switching tilesets at runtime
From: Jason Short <vze2zq63@xxxxxxxxxxx>
Date: Sun, 13 Jan 2002 05:27:41 -0500
Reply-to: jdorje@xxxxxxxxxxxx

Jason Short wrote:

Here's a preliminary (buggy and incomplete) patch to allow switching tilesets at runtime.


[...]

Um, here's the patch.

jason
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.59
diff -u -r1.59 tilespec.c
--- client/tilespec.c   2002/01/06 16:43:25     1.59
+++ client/tilespec.c   2002/01/13 09:19:55
@@ -207,6 +207,112 @@
 }
 
 /**********************************************************************
+  Frees the tilespec toplevel data, in preparation for re-reading it.
+
+  See tilespec_read_toplevel().
+***********************************************************************/
+static void tilespec_free_toplevel(void)
+{
+  if (city_names_font) {
+    free(city_names_font);
+    city_names_font = NULL;
+  }
+  if (city_productions_font_name) {
+    free(city_productions_font_name);
+    city_productions_font_name = NULL;
+  }
+  if (main_intro_filename) {
+    free(main_intro_filename);
+    main_intro_filename = NULL;
+  }
+  if (minimap_intro_filename) {
+    free(minimap_intro_filename);
+    minimap_intro_filename = NULL;
+  }
+  /* FIXME: free spec_filenames */
+}
+
+/**********************************************************************
+  Read a new tilespec in from scratch.
+
+  Unlike the initial reading code, which reads pieces one at a time,
+  this gets rid of the old data and reads in the new all at once.
+
+  It will also call the necessary functions to redraw the graphics.
+***********************************************************************/
+void tilespec_reread(const char *tileset_name)
+{
+  int id;
+
+  freelog(LOG_ERROR, "Loading tileset %s.", tileset_name);
+
+  /* Step 1:  Cleanup.
+   *
+   * We free any old data in preparation for re-reading it.
+   * This is pretty certainly incomplete, although the memory leak
+   * doesn't seem to be debilitating.
+   */
+  hash_free(sprite_hash);
+  tilespec_free_toplevel();
+
+  /* Step 2:  Read.
+   *
+   * We read in the new tileset.  This should be pretty straightforward.
+   */
+  tilespec_read_toplevel(tileset_name);
+  tilespec_load_tiles();
+
+  /* Step 3: Setup
+   *
+   * The rest of this is a seriously sticky problem.  On
+   * startup, we build a hash from all the sprite data.
+   * Then, when we connect to a server, the server sends us
+   * ruleset data a piece at a time and we use this data to
+   * assemble the sprite structures.  But if we change
+   * while connected we have to reassemble all of these.  This
+   * _should_ just involve calling tilespec_setup_*** on
+   * everything.  But how do we tell what "everything" is?
+   *
+   * The below code assumes that everything really _is_
+   * everything.  But this probably isn't true.  In fact,
+   * it's _certainly_ not true if we haven't received the
+   * info from the server yet.  OTOH, this may just
+   * initialize things to NULL in this case.
+   */
+
+  for (id = T_FIRST; id < T_COUNT; id++) {
+    tilespec_setup_tile_type(id);
+  }
+  for (id = 0; id < U_LAST; id++) {
+    tilespec_setup_unit_type(id);
+  }
+  for (id = 0; id < game.government_count; id++) {
+    tilespec_setup_government(id);
+  }
+  for (id = 0; id < game.nation_count; id++) {
+    tilespec_setup_nation_flag(id);
+  }
+
+  /* tilespec_load_tiles reverts the city tile pointers to 0.  This
+     is a temporary workaround. */
+  tilespec_alloc_city_tiles(game.styles_count);
+  for (id = 0; id < game.styles_count; id++) {
+    tilespec_setup_city_tiles(id);
+  }
+
+  /* Step 4:  Draw.
+   *
+   * Do any necessary redraws.
+   *
+   * I had thought that it would be necessary to manually redraw the
+   * canvas, but this seems to happen all by itself.  But we
+   * probably should recenter the mapcanvas, since it can be thrown
+   * way off by a change in tile size or orientation.
+   */
+  /* ... */
+}
+
+/**********************************************************************
   Finds and reads the toplevel tilespec file based on given name.
   Sets global variables, including tile sizes and full names for
   intro files.
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.23
diff -u -r1.23 tilespec.h
--- client/tilespec.h   2001/10/19 08:12:52     1.23
+++ client/tilespec.h   2002/01/13 09:19:55
@@ -29,6 +29,8 @@
 void tilespec_read_toplevel(const char *tileset_name);
 void tilespec_load_tiles(void);
 
+void tilespec_reread(const char *tileset_name);
+
 void tilespec_setup_unit_type(int id);
 void tilespec_setup_tile_type(int id);
 void tilespec_setup_government(int id);
Index: client/gui-gtk/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/menu.c,v
retrieving revision 1.59
diff -u -r1.59 menu.c
--- client/gui-gtk/menu.c       2001/10/26 08:07:13     1.59
+++ client/gui-gtk/menu.c       2002/01/13 09:19:56
@@ -51,6 +51,8 @@
 
 #include "menu.h"
 
+#include "tilespec.h"
+
 GtkItemFactory *item_factory=NULL;
 
 static void menus_rename(const char *path, char *s);
@@ -94,6 +96,7 @@
   MENU_VIEW_SHOW_FOCUS_UNIT,
   MENU_VIEW_SHOW_FOG_OF_WAR,
   MENU_VIEW_CENTER_VIEW,
+  MENU_VIEW_SWITCH_TILESET,
 
   MENU_ORDER_BUILD_CITY,     /* shared with BUILD_WONDER */
   MENU_ORDER_ROAD,           /* shared with TRADEROUTE */
@@ -289,6 +292,28 @@
   case MENU_VIEW_CENTER_VIEW:
     center_on_unit();
     break;
+  case MENU_VIEW_SWITCH_TILESET:
+    {
+      /* FIXME: this just toggles between the Trident, Engels, and Hires
+         tilesets.  It also switches first to trident no matter what
+         we started in. */
+      static char *cur = NULL;
+       
+      if (!cur) {
+       cur = "hires";
+      }
+
+      if (!strcmp(cur, "hires")) {
+       cur = "trident";
+      } else if (!strcmp(cur, "trident")) {
+       cur = "engels";
+      } else if (!strcmp(cur, "engels")) {
+       cur = "hires";
+      }
+
+      tilespec_reread(cur);    
+      break;
+    }
   }
 }
 
@@ -632,6 +657,10 @@
        NULL,                   0,                                      
"<Separator>"   },
   { "/" N_("View") "/" N_("_Center View"),             "c",
        view_menu_callback,     MENU_VIEW_CENTER_VIEW                           
        },
+  { "/" N_("View") "/sep3",                            NULL,
+       NULL,                   0,                                      
"<Separator>"   },
+  { "/" N_("View") "/" N_("Switch Tileset"),           NULL,
+       view_menu_callback,     MENU_VIEW_SWITCH_TILESET                        
                },
   /* Orders menu ... */
   { "/" N_("_Orders"),                                 NULL,
        NULL,                   0,                                      
"<Branch>"      },

[Prev in Thread] Current Thread [Next in Thread]