chiark / gitweb /
Use a proper union in struct config_item.
authorSimon Tatham <anakin@pobox.com>
Sun, 1 Oct 2017 12:38:35 +0000 (13:38 +0100)
committerSimon Tatham <anakin@pobox.com>
Sun, 1 Oct 2017 15:34:41 +0000 (16:34 +0100)
This allows me to use different types for the mutable, dynamically
allocated string value in a C_STRING control and the fixed constant
list of option names in a C_CHOICES.

51 files changed:
blackbox.c
bridges.c
cube.c
devel.but
dominosa.c
emcc.c
fifteen.c
filling.c
flip.c
flood.c
galaxies.c
gtk.c
guess.c
inertia.c
keen.c
lightup.c
loopy.c
magnets.c
map.c
midend.c
mines.c
misc.c
nestedvm.c
net.c
netslide.c
osx.m
palisade.c
pattern.c
pearl.c
pegs.c
puzzles.h
range.c
rect.c
samegame.c
signpost.c
singles.c
sixteen.c
slant.c
solo.c
tents.c
towers.c
tracks.c
twiddle.c
undead.c
unequal.c
unfinished/group.c
unfinished/slide.c
unfinished/sokoban.c
unruly.c
untangle.c
windows.c

index 422b7521a496ba2967559b80f9ce0f4f1b4597ef..7af131611ad3552dd26141ba608b590c3b5da5b3 100644 (file)
@@ -148,14 +148,12 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "No. of balls";
     ret[2].type = C_STRING;
@@ -163,13 +161,10 @@ static config_item *game_configure(const game_params *params)
         sprintf(buf, "%d", params->minballs);
     else
         sprintf(buf, "%d-%d", params->minballs, params->maxballs);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -178,12 +173,13 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     /* Allow 'a-b' for a range, otherwise assume a single number. */
-    if (sscanf(cfg[2].sval, "%d-%d", &ret->minballs, &ret->maxballs) < 2)
-        ret->minballs = ret->maxballs = atoi(cfg[2].sval);
+    if (sscanf(cfg[2].u.string.sval, "%d-%d",
+               &ret->minballs, &ret->maxballs) < 2)
+        ret->minballs = ret->maxballs = atoi(cfg[2].u.string.sval);
 
     return ret;
 }
index ebf73234cf2cb15d18e698c5862fd2dced5b6499..0684b36dfc2d2274a95d17e84b1f8369064eddd9 100644 (file)
--- a/bridges.c
+++ b/bridges.c
@@ -742,44 +742,40 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = ":Easy:Medium:Hard";
-    ret[2].ival = params->difficulty;
+    ret[2].u.choices.choicenames = ":Easy:Medium:Hard";
+    ret[2].u.choices.selected = params->difficulty;
 
     ret[3].name = "Allow loops";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->allowloops;
+    ret[3].u.boolean.bval = params->allowloops;
 
     ret[4].name = "Max. bridges per direction";
     ret[4].type = C_CHOICES;
-    ret[4].sval = ":1:2:3:4"; /* keep up-to-date with MAX_BRIDGES */
-    ret[4].ival = params->maxb - 1;
+    ret[4].u.choices.choicenames = ":1:2:3:4"; /* keep up-to-date with
+                                                * MAX_BRIDGES */
+    ret[4].u.choices.selected = params->maxb - 1;
 
     ret[5].name = "%age of island squares";
     ret[5].type = C_CHOICES;
-    ret[5].sval = ":5%:10%:15%:20%:25%:30%";
-    ret[5].ival = (params->islands / 5)-1;
+    ret[5].u.choices.choicenames = ":5%:10%:15%:20%:25%:30%";
+    ret[5].u.choices.selected = (params->islands / 5)-1;
 
     ret[6].name = "Expansion factor (%age)";
     ret[6].type = C_CHOICES;
-    ret[6].sval = ":0%:10%:20%:30%:40%:50%:60%:70%:80%:90%:100%";
-    ret[6].ival = params->expansion / 10;
+    ret[6].u.choices.choicenames = ":0%:10%:20%:30%:40%:50%:60%:70%:80%:90%:100%";
+    ret[6].u.choices.selected = params->expansion / 10;
 
     ret[7].name = NULL;
     ret[7].type = C_END;
-    ret[7].sval = NULL;
-    ret[7].ival = 0;
 
     return ret;
 }
@@ -788,13 +784,13 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w          = atoi(cfg[0].sval);
-    ret->h          = atoi(cfg[1].sval);
-    ret->difficulty = cfg[2].ival;
-    ret->allowloops = cfg[3].ival;
-    ret->maxb       = cfg[4].ival + 1;
-    ret->islands    = (cfg[5].ival + 1) * 5;
-    ret->expansion  = cfg[6].ival * 10;
+    ret->w          = atoi(cfg[0].u.string.sval);
+    ret->h          = atoi(cfg[1].u.string.sval);
+    ret->difficulty = cfg[2].u.choices.selected;
+    ret->allowloops = cfg[3].u.boolean.bval;
+    ret->maxb       = cfg[4].u.choices.selected + 1;
+    ret->islands    = (cfg[5].u.choices.selected + 1) * 5;
+    ret->expansion  = cfg[6].u.choices.selected * 10;
 
     return ret;
 }
diff --git a/cube.c b/cube.c
index a30dc10b3fd24bb05040fee6448eef329f05bdf9..249d1ba3623bb671c494db2298c0b44128f15c4d 100644 (file)
--- a/cube.c
+++ b/cube.c
@@ -489,25 +489,21 @@ static config_item *game_configure(const game_params *params)
 
     ret[0].name = "Type of solid";
     ret[0].type = C_CHOICES;
-    ret[0].sval = ":Tetrahedron:Cube:Octahedron:Icosahedron";
-    ret[0].ival = params->solid;
+    ret[0].u.choices.choicenames = ":Tetrahedron:Cube:Octahedron:Icosahedron";
+    ret[0].u.choices.selected = params->solid;
 
     ret[1].name = "Width / top";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->d1);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Height / bottom";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->d2);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -516,9 +512,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->solid = cfg[0].ival;
-    ret->d1 = atoi(cfg[1].sval);
-    ret->d2 = atoi(cfg[2].sval);
+    ret->solid = cfg[0].u.choices.selected;
+    ret->d1 = atoi(cfg[1].u.string.sval);
+    ret->d2 = atoi(cfg[2].u.string.sval);
 
     return ret;
 }
index 16aaf02d35dc3fd99128dbeb3678fb7489c0d9bb..98724b39c62690daf6c18a9fbee3ffc9ec258aef 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -555,16 +555,15 @@ The \cw{config_item} structure contains the following elements:
 
 \c char *name;
 \c int type;
-\c char *sval;
-\c int ival;
+\c union { /* type-specific fields */ } u;
+\e         iiiiiiiiiiiiiiiiiiiiiiiiii
 
 \c{name} is an ASCII string giving the textual label for a GUI
 control. It is \e{not} expected to be dynamically allocated.
 
 \c{type} contains one of a small number of \c{enum} values defining
-what type of control is being described. The meaning of the \c{sval}
-and \c{ival} fields depends on the value in \c{type}. The valid
-values are:
+what type of control is being described. The usable member of the
+union field \c{u} depends on \c{type}. The valid type values are:
 
 \dt \c{C_STRING}
 
@@ -572,38 +571,64 @@ values are:
 input. The back end does not bother informing the front end that the
 box is numeric rather than textual; some front ends do have the
 capacity to take this into account, but I decided it wasn't worth
-the extra complexity in the interface.) For this type, \c{ival} is
-unused, and \c{sval} contains a dynamically allocated string
-representing the contents of the input box.
+the extra complexity in the interface.)
+
+\lcont{
+
+For controls of this type, \c{u.string} contains a single field
+
+\c char *sval;
+
+which stores a dynamically allocated string representing the contents
+of the input box.
+
+}
 
 \dt \c{C_BOOLEAN}
 
-\dd Describes a simple checkbox. For this type, \c{sval} is unused,
-and \c{ival} is \cw{TRUE} or \cw{FALSE}.
+\dd Describes a simple checkbox.
+
+\lcont{
+
+For controls of this type, \c{u.boolean} contains a single field
+
+\c int bval;
+
+which is either \cw{TRUE} or \cw{FALSE}.
+
+}
 
 \dt \c{C_CHOICES}
 
 \dd Describes a drop-down list presenting one of a small number of
-fixed choices. For this type, \c{sval} contains a list of strings
-describing the choices; the very first character of \c{sval} is used
-as a delimiter when processing the rest (so that the strings
-\cq{:zero:one:two}, \cq{!zero!one!two} and \cq{xzeroxonextwo} all
-define a three-element list containing \cq{zero}, \cq{one} and
-\cq{two}). \c{ival} contains the index of the currently selected
-element, numbering from zero (so that in the above example, 0 would
-mean \cq{zero} and 2 would mean \cq{two}).
+fixed choices.
 
 \lcont{
 
-Note that for this control type, \c{sval} is \e{not} dynamically
-allocated, whereas it was for \c{C_STRING}.
+For controls of this type, \c{u.choices} contains two fields:
+
+\c const char *choicenames;
+\c int selected;
+
+\c{choicenames} contains a list of strings describing the choices. The
+very first character of \c{sval} is used as a delimiter when
+processing the rest (so that the strings \cq{:zero:one:two},
+\cq{!zero!one!two} and \cq{xzeroxonextwo} all define a three-element
+list containing \cq{zero}, \cq{one} and \cq{two}).
+
+\c{selected} contains the index of the currently selected element,
+numbering from zero (so that in the above example, 0 would mean
+\cq{zero} and 2 would mean \cq{two}).
+
+Note that \c{u.choices.choicenames} is \e{not} dynamically allocated,
+unlike \c{u.string.sval}.
 
 }
 
 \dt \c{C_END}
 
-\dd Marks the end of the array of \c{config_item}s. All other fields
-are unused.
+\dd Marks the end of the array of \c{config_item}s. There is no
+associated member of the union field \c{u} for this type.
 
 The array returned from this function is expected to have filled in
 the initial values of all the controls according to the input
@@ -3737,10 +3762,10 @@ quite everywhere.)
 
 \c void free_cfg(config_item *cfg);
 
-This function correctly frees an array of \c{config_item}s,
-including walking the array until it gets to the end and freeing
-precisely those \c{sval} fields which are expected to be dynamically
-allocated.
+This function correctly frees an array of \c{config_item}s, including
+walking the array until it gets to the end and freeing any subsidiary
+data items in each \c{u} sub-union which are expected to be
+dynamically allocated.
 
 (See \k{backend-configure} for details of the \c{config_item}
 structure.)
index 5a3016b4bed2f5e459002920ba0b2dbe145b65e4..d26f97ae5b59ee429870f85e47662dd10de063c8 100644 (file)
@@ -169,18 +169,14 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Maximum number on dominoes";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->n);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Ensure unique solution";
     ret[1].type = C_BOOLEAN;
-    ret[1].sval = NULL;
-    ret[1].ival = params->unique;
+    ret[1].u.boolean.bval = params->unique;
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -189,8 +185,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->n = atoi(cfg[0].sval);
-    ret->unique = cfg[1].ival;
+    ret->n = atoi(cfg[0].u.string.sval);
+    ret->unique = cfg[1].u.boolean.bval;
 
     return ret;
 }
diff --git a/emcc.c b/emcc.c
index 23ab333f5db0cb58b7579b10b9f974d4e45f9c95..c499eef289468bc85f88ab31870781decfde46b6 100644 (file)
--- a/emcc.c
+++ b/emcc.c
@@ -599,13 +599,14 @@ static void cfg_start(int which)
     for (i = 0; cfg[i].type != C_END; i++) {
        switch (cfg[i].type) {
          case C_STRING:
-            js_dialog_string(i, cfg[i].name, cfg[i].sval);
+            js_dialog_string(i, cfg[i].name, cfg[i].u.string.sval);
            break;
          case C_BOOLEAN:
-            js_dialog_boolean(i, cfg[i].name, cfg[i].ival);
+            js_dialog_boolean(i, cfg[i].name, cfg[i].u.boolean.bval);
            break;
          case C_CHOICES:
-            js_dialog_choices(i, cfg[i].name, cfg[i].sval, cfg[i].ival);
+            js_dialog_choices(i, cfg[i].name, cfg[i].u.choices.choicenames,
+                              cfg[i].u.choices.selected);
            break;
        }
     }
@@ -619,12 +620,29 @@ static void cfg_start(int which)
  */
 void dlg_return_sval(int index, const char *val)
 {
-    sfree(cfg[index].sval);
-    cfg[index].sval = dupstr(val);
+    config_item *i = cfg + index;
+    switch (i->type) {
+      case C_STRING:
+        sfree(i->u.string.sval);
+        i->u.string.sval = dupstr(val);
+        break;
+      default:
+        assert(0 && "Bad type for return_sval");
+    }
 }
 void dlg_return_ival(int index, int val)
 {
-    cfg[index].ival = val;
+    config_item *i = cfg + index;
+    switch (i->type) {
+      case C_BOOLEAN:
+        i->u.boolean.bval = val;
+        break;
+      case C_CHOICES:
+        i->u.choices.selected = val;
+        break;
+      default:
+        assert(0 && "Bad type for return_ival");
+    }
 }
 
 /*
index aee89071cac4b871ce8754e84268533f02a6530f..9a985e34f621c92ec32523c44c1f321d6c7d5dbe 100644 (file)
--- a/fifteen.c
+++ b/fifteen.c
@@ -111,19 +111,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -132,8 +128,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     return ret;
 }
index d0883afc46b469fac5b5b73a3af486b1a5a333fe..585b4bd43ebebc87649158744feabc0938065e38 100644 (file)
--- a/filling.c
+++ b/filling.c
@@ -161,19 +161,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -182,8 +178,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     return ret;
 }
diff --git a/flip.c b/flip.c
index 68979fee9dacdac6e5c58cccc6e274003965c618..fc96329d4ce3bb1b173605387d8f6c7d83e28c84 100644 (file)
--- a/flip.c
+++ b/flip.c
@@ -149,24 +149,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Shape type";
     ret[2].type = C_CHOICES;
-    ret[2].sval = ":Crosses:Random";
-    ret[2].ival = params->matrix_type;
+    ret[2].u.choices.choicenames = ":Crosses:Random";
+    ret[2].u.choices.selected = params->matrix_type;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -175,9 +171,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->matrix_type = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->matrix_type = cfg[2].u.choices.selected;
 
     return ret;
 }
diff --git a/flood.c b/flood.c
index 247c5096a2b03c596c4a173cd16ecf9c0c5bca6a..90247fc2d0eca9adb4f6ea0a114642167fd0579b 100644 (file)
--- a/flood.c
+++ b/flood.c
@@ -170,31 +170,25 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Colours";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->colours);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Extra moves permitted";
     ret[3].type = C_STRING;
     sprintf(buf, "%d", params->leniency);
-    ret[3].sval = dupstr(buf);
-    ret[3].ival = 0;
+    ret[3].u.string.sval = dupstr(buf);
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -203,10 +197,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->colours = atoi(cfg[2].sval);
-    ret->leniency = atoi(cfg[3].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->colours = atoi(cfg[2].u.string.sval);
+    ret->leniency = atoi(cfg[3].u.string.sval);
 
     return ret;
 }
index 03bed9cbbf9755e28ff9b0d9e8490cc89377fc35..629fb897f79eea1feeafd4d8d2211697a73e9c3b 100644 (file)
@@ -248,24 +248,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -274,9 +270,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
 
     return ret;
 }
diff --git a/gtk.c b/gtk.c
index b1175efd03c6d8a2b1ebc932f17d2a2f0e64d470..c1e5a66edf4c093866f00e8e74151e9ad2a199f9 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -1641,22 +1641,25 @@ static void editbox_changed(GtkEditable *ed, gpointer data)
 {
     config_item *i = (config_item *)data;
 
-    sfree(i->sval);
-    i->sval = dupstr(gtk_entry_get_text(GTK_ENTRY(ed)));
+    assert(i->type == C_STRING);
+    sfree(i->u.string.sval);
+    i->u.string.sval = dupstr(gtk_entry_get_text(GTK_ENTRY(ed)));
 }
 
 static void button_toggled(GtkToggleButton *tb, gpointer data)
 {
     config_item *i = (config_item *)data;
 
-    i->ival = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb));
+    assert(i->type == C_BOOLEAN);
+    i->u.boolean.bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb));
 }
 
 static void droplist_sel(GtkComboBox *combo, gpointer data)
 {
     config_item *i = (config_item *)data;
 
-    i->ival = gtk_combo_box_get_active(combo);
+    assert(i->type == C_CHOICES);
+    i->u.choices.selected = gtk_combo_box_get_active(combo);
 }
 
 static int get_config(frontend *fe, int which)
@@ -1751,7 +1754,7 @@ static int get_config(frontend *fe, int which)
                             GTK_EXPAND | GTK_SHRINK | GTK_FILL,
                             3, 3);
 #endif
-           gtk_entry_set_text(GTK_ENTRY(w), i->sval);
+           gtk_entry_set_text(GTK_ENTRY(w), i->u.string.sval);
            g_signal_connect(G_OBJECT(w), "changed",
                              G_CALLBACK(editbox_changed), i);
            g_signal_connect(G_OBJECT(w), "key_press_event",
@@ -1776,7 +1779,8 @@ static int get_config(frontend *fe, int which)
                             GTK_EXPAND | GTK_SHRINK | GTK_FILL,
                             3, 3);
 #endif
-           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), i->ival);
+           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
+                                         i->u.boolean.bval);
            gtk_widget_show(w);
            break;
 
@@ -1799,15 +1803,16 @@ static int get_config(frontend *fe, int which)
 
             {
                int c;
-               char *p, *q, *name;
+               const char *p, *q;
+                char *name;
                 GtkListStore *model;
                GtkCellRenderer *cr;
                 GtkTreeIter iter;
 
                 model = gtk_list_store_new(1, G_TYPE_STRING);
 
-               c = *i->sval;
-               p = i->sval+1;
+               c = *i->u.choices.choicenames;
+               p = i->u.choices.choicenames+1;
 
                while (*p) {
                    q = p;
@@ -1828,7 +1833,8 @@ static int get_config(frontend *fe, int which)
 
                 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
 
-               gtk_combo_box_set_active(GTK_COMBO_BOX(w), i->ival);
+               gtk_combo_box_set_active(GTK_COMBO_BOX(w),
+                                         i->u.choices.selected);
 
                cr = gtk_cell_renderer_text_new();
                gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), cr, TRUE);
diff --git a/guess.c b/guess.c
index b3d4a9a8e9ce2d5cfc1d8cccd695a8f11817ddaa..af26edc4664d78e6f156c8e97cfc81b09af65e8a 100644 (file)
--- a/guess.c
+++ b/guess.c
@@ -166,35 +166,28 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Colours";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->ncolours);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Pegs per guess";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->npegs);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Guesses";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->nguesses);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Allow blanks";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->allow_blank;
+    ret[3].u.boolean.bval = params->allow_blank;
 
     ret[4].name = "Allow duplicates";
     ret[4].type = C_BOOLEAN;
-    ret[4].sval = NULL;
-    ret[4].ival = params->allow_multiple;
+    ret[4].u.boolean.bval = params->allow_multiple;
 
     ret[5].name = NULL;
     ret[5].type = C_END;
-    ret[5].sval = NULL;
-    ret[5].ival = 0;
 
     return ret;
 }
@@ -203,12 +196,12 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->ncolours = atoi(cfg[0].sval);
-    ret->npegs = atoi(cfg[1].sval);
-    ret->nguesses = atoi(cfg[2].sval);
+    ret->ncolours = atoi(cfg[0].u.string.sval);
+    ret->npegs = atoi(cfg[1].u.string.sval);
+    ret->nguesses = atoi(cfg[2].u.string.sval);
 
-    ret->allow_blank = cfg[3].ival;
-    ret->allow_multiple = cfg[4].ival;
+    ret->allow_blank = cfg[3].u.boolean.bval;
+    ret->allow_multiple = cfg[4].u.boolean.bval;
 
     return ret;
 }
index c22d2e17d4be879e3dc9a9c09ea0f806b0603354..f5bf1a1b6feaa38801258ade46848bb543220faf 100644 (file)
--- a/inertia.c
+++ b/inertia.c
@@ -168,19 +168,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -189,8 +185,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     return ret;
 }
diff --git a/keen.c b/keen.c
index a3fbb74217c887cc3bdab79f900846393bb20c6f..8a056593235407043544b1afd45c3b7921f2661f 100644 (file)
--- a/keen.c
+++ b/keen.c
@@ -183,23 +183,19 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Grid size";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Difficulty";
     ret[1].type = C_CHOICES;
-    ret[1].sval = DIFFCONFIG;
-    ret[1].ival = params->diff;
+    ret[1].u.choices.choicenames = DIFFCONFIG;
+    ret[1].u.choices.selected = params->diff;
 
     ret[2].name = "Multiplication only";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->multiplication_only;
+    ret[2].u.boolean.bval = params->multiplication_only;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -208,9 +204,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->diff = cfg[1].ival;
-    ret->multiplication_only = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->diff = cfg[1].u.choices.selected;
+    ret->multiplication_only = cfg[2].u.boolean.bval;
 
     return ret;
 }
index a56f3a995189deaa18f758abe817278f39092282..c5ee418b1ccd222069151d17ac79e830dc3e146b 100644 (file)
--- a/lightup.c
+++ b/lightup.c
@@ -299,37 +299,32 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "%age of black squares";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->blackpc);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Symmetry";
     ret[3].type = C_CHOICES;
-    ret[3].sval = ":None"
+    ret[3].u.choices.choicenames = ":None"
                   ":2-way mirror:2-way rotational"
                   ":4-way mirror:4-way rotational";
-    ret[3].ival = params->symm;
+    ret[3].u.choices.selected = params->symm;
 
     ret[4].name = "Difficulty";
     ret[4].type = C_CHOICES;
-    ret[4].sval = ":Easy:Tricky:Hard";
-    ret[4].ival = params->difficulty;
+    ret[4].u.choices.choicenames = ":Easy:Tricky:Hard";
+    ret[4].u.choices.selected = params->difficulty;
 
     ret[5].name = NULL;
     ret[5].type = C_END;
-    ret[5].sval = NULL;
-    ret[5].ival = 0;
 
     return ret;
 }
@@ -338,11 +333,11 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w =       atoi(cfg[0].sval);
-    ret->h =       atoi(cfg[1].sval);
-    ret->blackpc = atoi(cfg[2].sval);
-    ret->symm =    cfg[3].ival;
-    ret->difficulty = cfg[4].ival;
+    ret->w =       atoi(cfg[0].u.string.sval);
+    ret->h =       atoi(cfg[1].u.string.sval);
+    ret->blackpc = atoi(cfg[2].u.string.sval);
+    ret->symm =    cfg[3].u.choices.selected;
+    ret->difficulty = cfg[4].u.choices.selected;
 
     return ret;
 }
diff --git a/loopy.c b/loopy.c
index 92b27ab51690f10aa89983b8af934fa591dc1449..8af9a30dece76278d841f75f9b50ecfed3690c57 100644 (file)
--- a/loopy.c
+++ b/loopy.c
@@ -640,29 +640,25 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Grid type";
     ret[2].type = C_CHOICES;
-    ret[2].sval = GRID_CONFIGS;
-    ret[2].ival = params->type;
+    ret[2].u.choices.choicenames = GRID_CONFIGS;
+    ret[2].u.choices.selected = params->type;
 
     ret[3].name = "Difficulty";
     ret[3].type = C_CHOICES;
-    ret[3].sval = DIFFCONFIG;
-    ret[3].ival = params->diff;
+    ret[3].u.choices.choicenames = DIFFCONFIG;
+    ret[3].u.choices.selected = params->diff;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -671,10 +667,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->type = cfg[2].ival;
-    ret->diff = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->type = cfg[2].u.choices.selected;
+    ret->diff = cfg[3].u.choices.selected;
 
     return ret;
 }
index 354c00a524aa0745d303df2cd42c07b02d3cdb8e..5a6b6617975ca6c42aef21557b2338a81f5446bd 100644 (file)
--- a/magnets.c
+++ b/magnets.c
@@ -193,29 +193,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = "Strip clues";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->stripclues;
+    ret[3].u.boolean.bval = params->stripclues;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -224,10 +219,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
-    ret->stripclues = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
+    ret->stripclues = cfg[3].u.boolean.bval;
 
     return ret;
 }
diff --git a/map.c b/map.c
index c66e7e2ea409f1e17815c30caaae4e425bbb00fd..917c525d7eae55fe1bb647a633530c1e35b9613a 100644 (file)
--- a/map.c
+++ b/map.c
@@ -213,30 +213,25 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Regions";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->n);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Difficulty";
     ret[3].type = C_CHOICES;
-    ret[3].sval = DIFFCONFIG;
-    ret[3].ival = params->diff;
+    ret[3].u.choices.choicenames = DIFFCONFIG;
+    ret[3].u.choices.selected = params->diff;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -245,10 +240,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->n = atoi(cfg[2].sval);
-    ret->diff = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->n = atoi(cfg[2].u.string.sval);
+    ret->diff = cfg[3].u.choices.selected;
 
     return ret;
 }
index 913b322414e50f47688f9fe6aef47bb2b3a29523..1f5f0773606d4a73a16e02e863f2fb8955a432c4 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -1360,7 +1360,6 @@ config_item *midend_get_config(midend *me, int which, char **wintitle)
             ret[0].name = "Game random seed";
         else
             ret[0].name = "Game ID";
-       ret[0].ival = 0;
         /*
          * For CFG_DESC the text going in here will be a string
          * encoding of the restricted parameters, plus a colon,
@@ -1379,13 +1378,12 @@ config_item *midend_get_config(midend *me, int which, char **wintitle)
             rest = me->seedstr ? me->seedstr : "";
             sep = '#';
         }
-        ret[0].sval = snewn(strlen(parstr) + strlen(rest) + 2, char);
-        sprintf(ret[0].sval, "%s%c%s", parstr, sep, rest);
+        ret[0].u.string.sval = snewn(strlen(parstr) + strlen(rest) + 2, char);
+        sprintf(ret[0].u.string.sval, "%s%c%s", parstr, sep, rest);
         sfree(parstr);
 
        ret[1].type = C_END;
-       ret[1].name = ret[1].sval = NULL;
-       ret[1].ival = 0;
+       ret[1].name = NULL;
 
        return ret;
     }
@@ -1620,7 +1618,7 @@ char *midend_set_config(midend *me, int which, config_item *cfg)
 
       case CFG_SEED:
       case CFG_DESC:
-        error = midend_game_id_int(me, cfg[0].sval,
+        error = midend_game_id_int(me, cfg[0].u.string.sval,
                                    (which == CFG_SEED ? DEF_SEED : DEF_DESC));
        if (error)
            return error;
diff --git a/mines.c b/mines.c
index 5bae0e841e18dd150f339d2adc6e7e9f57df2355..4612da9f5a32367aa4c9503de24e3ab3d80a2e4e 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -203,30 +203,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Mines";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->n);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Ensure solubility";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->unique;
+    ret[3].u.boolean.bval = params->unique;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -235,12 +229,12 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->n = atoi(cfg[2].sval);
-    if (strchr(cfg[2].sval, '%'))
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->n = atoi(cfg[2].u.string.sval);
+    if (strchr(cfg[2].u.string.sval, '%'))
        ret->n = ret->n * (ret->w * ret->h) / 100;
-    ret->unique = cfg[3].ival;
+    ret->unique = cfg[3].u.boolean.bval;
 
     return ret;
 }
diff --git a/misc.c b/misc.c
index b44f1b14f854aa8e8a24cf190f95cc6fd39a3102..d555ad261a9be39c2e93477a5e854edb421e051c 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -17,7 +17,7 @@ void free_cfg(config_item *cfg)
 
     for (i = cfg; i->type != C_END; i++)
        if (i->type == C_STRING)
-           sfree(i->sval);
+           sfree(i->u.string.sval);
     sfree(cfg);
 }
 
index f7a2ae8ec58217e50c4769489936697e7bb4683d..704f6d10b0ee66350225bacc18cfc8b74515560c 100644 (file)
@@ -273,19 +273,22 @@ void jcallback_config_ok()
 void jcallback_config_set_string(int item_ptr, int char_ptr) {
     config_item *i = (config_item *)item_ptr;
     char* newval = (char*) char_ptr;
-    sfree(i->sval);
-    i->sval = dupstr(newval);
+    assert(i->type == C_STRING);
+    sfree(i->u.string.sval);
+    i->u.string.sval = dupstr(newval);
     free(newval);
 }
 
 void jcallback_config_set_boolean(int item_ptr, int selected) {
     config_item *i = (config_item *)item_ptr;
-    i->ival = selected != 0 ? TRUE : FALSE;
+    assert(i->type == C_BOOLEAN);
+    i->u.boolean.bval = selected != 0 ? TRUE : FALSE;
 }
 
 void jcallback_config_set_choice(int item_ptr, int selected) {
     config_item *i = (config_item *)item_ptr;
-    i->ival = selected;
+    assert(i->type == C_CHOICES);
+    i->u.choices.selected = selected;
 }
 
 static int get_config(frontend *fe, int which)
@@ -298,7 +301,18 @@ static int get_config(frontend *fe, int which)
     _call_java(10, (int)title, 0, 0);
     for (i = fe->cfg; i->type != C_END; i++) {
        _call_java(5, (int)i, i->type, (int)i->name);
-       _call_java(11, (int)i->sval, i->ival, 0);
+        switch (i->type) {
+          case C_STRING:
+            _call_java(11, (int)i->u.string.sval, 0, 0);
+            break;
+          case C_BOOLEAN:
+            _call_java(11, 0, i->u.boolean.bval, 0);
+            break;
+          case C_CHOICES:
+            _call_java(11, (int)i->u.choices.choicenames,
+                       i->u.choices.selected, 0);
+            break;
+        }
     }
     _call_java(12,0,0,0);
     free_cfg(fe->cfg);
diff --git a/net.c b/net.c
index fc603d1e031683faea275ce7c95ad63726d94128..2b8706d25146784638c2e06467ed3db7a7dbb4ca 100644 (file)
--- a/net.c
+++ b/net.c
@@ -267,35 +267,28 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->width);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->height);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Walls wrap around";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->wrapping;
+    ret[2].u.boolean.bval = params->wrapping;
 
     ret[3].name = "Barrier probability";
     ret[3].type = C_STRING;
     sprintf(buf, "%g", params->barrier_probability);
-    ret[3].sval = dupstr(buf);
-    ret[3].ival = 0;
+    ret[3].u.string.sval = dupstr(buf);
 
     ret[4].name = "Ensure unique solution";
     ret[4].type = C_BOOLEAN;
-    ret[4].sval = NULL;
-    ret[4].ival = params->unique;
+    ret[4].u.boolean.bval = params->unique;
 
     ret[5].name = NULL;
     ret[5].type = C_END;
-    ret[5].sval = NULL;
-    ret[5].ival = 0;
 
     return ret;
 }
@@ -304,11 +297,11 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->width = atoi(cfg[0].sval);
-    ret->height = atoi(cfg[1].sval);
-    ret->wrapping = cfg[2].ival;
-    ret->barrier_probability = (float)atof(cfg[3].sval);
-    ret->unique = cfg[4].ival;
+    ret->width = atoi(cfg[0].u.string.sval);
+    ret->height = atoi(cfg[1].u.string.sval);
+    ret->wrapping = cfg[2].u.boolean.bval;
+    ret->barrier_probability = (float)atof(cfg[3].u.string.sval);
+    ret->unique = cfg[4].u.boolean.bval;
 
     return ret;
 }
index d43dc2e0cb7b94e749bd21788c661888c4b2e6ac..542b571c8534077268808a3863db97a95561e4db 100644 (file)
@@ -262,36 +262,29 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->width);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->height);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Walls wrap around";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->wrapping;
+    ret[2].u.boolean.bval = params->wrapping;
 
     ret[3].name = "Barrier probability";
     ret[3].type = C_STRING;
     sprintf(buf, "%g", params->barrier_probability);
-    ret[3].sval = dupstr(buf);
-    ret[3].ival = 0;
+    ret[3].u.string.sval = dupstr(buf);
 
     ret[4].name = "Number of shuffling moves";
     ret[4].type = C_STRING;
     sprintf(buf, "%d", params->movetarget);
-    ret[4].sval = dupstr(buf);
-    ret[4].ival = 0;
+    ret[4].u.string.sval = dupstr(buf);
 
     ret[5].name = NULL;
     ret[5].type = C_END;
-    ret[5].sval = NULL;
-    ret[5].ival = 0;
 
     return ret;
 }
@@ -300,11 +293,11 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->width = atoi(cfg[0].sval);
-    ret->height = atoi(cfg[1].sval);
-    ret->wrapping = cfg[2].ival;
-    ret->barrier_probability = (float)atof(cfg[3].sval);
-    ret->movetarget = atoi(cfg[4].sval);
+    ret->width = atoi(cfg[0].u.string.sval);
+    ret->height = atoi(cfg[1].u.string.sval);
+    ret->wrapping = cfg[2].u.boolean.bval;
+    ret->barrier_probability = (float)atof(cfg[3].u.string.sval);
+    ret->movetarget = atoi(cfg[4].u.string.sval);
 
     return ret;
 }
diff --git a/osx.m b/osx.m
index be29819b620494094168f0e779b9681307ffdfdd..4798e49da6d178e93d7213b8147fdbfcf466199f 100644 (file)
--- a/osx.m
+++ b/osx.m
@@ -1103,7 +1103,8 @@ struct frontend {
            [tf setEditable:YES];
            [tf setSelectable:YES];
            [tf setBordered:YES];
-           [[tf cell] setTitle:[NSString stringWithUTF8String:i->sval]];
+           [[tf cell] setTitle:[NSString
+                                    stringWithUTF8String:i->u.string.sval]];
            [tf sizeToFit];
            rect = [tf frame];
            /*
@@ -1132,7 +1133,7 @@ struct frontend {
            [b setButtonType:NSSwitchButton];
            [b setTitle:[NSString stringWithUTF8String:i->name]];
            [b sizeToFit];
-           [b setState:(i->ival ? NSOnState : NSOffState)];
+           [b setState:(i->u.boolean.bval ? NSOnState : NSOffState)];
            rect = [b frame];
            if (totalw < rect.size.width + 1) totalw = rect.size.width + 1;
            if (thish < rect.size.height + 1) thish = rect.size.height + 1;
@@ -1161,12 +1162,14 @@ struct frontend {
            pb = [[NSPopUpButton alloc] initWithFrame:tmprect pullsDown:NO];
            [pb setBezelStyle:NSRoundedBezelStyle];
            {
-               char c, *p;
+               char c;
+                const char *p;
 
-               p = i->sval;
+               p = i->u.choices.choicenames;
                c = *p++;
                while (*p) {
-                   char *q, *copy;
+                   const char *q;
+                    char *copy;
 
                    q = p;
                    while (*p && *p != c) p++;
@@ -1180,7 +1183,7 @@ struct frontend {
                    if (*p) p++;
                }
            }
-           [pb selectItemAtIndex:i->ival];
+           [pb selectItemAtIndex:i->u.choices.selected];
            [pb sizeToFit];
 
            rect = [pb frame];
@@ -1303,17 +1306,18 @@ struct frontend {
        for (i = cfg; i->type != C_END; i++) {
            switch (i->type) {
              case C_STRING:
-               sfree(i->sval);
-               i->sval = dupstr([[[(id)cfg_controls[k+1] cell]
+               sfree(i->u.string.sval);
+               i->u.string.sval = dupstr([[[(id)cfg_controls[k+1] cell]
                                   title] UTF8String]);
                k += 2;
                break;
              case C_BOOLEAN:
-               i->ival = [(id)cfg_controls[k] state] == NSOnState;
+               i->u.boolean.bval = [(id)cfg_controls[k] state] == NSOnState;
                k++;
                break;
              case C_CHOICES:
-               i->ival = [(id)cfg_controls[k+1] indexOfSelectedItem];
+               i->u.choices.selected =
+                    [(id)cfg_controls[k+1] indexOfSelectedItem];
                k += 2;
                break;
            }
index 93c1ad6e51b9e5d9e70b241e4fdff1fe42937604..3b5878ba88fd8015c2c2d22974fd4ab1ce3b117e 100644 (file)
@@ -119,10 +119,20 @@ static config_item *game_configure(const game_params *params)
 {
     config_item *ret = snewn(4, config_item);
 
-    CONFIG(0, "Width",       C_STRING, 0, string(20, "%d", params->w));
-    CONFIG(1, "Height",      C_STRING, 0, string(20, "%d", params->h));
-    CONFIG(2, "Region size", C_STRING, 0, string(20, "%d", params->k));
-    CONFIG(3, NULL,          C_END,    0, NULL);
+    ret[0].name = "Width";
+    ret[0].type = C_STRING;
+    ret[0].u.string.sval = string(20, "%d", params->w);
+
+    ret[1].name = "Height";
+    ret[1].type = C_STRING;
+    ret[1].u.string.sval = string(20, "%d", params->h);
+
+    ret[2].name = "Region size";
+    ret[2].type = C_STRING;
+    ret[2].u.string.sval = string(20, "%d", params->k);
+
+    ret[3].name = NULL;
+    ret[3].type = C_END;
 
     return ret;
 }
@@ -131,9 +141,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *params = snew(game_params);
 
-    params->w = atoi(cfg[0].sval);
-    params->h = atoi(cfg[1].sval);
-    params->k = atoi(cfg[2].sval);
+    params->w = atoi(cfg[0].u.string.sval);
+    params->h = atoi(cfg[1].u.string.sval);
+    params->k = atoi(cfg[2].u.string.sval);
 
     return params;
 }
index 9964dd5d4dbd2ed78c27eeeb2542121ac218eb83..e6805534e277ad459aa64368dd4ab3b0a966f808 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -148,19 +148,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -169,8 +165,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     return ret;
 }
diff --git a/pearl.c b/pearl.c
index 2241b46315831c8ca91470e94cac5631d0e66956..e3e83c5125db7e3b7fe39f0617fa7e2581decf42 100644 (file)
--- a/pearl.c
+++ b/pearl.c
@@ -234,29 +234,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->difficulty;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->difficulty;
 
     ret[3].name = "Allow unsoluble";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->nosolve;
+    ret[3].u.boolean.bval = params->nosolve;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -265,10 +260,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->difficulty = cfg[2].ival;
-    ret->nosolve = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->difficulty = cfg[2].u.choices.selected;
+    ret->nosolve = cfg[3].u.boolean.bval;
 
     return ret;
 }
diff --git a/pegs.c b/pegs.c
index 38e73b74f65698115ab48faa4eb34deaf25f7952..35f6624a5cd0f865a4d6f84b578a91dfab9e13fb 100644 (file)
--- a/pegs.c
+++ b/pegs.c
@@ -149,24 +149,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Board type";
     ret[2].type = C_CHOICES;
-    ret[2].sval = TYPECONFIG;
-    ret[2].ival = params->type;
+    ret[2].u.choices.choicenames = TYPECONFIG;
+    ret[2].u.choices.selected = params->type;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -175,9 +171,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->type = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->type = cfg[2].u.choices.selected;
 
     return ret;
 }
index f43ee8345f29315a139f19cabb750bda7d4f1e25..0a91e31013f3afa2313b77201be3adf5a529a2a9 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -137,30 +137,36 @@ typedef struct psdata psdata;
  */
 enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END };
 struct config_item {
-    /*
-     * `name' is never dynamically allocated.
-     */
-    char *name;
-    /*
-     * `type' contains one of the above values.
-     */
+    /* Not dynamically allocated */
+    const char *name;
+    /* Value from the above C_* enum */
     int type;
-    /*
-     * For C_STRING, `sval' is always dynamically allocated and
-     * non-NULL. For C_BOOLEAN and C_END, `sval' is always NULL.
-     * For C_CHOICES, `sval' is non-NULL, _not_ dynamically
-     * allocated, and contains a set of option strings separated by
-     * a delimiter. The delimeter is also the first character in
-     * the string, so for example ":Foo:Bar:Baz" gives three
-     * options `Foo', `Bar' and `Baz'.
-     */
-    char *sval;
-    /*
-     * For C_BOOLEAN, this is TRUE or FALSE. For C_CHOICES, it
-     * indicates the chosen index from the `sval' list. In the
-     * above example, 0==Foo, 1==Bar and 2==Baz.
-     */
-    int ival;
+    union {
+        struct { /* if type == C_STRING */
+            /* Always dynamically allocated and non-NULL */
+            char *sval;
+        } string;
+        struct { /* if type == C_CHOICES */
+            /*
+             * choicenames is non-NULL, not dynamically allocated, and
+             * contains a set of option strings separated by a
+             * delimiter. The delimiter is also the first character in
+             * the string, so for example ":Foo:Bar:Baz" gives three
+             * options `Foo', `Bar' and `Baz'.
+             */
+            const char *choicenames;
+            /*
+             * Indicates the chosen index from the options in
+             * choicenames. In the above example, 0==Foo, 1==Bar and
+             * 2==Baz.
+             */
+            int selected;
+        } choices;
+        struct {
+            /* just TRUE or FALSE */
+            int bval;
+        } boolean;
+    } u;
 };
 
 /*
diff --git a/range.c b/range.c
index 8017f8dc4b14c21058550d4ece6730e9abae9179..dd7ecbc61d5e6e17dfa240520cb9cd61f84554d5 100644 (file)
--- a/range.c
+++ b/range.c
@@ -170,18 +170,14 @@ static config_item *game_configure(const game_params *params)
 
     ret[0].name = "Width";
     ret[0].type = C_STRING;
-    ret[0].sval = nfmtstr(10, "%d", params->w);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = nfmtstr(10, "%d", params->w);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
-    ret[1].sval = nfmtstr(10, "%d", params->h);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = nfmtstr(10, "%d", params->h);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -189,8 +185,8 @@ static config_item *game_configure(const game_params *params)
 static game_params *custom_params(const config_item *configuration)
 {
     game_params *ret = snew(game_params);
-    ret->w = atoi(configuration[0].sval);
-    ret->h = atoi(configuration[1].sval);
+    ret->w = atoi(configuration[0].u.string.sval);
+    ret->h = atoi(configuration[1].u.string.sval);
     return ret;
 }
 
diff --git a/rect.c b/rect.c
index 67cc30a41c85b1008fcca5454dcee4baa25f393d..b31a84e3013a70f89cb02aad8787cae27c4fc867 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -180,30 +180,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Expansion factor";
     ret[2].type = C_STRING;
     sprintf(buf, "%g", params->expandfactor);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Ensure unique solution";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->unique;
+    ret[3].u.boolean.bval = params->unique;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -212,10 +206,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->expandfactor = (float)atof(cfg[2].sval);
-    ret->unique = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->expandfactor = (float)atof(cfg[2].u.string.sval);
+    ret->unique = cfg[3].u.boolean.bval;
 
     return ret;
 }
index 7a40fcc0fef28c669b93be99d8845bf9d2fd38a5..4092282036c58003b3259327dbbef491948e5fa0 100644 (file)
@@ -241,35 +241,29 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "No. of colours";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->ncols);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "Scoring system";
     ret[3].type = C_CHOICES;
-    ret[3].sval = ":(n-1)^2:(n-2)^2";
-    ret[3].ival = params->scoresub-1;
+    ret[3].u.choices.choicenames = ":(n-1)^2:(n-2)^2";
+    ret[3].u.choices.selected = params->scoresub-1;
 
     ret[4].name = "Ensure solubility";
     ret[4].type = C_BOOLEAN;
-    ret[4].sval = NULL;
-    ret[4].ival = params->soluble;
+    ret[4].u.boolean.bval = params->soluble;
 
     ret[5].name = NULL;
     ret[5].type = C_END;
-    ret[5].sval = NULL;
-    ret[5].ival = 0;
 
     return ret;
 }
@@ -278,11 +272,11 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->ncols = atoi(cfg[2].sval);
-    ret->scoresub = cfg[3].ival + 1;
-    ret->soluble = cfg[4].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->ncols = atoi(cfg[2].u.string.sval);
+    ret->scoresub = cfg[3].u.choices.selected + 1;
+    ret->soluble = cfg[4].u.boolean.bval;
 
     return ret;
 }
index 9d782f084aaa3cbf9c4a61e75899fd82f307396a..61bd3c0d72b270d41aeb834958aa45fcd2a2575e 100644 (file)
@@ -387,24 +387,19 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Start and end in corners";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->force_corner_start;
+    ret[2].u.boolean.bval = params->force_corner_start;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -413,9 +408,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->force_corner_start = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->force_corner_start = cfg[2].u.boolean.bval;
 
     return ret;
 }
index ff6960fb0c81592b2f7b679c25b61b8166da2b02..32d5965fb9949a848ec3ba011b2fe038ee286dd5 100644 (file)
--- a/singles.c
+++ b/singles.c
@@ -222,24 +222,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -248,9 +244,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
 
     return ret;
 }
index 562eeb8c1401755421ad02a1dc336bdfcfe5c169..0381edfad2715bbd77d866f974b8765e49bc01d5 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -140,25 +140,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Number of shuffling moves";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->movetarget);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -167,9 +162,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->movetarget = atoi(cfg[2].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->movetarget = atoi(cfg[2].u.string.sval);
 
     return ret;
 }
diff --git a/slant.c b/slant.c
index 5980eb2125a02c8776a84af888d1d61e2833b5a7..02f19fc85d06c11755c2292c7b436e2bed18ef60 100644 (file)
--- a/slant.c
+++ b/slant.c
@@ -184,24 +184,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -210,9 +206,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
 
     return ret;
 }
diff --git a/solo.c b/solo.c
index b40901d1ddf9d4c773c0b09ca283054bc6044cbd..83bc12c9766cfc759baef868ad02dd7280c11dc6 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -445,46 +445,39 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Columns of sub-blocks";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->c);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Rows of sub-blocks";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->r);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "\"X\" (require every number in each main diagonal)";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->xtype;
+    ret[2].u.boolean.bval = params->xtype;
 
     ret[3].name = "Jigsaw (irregularly shaped sub-blocks)";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = (params->r == 1);
+    ret[3].u.boolean.bval = (params->r == 1);
 
     ret[4].name = "Killer (digit sums)";
     ret[4].type = C_BOOLEAN;
-    ret[4].sval = NULL;
-    ret[4].ival = params->killer;
+    ret[4].u.boolean.bval = params->killer;
 
     ret[5].name = "Symmetry";
     ret[5].type = C_CHOICES;
-    ret[5].sval = ":None:2-way rotation:4-way rotation:2-way mirror:"
+    ret[5].u.choices.choicenames = ":None:2-way rotation:4-way rotation:2-way mirror:"
         "2-way diagonal mirror:4-way mirror:4-way diagonal mirror:"
         "8-way mirror";
-    ret[5].ival = params->symm;
+    ret[5].u.choices.selected = params->symm;
 
     ret[6].name = "Difficulty";
     ret[6].type = C_CHOICES;
-    ret[6].sval = ":Trivial:Basic:Intermediate:Advanced:Extreme:Unreasonable";
-    ret[6].ival = params->diff;
+    ret[6].u.choices.choicenames = ":Trivial:Basic:Intermediate:Advanced:Extreme:Unreasonable";
+    ret[6].u.choices.selected = params->diff;
 
     ret[7].name = NULL;
     ret[7].type = C_END;
-    ret[7].sval = NULL;
-    ret[7].ival = 0;
 
     return ret;
 }
@@ -493,16 +486,16 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->c = atoi(cfg[0].sval);
-    ret->r = atoi(cfg[1].sval);
-    ret->xtype = cfg[2].ival;
-    if (cfg[3].ival) {
+    ret->c = atoi(cfg[0].u.string.sval);
+    ret->r = atoi(cfg[1].u.string.sval);
+    ret->xtype = cfg[2].u.boolean.bval;
+    if (cfg[3].u.boolean.bval) {
        ret->c *= ret->r;
        ret->r = 1;
     }
-    ret->killer = cfg[4].ival;
-    ret->symm = cfg[5].ival;
-    ret->diff = cfg[6].ival;
+    ret->killer = cfg[4].u.boolean.bval;
+    ret->symm = cfg[5].u.choices.selected;
+    ret->diff = cfg[6].u.choices.selected;
     ret->kdiff = DIFF_KINTERSECT;
 
     return ret;
diff --git a/tents.c b/tents.c
index e17a893a106e8cd9a7ee1619f132795b9c106eb4..1d987faaef9793239487399e142cdea0d4dde757 100644 (file)
--- a/tents.c
+++ b/tents.c
@@ -371,24 +371,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -397,9 +393,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
 
     return ret;
 }
index 06b7279380b91050b94cba353f4fe6be2eb76931..3892d8e82260774db40511555ac0d963b021f3c7 100644 (file)
--- a/towers.c
+++ b/towers.c
@@ -212,18 +212,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Grid size";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Difficulty";
     ret[1].type = C_CHOICES;
-    ret[1].sval = DIFFCONFIG;
-    ret[1].ival = params->diff;
+    ret[1].u.choices.choicenames = DIFFCONFIG;
+    ret[1].u.choices.selected = params->diff;
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -232,8 +229,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->diff = cfg[1].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->diff = cfg[1].u.choices.selected;
 
     return ret;
 }
index f5f3e0b97d5b868264184cea781c8c16b0a7a8a8..78355cb90def90f02b2b880ea34dfd8ed944266e 100644 (file)
--- a/tracks.c
+++ b/tracks.c
@@ -148,28 +148,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = "Disallow consecutive 1 clues";
     ret[3].type = C_BOOLEAN;
-    ret[3].ival = params->single_ones;
+    ret[3].u.boolean.bval = params->single_ones;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -178,10 +174,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
-    ret->single_ones = cfg[3].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
+    ret->single_ones = cfg[3].u.boolean.bval;
 
     return ret;
 }
index f52e99950793910ca26544cbbb842044897bf7ce..70f768debfdf05af7d708fae44771dd9a5fcf68c 100644 (file)
--- a/twiddle.c
+++ b/twiddle.c
@@ -156,41 +156,33 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Rotating block size";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->n);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = "One number per row";
     ret[3].type = C_BOOLEAN;
-    ret[3].sval = NULL;
-    ret[3].ival = params->rowsonly;
+    ret[3].u.boolean.bval = params->rowsonly;
 
     ret[4].name = "Orientation matters";
     ret[4].type = C_BOOLEAN;
-    ret[4].sval = NULL;
-    ret[4].ival = params->orientable;
+    ret[4].u.boolean.bval = params->orientable;
 
     ret[5].name = "Number of shuffling moves";
     ret[5].type = C_STRING;
     sprintf(buf, "%d", params->movetarget);
-    ret[5].sval = dupstr(buf);
-    ret[5].ival = 0;
+    ret[5].u.string.sval = dupstr(buf);
 
     ret[6].name = NULL;
     ret[6].type = C_END;
-    ret[6].sval = NULL;
-    ret[6].ival = 0;
 
     return ret;
 }
@@ -199,12 +191,12 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->n = atoi(cfg[2].sval);
-    ret->rowsonly = cfg[3].ival;
-    ret->orientable = cfg[4].ival;
-    ret->movetarget = atoi(cfg[5].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->n = atoi(cfg[2].u.string.sval);
+    ret->rowsonly = cfg[3].u.boolean.bval;
+    ret->orientable = cfg[4].u.boolean.bval;
+    ret->movetarget = atoi(cfg[5].u.string.sval);
 
     return ret;
 }
index 27102239a6cedad53a041bd4a119ad484d690be7..a9343e8815de4d811eec7993bd323aa2a8701b63 100644 (file)
--- a/undead.c
+++ b/undead.c
@@ -163,24 +163,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -189,9 +185,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
     return ret;
 }
 
index 6342318b044507ba2286eeed24792e6e634b29dd..d4441e53c6e4e5a64b51ffc14be120fff0ceb92f 100644 (file)
--- a/unequal.c
+++ b/unequal.c
@@ -218,24 +218,21 @@ static config_item *game_configure(const game_params *params)
 
     ret[0].name = "Mode";
     ret[0].type = C_CHOICES;
-    ret[0].sval = ":Unequal:Adjacent";
-    ret[0].ival = params->adjacent;
+    ret[0].u.choices.choicenames = ":Unequal:Adjacent";
+    ret[0].u.choices.selected = params->adjacent;
 
     ret[1].name = "Size (s*s)";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->order);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Difficulty";
     ret[2].type = C_CHOICES;
-    ret[2].sval = DIFFCONFIG;
-    ret[2].ival = params->diff;
+    ret[2].u.choices.choicenames = DIFFCONFIG;
+    ret[2].u.choices.selected = params->diff;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -244,9 +241,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->adjacent = cfg[0].ival;
-    ret->order = atoi(cfg[1].sval);
-    ret->diff = cfg[2].ival;
+    ret->adjacent = cfg[0].u.choices.selected;
+    ret->order = atoi(cfg[1].u.string.sval);
+    ret->diff = cfg[2].u.choices.selected;
 
     return ret;
 }
index 0d2f915c2537698c0d131cd5ec33c2da4cd4e585..a9ae704e9b6247747577252b2706f1560450e8c2 100644 (file)
@@ -212,23 +212,19 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Grid size";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Difficulty";
     ret[1].type = C_CHOICES;
-    ret[1].sval = DIFFCONFIG;
-    ret[1].ival = params->diff;
+    ret[1].u.choices.choicenames = DIFFCONFIG;
+    ret[1].u.choices.selected = params->diff;
 
     ret[2].name = "Show identity";
     ret[2].type = C_BOOLEAN;
-    ret[2].sval = NULL;
-    ret[2].ival = params->id;
+    ret[2].u.boolean.bval = params->id;
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -237,9 +233,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->diff = cfg[1].ival;
-    ret->id = cfg[2].ival;
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->diff = cfg[1].u.choices.selected;
+    ret->id = cfg[2].u.boolean.bval;
 
     return ret;
 }
index 51ac7cbe1e46726aebb507102be52641d8a3fdb5..05a3f8bb2dc5537186f863d1565afdca2ceab933 100644 (file)
@@ -244,25 +244,20 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Solution length limit";
     ret[2].type = C_STRING;
     sprintf(buf, "%d", params->maxmoves);
-    ret[2].sval = dupstr(buf);
-    ret[2].ival = 0;
+    ret[2].u.string.sval = dupstr(buf);
 
     ret[3].name = NULL;
     ret[3].type = C_END;
-    ret[3].sval = NULL;
-    ret[3].ival = 0;
 
     return ret;
 }
@@ -271,9 +266,9 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
-    ret->maxmoves = atoi(cfg[2].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
+    ret->maxmoves = atoi(cfg[2].u.string.sval);
 
     return ret;
 }
index 2f0af35bc2e1fba70c23c324decf4714ccb35e8d..edd0f28672ed504c41241615b5355925ab6de1c1 100644 (file)
@@ -210,19 +210,15 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = NULL;
     ret[2].type = C_END;
-    ret[2].sval = NULL;
-    ret[2].ival = 0;
 
     return ret;
 }
@@ -231,8 +227,8 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w = atoi(cfg[0].sval);
-    ret->h = atoi(cfg[1].sval);
+    ret->w = atoi(cfg[0].u.string.sval);
+    ret->h = atoi(cfg[1].u.string.sval);
 
     return ret;
 }
index 51b168a72df73deec6ae48375ccc40eae43ef0e0..ac5c56508b8274266c58dd98445c7c52bbea0783 100644 (file)
--- a/unruly.c
+++ b/unruly.c
@@ -239,28 +239,24 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Width";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->w2);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = "Height";
     ret[1].type = C_STRING;
     sprintf(buf, "%d", params->h2);
-    ret[1].sval = dupstr(buf);
-    ret[1].ival = 0;
+    ret[1].u.string.sval = dupstr(buf);
 
     ret[2].name = "Unique rows and columns";
     ret[2].type = C_BOOLEAN;
-    ret[2].ival = params->unique;
+    ret[2].u.boolean.bval = params->unique;
 
     ret[3].name = "Difficulty";
     ret[3].type = C_CHOICES;
-    ret[3].sval = DIFFCONFIG;
-    ret[3].ival = params->diff;
+    ret[3].u.choices.choicenames = DIFFCONFIG;
+    ret[3].u.choices.selected = params->diff;
 
     ret[4].name = NULL;
     ret[4].type = C_END;
-    ret[4].sval = NULL;
-    ret[4].ival = 0;
 
     return ret;
 }
@@ -269,10 +265,10 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->w2 = atoi(cfg[0].sval);
-    ret->h2 = atoi(cfg[1].sval);
-    ret->unique = cfg[2].ival;
-    ret->diff = cfg[3].ival;
+    ret->w2 = atoi(cfg[0].u.string.sval);
+    ret->h2 = atoi(cfg[1].u.string.sval);
+    ret->unique = cfg[2].u.boolean.bval;
+    ret->diff = cfg[3].u.choices.selected;
 
     return ret;
 }
index 4dd93be36165c7327a3e16242c0b3636650d3124..4dfe208a147c60b7eb1d96e4eccaafc2f37ff30d 100644 (file)
@@ -185,13 +185,10 @@ static config_item *game_configure(const game_params *params)
     ret[0].name = "Number of points";
     ret[0].type = C_STRING;
     sprintf(buf, "%d", params->n);
-    ret[0].sval = dupstr(buf);
-    ret[0].ival = 0;
+    ret[0].u.string.sval = dupstr(buf);
 
     ret[1].name = NULL;
     ret[1].type = C_END;
-    ret[1].sval = NULL;
-    ret[1].ival = 0;
 
     return ret;
 }
@@ -200,7 +197,7 @@ static game_params *custom_params(const config_item *cfg)
 {
     game_params *ret = snew(game_params);
 
-    ret->n = atoi(cfg[0].sval);
+    ret->n = atoi(cfg[0].u.string.sval);
 
     return ret;
 }
index df1db4fd211b3158a81903080b7de6b0c313c44c..5b7028516020ccb35373aac840c24205654e02c1 100644 (file)
--- a/windows.c
+++ b/windows.c
@@ -2057,52 +2057,43 @@ static config_item *frontend_get_config(frontend *fe, int which,
 
        ret[i].name = "Number of puzzles to print";
        ret[i].type = C_STRING;
-       ret[i].sval = dupstr("1");
-       ret[i].ival = 0;
+       ret[i].u.string.sval = dupstr("1");
        i++;
 
        ret[i].name = "Number of puzzles across the page";
        ret[i].type = C_STRING;
-       ret[i].sval = dupstr("1");
-       ret[i].ival = 0;
+       ret[i].u.string.sval = dupstr("1");
        i++;
 
        ret[i].name = "Number of puzzles down the page";
        ret[i].type = C_STRING;
-       ret[i].sval = dupstr("1");
-       ret[i].ival = 0;
+       ret[i].u.string.sval = dupstr("1");
        i++;
 
        ret[i].name = "Percentage of standard size";
        ret[i].type = C_STRING;
-       ret[i].sval = dupstr("100.0");
-       ret[i].ival = 0;
+       ret[i].u.string.sval = dupstr("100.0");
        i++;
 
        ret[i].name = "Include currently shown puzzle";
        ret[i].type = C_BOOLEAN;
-       ret[i].sval = NULL;
-       ret[i].ival = TRUE;
+       ret[i].u.boolean.bval = TRUE;
        i++;
 
        ret[i].name = "Print solutions";
        ret[i].type = C_BOOLEAN;
-       ret[i].sval = NULL;
-       ret[i].ival = FALSE;
+       ret[i].u.boolean.bval = FALSE;
        i++;
 
        if (fe->game->can_print_in_colour) {
            ret[i].name = "Print in colour";
            ret[i].type = C_BOOLEAN;
-           ret[i].sval = NULL;
-           ret[i].ival = FALSE;
+           ret[i].u.boolean.bval = FALSE;
            i++;
        }
 
        ret[i].name = NULL;
        ret[i].type = C_END;
-       ret[i].sval = NULL;
-       ret[i].ival = 0;
        i++;
 
        return ret;
@@ -2117,17 +2108,18 @@ static char *frontend_set_config(frontend *fe, int which, config_item *cfg)
     if (which < CFG_FRONTEND_SPECIFIC) {
        return midend_set_config(fe->me, which, cfg);
     } else if (which == CFG_PRINT) {
-       if ((fe->printcount = atoi(cfg[0].sval)) <= 0)
+       if ((fe->printcount = atoi(cfg[0].u.string.sval)) <= 0)
            return "Number of puzzles to print should be at least one";
-       if ((fe->printw = atoi(cfg[1].sval)) <= 0)
+       if ((fe->printw = atoi(cfg[1].u.string.sval)) <= 0)
            return "Number of puzzles across the page should be at least one";
-       if ((fe->printh = atoi(cfg[2].sval)) <= 0)
+       if ((fe->printh = atoi(cfg[2].u.string.sval)) <= 0)
            return "Number of puzzles down the page should be at least one";
-       if ((fe->printscale = (float)atof(cfg[3].sval)) <= 0)
+       if ((fe->printscale = (float)atof(cfg[3].u.string.sval)) <= 0)
            return "Print size should be positive";
-       fe->printcurr = cfg[4].ival;
-       fe->printsolns = cfg[5].ival;
-       fe->printcolour = fe->game->can_print_in_colour && cfg[6].ival;
+       fe->printcurr = cfg[4].u.boolean.bval;
+       fe->printsolns = cfg[5].u.boolean.bval;
+       fe->printcolour = fe->game->can_print_in_colour &&
+            cfg[6].u.boolean.bval;
        return NULL;
     } else {
        assert(!"We should never get here");
@@ -2191,7 +2183,7 @@ static void create_config_controls(frontend * fe)
            mkctrl(fe, col2l, col2r, y, y + 12,
                   TEXT("EDIT"), WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL,
                   0, "", (j->ctlid = id++));
-           SetDlgItemTextA(fe->cfgbox, j->ctlid, i->sval);
+           SetDlgItemTextA(fe->cfgbox, j->ctlid, i->u.string.sval);
            break;
 
          case C_BOOLEAN:
@@ -2201,7 +2193,7 @@ static void create_config_controls(frontend * fe)
            mkctrl(fe, col1l, col2r, y + 1, y + 11, TEXT("BUTTON"),
                   BS_NOTIFY | BS_AUTOCHECKBOX | WS_TABSTOP,
                   0, i->name, (j->ctlid = id++));
-           CheckDlgButton(fe->cfgbox, j->ctlid, (i->ival != 0));
+           CheckDlgButton(fe->cfgbox, j->ctlid, (i->u.boolean.bval != 0));
            break;
 
          case C_CHOICES:
@@ -2215,9 +2207,11 @@ static void create_config_controls(frontend * fe)
                         CBS_DROPDOWNLIST | CBS_HASSTRINGS,
                         0, "", (j->ctlid = id++));
            {
-               char c, *p, *q, *str;
+               char c;
+                const char *p, *q;
+                char *str;
 
-               p = i->sval;
+               p = i->u.choices.choicenames;
                c = *p++;
                while (*p) {
                    q = p;
@@ -2236,7 +2230,7 @@ static void create_config_controls(frontend * fe)
                    p = q;
                }
            }
-           SendMessage(ctl, CB_SETCURSEL, i->ival, 0);
+           SendMessage(ctl, CB_SETCURSEL, i->u.choices.selected, 0);
            break;
        }
 
@@ -2324,16 +2318,16 @@ static int CALLBACK ConfigDlgProc(HWND hwnd, UINT msg,
            GetDlgItemText(fe->cfgbox, j->ctlid, buffer, lenof(buffer));
 #endif
            buffer[lenof(buffer)-1] = '\0';
-           sfree(i->sval);
-           i->sval = dupstr(buffer);
+           sfree(i->u.string.sval);
+           i->u.string.sval = dupstr(buffer);
        } else if (i->type == C_BOOLEAN && 
                   (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DBLCLK)) {
-           i->ival = IsDlgButtonChecked(fe->cfgbox, j->ctlid);
+           i->u.boolean.bval = IsDlgButtonChecked(fe->cfgbox, j->ctlid);
        } else if (i->type == C_CHOICES &&
                   HIWORD(wParam) == CBN_SELCHANGE) {
-           i->ival = SendDlgItemMessage(fe->cfgbox, j->ctlid,
-                                        CB_GETCURSEL, 0, 0);
+           i->u.choices.selected = SendDlgItemMessage(fe->cfgbox, j->ctlid,
+                                                       CB_GETCURSEL, 0, 0);
        }
 
        return 0;
@@ -2683,7 +2677,7 @@ static int get_config(frontend *fe, int which)
            ctl = mkctrl(fe, col2l, col2r, y, y+height*3/2,
                         "EDIT", WS_TABSTOP | ES_AUTOHSCROLL,
                         WS_EX_CLIENTEDGE, "", (j->ctlid = id++));
-           SetWindowText(ctl, i->sval);
+           SetWindowText(ctl, i->u.string.sval);
            y += height*3/2;
            break;
 
@@ -2694,7 +2688,7 @@ static int get_config(frontend *fe, int which)
            mkctrl(fe, col1l, col2r, y, y+height, "BUTTON",
                   BS_NOTIFY | BS_AUTOCHECKBOX | WS_TABSTOP,
                   0, i->name, (j->ctlid = id++));
-           CheckDlgButton(fe->cfgbox, j->ctlid, (i->ival != 0));
+           CheckDlgButton(fe->cfgbox, j->ctlid, (i->u.boolean.bval != 0));
            y += height;
            break;
 
@@ -2709,10 +2703,12 @@ static int get_config(frontend *fe, int which)
                         CBS_DROPDOWNLIST | CBS_HASSTRINGS,
                         WS_EX_CLIENTEDGE, "", (j->ctlid = id++));
            {
-               char c, *p, *q, *str;
+               char c;
+                const char *p, *q;
+                char *str;
 
                SendMessage(ctl, CB_RESETCONTENT, 0, 0);
-               p = i->sval;
+               p = i->u.choices.choicenames;
                c = *p++;
                while (*p) {
                    q = p;
@@ -2727,7 +2723,7 @@ static int get_config(frontend *fe, int which)
                }
            }
 
-           SendMessage(ctl, CB_SETCURSEL, i->ival, 0);
+           SendMessage(ctl, CB_SETCURSEL, i->u.choices.selected, 0);
 
            y += height*3/2;
            break;