[Freeciv-Dev] Re: switching tilesets at runtime
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
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>" },
|
|