#include <math.h>
#include <sys/time.h>
+#include <sys/resource.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
titles += strlen(titles)+1;
i++;
}
- gtk_object_set_data(GTK_OBJECT(window), "user-data",
- GINT_TO_POINTER(&i));
+ gtk_object_set_data(GTK_OBJECT(window), "user-data", &i);
gtk_signal_connect(GTK_OBJECT(window), "destroy",
GTK_SIGNAL_FUNC(window_destroy), NULL);
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
* size allocation. A null widget is already taking up all the
* space it ever will.)
*/
- GtkAllocation a;
-
if (!w)
return FALSE; /* nonexistent widgets aren't a problem */
- gtk_widget_get_allocation(w, &a);
- return a.height == 0 || a.width == 0;
+#if GTK_CHECK_VERSION(2,18,0) /* skip if no gtk_widget_get_allocation */
+ {
+ GtkAllocation a;
+ gtk_widget_get_allocation(w, &a);
+ if (a.height == 0 || a.width == 0)
+ return TRUE; /* widget exists but has no size yet */
+ }
+#endif
+
+ return FALSE;
}
static void try_shrink_drawing_area(frontend *fe)
gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menuitem));
gtk_container_add(GTK_CONTAINER(submenu), menuitem);
gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
- GPOINTER_TO_INT(CFG_SETTINGS));
+ GINT_TO_POINTER(CFG_SETTINGS));
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(menu_config_event), fe);
gtk_widget_show(menuitem);
char *pname = argv[0];
char *error;
int ngenerate = 0, print = FALSE, px = 1, py = 1;
+ int time_generation = FALSE, test_solve = FALSE, list_presets = FALSE;
int soln = FALSE, colour = FALSE;
float scale = 1.0F;
float redo_proportion = 0.0F;
}
} else
ngenerate = 1;
+ } else if (doing_opts && !strcmp(p, "--time-generation")) {
+ time_generation = TRUE;
+ } else if (doing_opts && !strcmp(p, "--test-solve")) {
+ test_solve = TRUE;
+ } else if (doing_opts && !strcmp(p, "--list-presets")) {
+ list_presets = TRUE;
} else if (doing_opts && !strcmp(p, "--save")) {
if (--ac > 0) {
savefile = *++av;
}
}
- if (*errbuf) {
- fputs(errbuf, stderr);
- return 1;
- }
-
/*
* Special standalone mode for generating puzzle IDs on the
* command line. Useful for generating puzzles to be printed
char *id;
document *doc = NULL;
+ /*
+ * If we're in this branch, we should display any pending
+ * error message from the command line, since GTK isn't going
+ * to take another crack at making sense of it.
+ */
+ if (*errbuf) {
+ fputs(errbuf, stderr);
+ return 1;
+ }
+
n = ngenerate;
me = midend_new(NULL, &thegame, NULL, NULL);
* generated descriptive game IDs.)
*/
while (ngenerate == 0 || i < n) {
- char *pstr, *err;
+ char *pstr, *err, *seed;
+ struct rusage before, after;
if (ngenerate == 0) {
pstr = fgetline(stdin);
return 1;
}
}
- sfree(pstr);
- midend_new_game(me);
+ if (time_generation)
+ getrusage(RUSAGE_SELF, &before);
+
+ midend_new_game(me);
+
+ seed = midend_get_random_seed(me);
+
+ if (time_generation) {
+ double elapsed;
+
+ getrusage(RUSAGE_SELF, &after);
+
+ elapsed = (after.ru_utime.tv_sec -
+ before.ru_utime.tv_sec);
+ elapsed += (after.ru_utime.tv_usec -
+ before.ru_utime.tv_usec) / 1000000.0;
+
+ printf("%s %s: %.6f\n", thegame.name, seed, elapsed);
+ }
+
+ if (test_solve && thegame.can_solve) {
+ /*
+ * Now destroy the aux_info in the midend, by means of
+ * re-entering the same game id, and then try to solve
+ * it.
+ */
+ char *game_id, *err;
+
+ game_id = midend_get_game_id(me);
+ err = midend_game_id(me, game_id);
+ if (err) {
+ fprintf(stderr, "%s %s: game id re-entry error: %s\n",
+ thegame.name, seed, err);
+ return 1;
+ }
+ midend_new_game(me);
+ sfree(game_id);
+
+ err = midend_solve(me);
+ /*
+ * If the solve operation returned the error "Solution
+ * not known for this puzzle", that's OK, because that
+ * just means it's a puzzle for which we don't have an
+ * algorithmic solver and hence can't solve it without
+ * the aux_info, e.g. Netslide. Any other error is a
+ * problem, though.
+ */
+ if (err && strcmp(err, "Solution not known for this puzzle")) {
+ fprintf(stderr, "%s %s: solve error: %s\n",
+ thegame.name, seed, err);
+ return 1;
+ }
+ }
+
+ sfree(pstr);
+ sfree(seed);
if (doc) {
err = midend_print_puzzle(me, doc, soln);
}
sfree(realname);
}
- if (!doc && !savefile) {
+ if (!doc && !savefile && !time_generation) {
id = midend_get_game_id(me);
puts(id);
sfree(id);
midend_free(me);
return 0;
+ } else if (list_presets) {
+ /*
+ * Another specialist mode which causes the puzzle to list the
+ * game_params strings for all its preset configurations.
+ */
+ int i, npresets;
+ midend *me;
+
+ me = midend_new(NULL, &thegame, NULL, NULL);
+ npresets = midend_num_presets(me);
+
+ for (i = 0; i < npresets; i++) {
+ game_params *params;
+ char *name, *paramstr;
+
+ midend_fetch_preset(me, i, &name, ¶ms);
+ paramstr = thegame.encode_params(params, TRUE);
+
+ printf("%s %s\n", paramstr, name);
+ sfree(paramstr);
+ }
+
+ midend_free(me);
+ return 0;
} else {
frontend *fe;