Update of /cvsroot/xconq/xconq/src/gdl
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv22145
Modified Files:
Makefile.am Makefile.in gvars.cc history.cc lisp.cc module.cc
namer.cc pact.cc player.cc score.cc tables.cc types.cc
world.cc
Log Message:
Add GDL serialization support.
Fix copyrights.
Fix automakefile.
Index: gvars.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/gvars.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** gvars.cc 23 May 2006 18:02:09 -0000 1.4
--- gvars.cc 2 Jun 2006 16:57:43 -0000 1.5
***************
*** 6,10 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
Copyright (C) 2004-2006 Eric A. McDonald
--- 6,10 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
Copyright (C) 2004-2006 Eric A. McDonald
***************
*** 233,236 ****
--- 233,299 ----
}
+ void
+ write_globals(void)
+ {
+ int i, complete = FALSE;
+ Obj *val;
+ time_t now;
+
+ /* Snapshot realtime values, but only after they've been set up. */
+ if (g_elapsed_time() >= 0) {
+ time(&now);
+ set_g_elapsed_time(idifftime(now, game_start_in_real_time));
+ }
+
+ newline_form();
+
+ for (i = 0; vardefns[i].name != 0; ++i) {
+ if (debugging_state_sync
+ && strcmp(vardefns[i].name, "elapsed-real-time") == 0)
+ continue;
+ if (vardefns[i].intgetter != NULL) {
+ if (complete || (*(vardefns[i].intgetter))() != vardefns[i].dflt) {
+ start_form(key(K_SET));
+ add_to_form(vardefns[i].name);
+ add_num_to_form((*(vardefns[i].intgetter))());
+ end_form();
+ newline_form();
+ }
+ } else if (vardefns[i].strgetter != NULL) {
+ if (complete
+ || string_not_default((*(vardefns[i].strgetter))(),
+ vardefns[i].dfltstr)) {
+ start_form(key(K_SET));
+ add_to_form(vardefns[i].name);
+ add_to_form(escaped_string((*(vardefns[i].strgetter))()));
+ end_form();
+ newline_form();
+ }
+ } else if (vardefns[i].objgetter != NULL) {
+ val = (*(vardefns[i].objgetter))();
+ if (complete
+ || val != lispnil
+ /* Must write out explicit nil setting if the default
+ function is defined, so it won't re-run on startup. */
+ || (val == lispnil && vardefns[i].dfltfn != NULL)) {
+ start_form(key(K_SET));
+ add_to_form(vardefns[i].name);
+ space_form();
+ /* Suppress evaluation upon readin. */
+ add_to_form_no_space("'");
+ add_form_to_form((*(vardefns[i].objgetter))());
+ end_form();
+ newline_form();
+ }
+ } else {
+ #ifdef __cplusplus
+ throw "snafu";
+ #else
+ abort();
+ #endif
+ }
+ }
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: Makefile.in
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/Makefile.in,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** Makefile.in 29 May 2006 20:11:12 -0000 1.8
--- Makefile.in 2 Jun 2006 16:57:43 -0000 1.9
***************
*** 66,75 ****
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
! libconq_gdl_la_DEPENDENCIES = unit/libconq_gdl_media.la \
unit/libconq_gdl_unit.la side/libconq_gdl_side.la \
! side/libconq_gdl_gamearea.la
am_libconq_gdl_la_OBJECTS = lisp.lo desc.lo dice.lo types.lo gvars.lo \
tables.lo dir.lo namer.lo pact.lo history.lo player.lo \
! score.lo world.lo module.lo write.lo
libconq_gdl_la_OBJECTS = $(am_libconq_gdl_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src/include
--- 66,75 ----
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
! libconq_gdl_la_DEPENDENCIES = media/libconq_gdl_media.la \
unit/libconq_gdl_unit.la side/libconq_gdl_side.la \
! gamearea/libconq_gdl_gamearea.la
am_libconq_gdl_la_OBJECTS = lisp.lo desc.lo dice.lo types.lo gvars.lo \
tables.lo dir.lo namer.lo pact.lo history.lo player.lo \
! score.lo world.lo module.lo
libconq_gdl_la_OBJECTS = $(am_libconq_gdl_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src/include
***************
*** 230,237 ****
libconq_gdl_la_SOURCES = lisp.cc desc.cc dice.cc types.cc gvars.cc \
tables.cc dir.cc namer.cc pact.cc history.cc player.cc \
! score.cc world.cc module.cc write.cc
! libconq_gdl_la_LIBADD = unit/libconq_gdl_media.la \
unit/libconq_gdl_unit.la side/libconq_gdl_side.la \
! side/libconq_gdl_gamearea.la
all: all-recursive
--- 230,237 ----
libconq_gdl_la_SOURCES = lisp.cc desc.cc dice.cc types.cc gvars.cc \
tables.cc dir.cc namer.cc pact.cc history.cc player.cc \
! score.cc world.cc module.cc
! libconq_gdl_la_LIBADD = media/libconq_gdl_media.la \
unit/libconq_gdl_unit.la side/libconq_gdl_side.la \
! gamearea/libconq_gdl_gamearea.la
all: all-recursive
***************
*** 317,321 ****
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/world.Plo@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Plo@am__quote@
.cc.o:
--- 317,320 ----
Index: player.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/player.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** player.cc 27 May 2006 23:31:33 -0000 1.1
--- player.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 8,12 ****
Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2004-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
--- 8,12 ----
Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
***************
*** 33,36 ****
--- 33,37 ----
*/
+ #include "gdl/side/side.h"
#include "gdl/player.h"
***************
*** 170,173 ****
--- 171,205 ----
}
+ void
+ write_player(Player *player)
+ {
+ start_form(key(K_PLAYER));
+ add_num_to_form(player->id);
+ newline_form();
+ space_form();
+ write_str_prop(key(K_NAME), player->name, "", FALSE, TRUE);
+ write_str_prop(key(K_CONFIG_NAME), player->configname, "", FALSE, TRUE);
+ write_str_prop(key(K_DISPLAY_NAME), player->displayname, "", FALSE, TRUE);
+ write_str_prop(key(K_AI_TYPE_NAME), player->aitypename, "", FALSE, TRUE);
+ space_form();
+ end_form();
+ newline_form();
+ }
+
+ void
+ write_players(void)
+ {
+ Side *side;
+
+ Dprintf("Will try to write players ...\n");
+ for_all_sides(side) {
+ if (side->player != NULL) {
+ write_player(side->player);
+ Dprintf("Wrote player %s,\n", player_desig(side->player));
+ }
+ }
+ Dprintf("... Done writing players.\n");
+ }
+
// Game Setup
Index: pact.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/pact.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pact.cc 27 May 2006 23:01:40 -0000 1.1
--- pact.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 6,12 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2004-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
--- 6,12 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
***************
*** 101,104 ****
--- 101,136 ----
}
+ void
+ write_agreement(Agreement *agreement)
+ {
+ start_form(key(K_AGREEMENT));
+ add_num_to_form(agreement->id);
+ newline_form();
+ space_form();
+ write_str_prop(key(K_TYPE_NAME), agreement->agtype, "", FALSE, TRUE);
+ write_str_prop(key(K_NAME), agreement->name, "", FALSE, TRUE);
+ write_num_prop(key(K_STATE), agreement->state, 0, FALSE, TRUE);
+ write_lisp_prop(key(K_TERMS), agreement->terms, lispnil, FALSE, FALSE, TRUE);
+ write_num_prop(key(K_DRAFTERS), agreement->drafters, 0, FALSE, TRUE);
+ write_num_prop(key(K_PROPOSERS), agreement->proposers, 0, FALSE, TRUE);
+ write_num_prop(key(K_SIGNERS), agreement->signers, 0, FALSE, TRUE);
+ write_num_prop(key(K_WILLING_TO_SIGN), agreement->willing, 0, FALSE, TRUE);
+ write_num_prop(key(K_KNOWN_TO), agreement->knownto, 0, FALSE, TRUE);
+ write_num_prop(key(K_ENFORCEMENT), agreement->enforcement, 0, FALSE, TRUE);
+ space_form();
+ end_form();
+ newline_form();
+ }
+
+ void
+ write_agreements(void)
+ {
+ Agreement *ag;
+
+ for_all_agreements(ag) {
+ write_agreement(ag);
+ }
+ }
+
#endif
Index: world.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/world.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** world.cc 29 May 2006 20:11:12 -0000 1.1
--- world.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 38,41 ****
--- 38,42 ----
#include "gdl/gamearea/area.h"
#include "gdl/world.h"
+ #include "gdl/module.h"
NAMESPACE_XCONQ_BEGIN
***************
*** 51,54 ****
--- 52,59 ----
int daynight = FALSE;
+ // Global Variables: Behavior Options
+
+ int doreshape;
+
// Queries
***************
*** 148,151 ****
--- 153,182 ----
}
+ int
+ reshaped_point(int x1, int y1, int *x2p, int *y2p)
+ {
+ *x2p = (((x1 - reshaper->subarea_x) * reshaper->final_subarea_width )
+ / reshaper->subarea_width ) + reshaper->final_subarea_x;
+ *y2p = (((y1 - reshaper->subarea_y) * reshaper->final_subarea_height)
+ / reshaper->subarea_height) + reshaper->final_subarea_y;
+ return TRUE;
+ }
+
+ void
+ write_world(void)
+ {
+ newline_form();
+ start_form(key(K_WORLD));
+ /* K_CIRCUMFERENCE always written. */
+ add_num_to_form((doreshape ? reshaper->final_circumference : world.circumference));
+ write_num_prop(key(K_DAY_LENGTH), world.daylength, 1, FALSE, FALSE);
+ write_num_prop(key(K_YEAR_LENGTH), world.yearlength, 1, FALSE, FALSE);
+ write_num_prop(key(K_AXIAL_TILT), world.axial_tilt, 0, FALSE, FALSE);
+ write_num_prop(key(K_DAYLIGHT_FRACTION), world.daylight_fraction, 0, FALSE, FALSE);
+ write_num_prop(key(K_TWILIGHT_FRACTION), world.twilight_fraction, 0, FALSE, FALSE);
+ end_form();
+ newline_form();
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: types.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/types.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** types.cc 29 May 2006 14:22:03 -0000 1.5
--- types.cc 2 Jun 2006 16:57:43 -0000 1.6
***************
*** 34,37 ****
--- 34,38 ----
#include "gdl/tables.h"
+ #include "gdl/module.h"
// Function Macros: Game Entity Property Accessors
***************
*** 523,526 ****
--- 524,536 ----
}
+ char *
+ shortest_escaped_name(int u)
+ {
+ char *internalname = u_internal_name(u);
+
+ sprintf(shortestbuf, "%s", escaped_symbol(internalname));
+ return shortestbuf;
+ }
+
int
could_be_on(int u, int t)
***************
*** 1736,1739 ****
--- 1746,2059 ----
}
+ void
+ write_utype_value_list(char *name, short *arr, int dflt, int addnewline)
+ {
+ int u, writeany;
+
+ if (arr == NULL)
+ return;
+ writeany = FALSE;
+ for_all_unit_types(u) {
+ if (arr[u] != dflt) {
+ writeany = TRUE;
+ break;
+ }
+ }
+ if (!writeany)
+ return;
+ space_form();
+ start_form(name);
+ for_all_unit_types(u) {
+ add_num_to_form(arr[u]);
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+
+ void
+ write_mtype_value_list(char *name, short *arr, int dflt, int addnewline)
+ {
+ int m, writeany;
+
+ if (nummtypes == 0 || arr == NULL)
+ return;
+ writeany = FALSE;
+ for_all_material_types(m) {
+ if (arr[m] != dflt) {
+ writeany = TRUE;
+ break;
+ }
+ }
+ if (!writeany)
+ return;
+ space_form();
+ start_form(name);
+ for_all_material_types(m) {
+ add_num_to_form(arr[m]);
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+
+ void
+ write_treasury_list(char *name, long *arr, int dflt, int addnewline)
+ {
+ int m, writeany;
+
+ if (nummtypes == 0 || arr == NULL)
+ return;
+ writeany = FALSE;
+ for_all_material_types(m) {
+ if (arr[m] != dflt) {
+ writeany = TRUE;
+ break;
+ }
+ }
+ if (!writeany)
+ return;
+ space_form();
+ start_form(name);
+ for_all_material_types(m) {
+ add_num_to_form(arr[m]);
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+
+ void
+ write_atype_value_list(char *name, short *arr, int dflt, int addnewline)
+ {
+ int a, writeany;
+
+ if (numatypes == 0 || arr == NULL)
+ return;
+ writeany = FALSE;
+ for_all_advance_types(a) {
+ if (arr[a] != dflt) {
+ writeany = TRUE;
+ break;
+ }
+ }
+ if (!writeany)
+ return;
+ space_form();
+ start_form(name);
+ for_all_advance_types(a) {
+ add_num_to_form(arr[a]);
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+
+ void
+ write_utype_string_list(char *name, char **arr, char *dflt, int addnewline)
+ {
+ int u, writeany;
+
+ if (arr == NULL)
+ return;
+ writeany = FALSE;
+ for_all_unit_types(u) {
+ if (arr[u] != dflt /* bogus, should use strcmp */) {
+ writeany = TRUE;
+ break;
+ }
+ }
+ if (!writeany)
+ return;
+ space_form();
+ start_form(name);
+ for_all_unit_types(u) {
+ add_to_form(escaped_string(arr[u]));
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+
+ void
+ write_type_name_list(int typ, int *flags, int dim)
+ {
+ int j, first = TRUE, listlen = 0;
+
+ if (flags == NULL)
+ return;
+ for (j = 0; j < dim; ++j)
+ if (flags[j])
+ ++listlen;
+ if (listlen > 1)
+ start_form("");
+ for (j = 0; j < dim; ++j) {
+ if (flags[j]) {
+ if (first)
+ first = FALSE;
+ else
+ space_form();
+ add_to_form_no_space(escaped_symbol(name_from_typ(typ, j)));
+ }
+ }
+ if (listlen > 1)
+ end_form();
+ }
+
+ void
+ write_types(void)
+ {
+ int u, m, t, i, ival;
+ char *name, *sval;
+ Obj *obj;
+
+ /* (or write out all the default values first for doc, then
+ only write changed values) */
+
+ for_all_unit_types(u) {
+ start_form(key(K_UNIT_TYPE));
+ name = shortest_escaped_name(u);
+ add_to_form(name);
+ newline_form();
+ space_form();
+ for (i = 0; utypedefns[i].name != NULL; ++i) {
+ /* Don't write out props used internally only, unless debugging. */
+ if ((strncmp(utypedefns[i].name, "zz-", 3) == 0) && !Debug)
+ continue;
+ if (utypedefns[i].intgetter) {
+ ival = (*(utypedefns[i].intgetter))(u);
+ write_num_prop(utypedefns[i].name, ival,
+ utypedefns[i].dflt, FALSE, TRUE);
+ } else if (utypedefns[i].strgetter) {
+ sval = (*(utypedefns[i].strgetter))(u);
+ /* Special-case a couple possibly-redundant slots. */
+ if (utypedefns[i].strgetter == u_type_name
+ && strcmp(name, sval) == 0)
+ continue;
+ if (utypedefns[i].strgetter == u_internal_name
+ && strcmp(name, sval) == 0)
+ continue;
+ write_str_prop(utypedefns[i].name, sval,
+ utypedefns[i].dfltstr, FALSE, TRUE);
+ } else {
+ obj = (*(utypedefns[i].objgetter))(u);
+ write_lisp_prop(utypedefns[i].name, obj,
+ lispnil, FALSE, FALSE, TRUE);
+ }
+ }
+ space_form();
+ end_form();
+ newline_form();
+ }
+ newline_form();
+ for_all_material_types(m) {
+ start_form(key(K_MATERIAL_TYPE));
+ name = escaped_symbol(m_type_name(m));
+ add_to_form(name);
+ newline_form();
+ space_form();
+ for (i = 0; mtypedefns[i].name != NULL; ++i) {
+ /* Don't write out props used internally only, unless debugging. */
+ if ((strncmp(mtypedefns[i].name, "zz-", 3) == 0) && !Debug)
+ continue;
+ if (mtypedefns[i].intgetter) {
+ ival = (*(mtypedefns[i].intgetter))(m);
+ write_num_prop(mtypedefns[i].name, ival,
+ mtypedefns[i].dflt, FALSE, TRUE);
+ } else if (mtypedefns[i].strgetter) {
+ sval = (*(mtypedefns[i].strgetter))(m);
+ /* Special-case a a possibly-redundant slot. */
+ if (mtypedefns[i].strgetter == m_type_name
+ && strcmp(name, sval) == 0)
+ continue;
+ write_str_prop(mtypedefns[i].name, sval,
+ mtypedefns[i].dfltstr, FALSE, TRUE);
+ } else {
+ obj = (*(mtypedefns[i].objgetter))(m);
+ write_lisp_prop(mtypedefns[i].name, obj,
+ lispnil, FALSE, FALSE, TRUE);
+ }
+ }
+ space_form();
+ end_form();
+ newline_form();
+ }
+ newline_form();
+ for_all_terrain_types(t) {
+ start_form(key(K_TERRAIN_TYPE));
+ name = escaped_symbol(t_type_name(t));
+ add_to_form(name);
+ newline_form();
+ space_form();
+ for (i = 0; ttypedefns[i].name != NULL; ++i) {
+ /* Don't write out props used internally only, unless debugging. */
+ if ((strncmp(ttypedefns[i].name, "zz-", 3) == 0) && !Debug)
+ continue;
+ if (ttypedefns[i].intgetter) {
+ ival = (*(ttypedefns[i].intgetter))(t);
+ write_num_prop(ttypedefns[i].name, ival,
+ ttypedefns[i].dflt, FALSE, TRUE);
+ } else if (ttypedefns[i].strgetter) {
+ sval = (*(ttypedefns[i].strgetter))(t);
+ /* Special-case a a possibly-redundant slot. */
+ if (ttypedefns[i].strgetter == t_type_name
+ && strcmp(name, sval) == 0)
+ continue;
+ write_str_prop(ttypedefns[i].name, sval,
+ ttypedefns[i].dfltstr, FALSE, TRUE);
+ } else {
+ obj = (*(ttypedefns[i].objgetter))(t);
+ write_lisp_prop(ttypedefns[i].name, obj,
+ lispnil, FALSE, FALSE, TRUE);
+ }
+ }
+ space_form();
+ end_form();
+ newline_form();
+ }
+ for_all_advance_types(t) {
+ start_form(key(K_ADVANCE_TYPE));
+ add_to_form(escaped_symbol(a_type_name(t)));
+ newline_form();
+ space_form();
+ for (i = 0; atypedefns[i].name != NULL; ++i) {
+ /* Don't write out props used internally only, unless debugging. */
+ if ((strncmp(atypedefns[i].name, "zz-", 3) == 0) && !Debug)
+ continue;
+ if (atypedefns[i].intgetter) {
+ ival = (*(atypedefns[i].intgetter))(t);
+ write_num_prop(atypedefns[i].name, ival,
+ atypedefns[i].dflt, FALSE, TRUE);
+ } else if (atypedefns[i].strgetter) {
+ sval = (*(atypedefns[i].strgetter))(t);
+ /* Special-case a a possibly-redundant slot. */
+ if (atypedefns[i].strgetter == a_type_name
+ && strcmp(name, sval) == 0)
+ continue;
+ write_str_prop(atypedefns[i].name, sval,
+ atypedefns[i].dfltstr, FALSE, TRUE);
+ } else {
+ obj = (*(atypedefns[i].objgetter))(t);
+ write_lisp_prop(atypedefns[i].name, obj,
+ lispnil, FALSE, FALSE, TRUE);
+ }
+ }
+ space_form();
+ end_form();
+ newline_form();
+ }
+ newline_form();
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: lisp.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/lisp.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** lisp.cc 27 May 2006 02:55:13 -0000 1.3
--- lisp.cc 2 Jun 2006 16:57:43 -0000 1.4
***************
*** 6,9 ****
--- 6,10 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
+ Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
Copyright (C) 2004-2006 Eric A. McDonald
***************
*** 40,43 ****
--- 41,45 ----
#include "gdl/kernel.h"
#include "gdl/ui.h"
+ #include "gdl/dice.h"
#include "gdl/tables.h"
#include "gdl/unit/unit.h"
***************
*** 121,124 ****
--- 123,129 ----
static char *escapedthingbuf;
+ //! Buffer for embedding forms in forms.
+ static char *onemorebuf;
+
// Local Function Declarations: Notifications
***************
*** 294,297 ****
--- 299,320 ----
}
+ int
+ string_not_default(char *str, char *dflt)
+ {
+ if (empty_string(dflt)) {
+ if (empty_string(str)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ } else {
+ if (empty_string(str)) {
+ return TRUE;
+ } else {
+ return (strcmp(str, dflt) != 0);
+ }
+ }
+ }
+
// Queries: Attribution
***************
*** 616,619 ****
--- 639,658 ----
Obj *
+ replace_at_key(Obj *lis, char *key, Obj *newval)
+ {
+ Obj *rest, *bdgs, *bdg;
+
+ for_all_list(lis, rest) {
+ bdgs = car(rest);
+ bdg = car(bdgs);
+ if (stringp(bdg) && strcmp(key, c_string(bdg)) == 0) {
+ set_cdr(bdgs, newval);
+ return lis;
+ }
+ }
+ return cons(cons(new_string(key), newval), lis);
+ }
+
+ Obj *
remove_from_list(Obj *element, Obj *lis)
{
***************
*** 2017,2094 ****
}
-
- #if (0) // Temp disable.
-
- int
- member(Obj *x, Obj *lis)
- {
- if (lis == lispnil) {
- return FALSE;
- } else if (!consp(lis)) {
- /* should probably be an error of some sort */
- return FALSE;
- } else if (equal(x, car(lis))) {
- return TRUE;
- } else {
- return member(x, cdr(lis));
- }
- }
-
- /* Return the nth element of a list. */
-
- Obj *
- elt(Obj *lis, int n)
- {
- while (n-- > 0) {
- lis = cdr(lis);
- }
- return car(lis);
- }
-
- Obj *
- reverse(Obj *lis)
- {
- Obj *rslt = lispnil;
-
- for (; lis != lispnil; lis = cdr(lis)) {
- rslt = cons(car(lis), rslt);
- }
- return rslt;
- }
-
- Obj *
- find_at_key(Obj *lis, char *key)
- {
- Obj *rest, *bdgs, *bdg;
-
- for_all_list(lis, rest) {
- bdgs = car(rest);
- bdg = car(bdgs);
- if (stringp(bdg) && strcmp(key, c_string(bdg)) == 0) {
- return cdr(bdgs);
- }
- }
- return lispnil;
- }
-
- Obj *
- replace_at_key(Obj *lis, char *key, Obj *newval)
- {
- Obj *rest, *bdgs, *bdg;
-
- for_all_list(lis, rest) {
- bdgs = car(rest);
- bdg = car(bdgs);
- if (stringp(bdg) && strcmp(key, c_string(bdg)) == 0) {
- set_cdr(bdgs, newval);
- return lis;
- }
- }
- return cons(cons(new_string(key), newval), lis);
- }
-
- /* These two routines make sure that any symbols and strings can
- be read in again. */
-
char *
escaped_symbol(char *str)
--- 2056,2059 ----
***************
*** 2112,2118 ****
}
- /* Note that this works correctly on NULL strings, turning them into
- strings of length 0. */
-
char *
escaped_string(char *str)
--- 2077,2080 ----
***************
*** 2133,2145 ****
}
- /* The escaped_string() function makes a dangerous assumption about
- the length of an escaped (or even unescaped) string being less than
- the BUFSIZE, which is the size of escapedthingbuf.
- safe_escaped_string() is slightly less efficient, but avoids this
- assumption. Do note, however, that safe_escaped_string() can result
- in a memory leak, if the caller does not free the result after
- using it.
- */
-
char *
safe_escaped_string(char *str, int len)
--- 2095,2098 ----
***************
*** 2170,2173 ****
--- 2123,2420 ----
}
+ void
+ start_form(char *hd)
+ {
+ if (wfp) {
+ fprintf(wfp, "(%s", hd);
+ } else {
+ add_to_packet("(");
+ add_to_packet(hd);
+ }
+ }
+
+ void
+ end_form(void)
+ {
+ if (wfp) {
+ fputs(")", wfp);
+ } else {
+ add_to_packet(")");
+ }
+ }
+
+ void
+ newline_form(void)
+ {
+ if (wfp) {
+ fprintf(wfp, "\n");
+ } else {
+ add_to_packet("\n");
+ }
+ }
+
+ void
+ space_form(void)
+ {
+ if (wfp) {
+ fputs(" ", wfp);
+ } else {
+ add_to_packet(" ");
+ }
+ }
+
+ void
+ add_to_form(char *x)
+ {
+ if (wfp) {
+ fprintf(wfp, " %s", x);
+ } else {
+ add_to_packet(" ");
+ add_to_packet(x);
+ }
+ }
+
+ void
+ add_to_form_no_space(char *x)
+ {
+ if (wfp) {
+ fputs(x, wfp);
+ } else {
+ add_to_packet(x);
+ }
+ }
+
+ void
+ add_char_to_form(int x)
+ {
+ char buf[2];
+
+ if (wfp) {
+ fprintf(wfp, "%c", x);
+ } else {
+ buf[0] = x;
+ buf[1] = '\0';
+ add_to_packet(buf);
+ }
+ }
+
+ void
+ add_num_to_form(int x)
+ {
+ char buf[30];
+
+ if (wfp) {
+ fprintf(wfp, " %d", x);
+ } else {
+ sprintf(buf, " %d", x);
+ add_to_packet(buf);
+ }
+ }
+
+ void
+ add_num_to_form_no_space(int x)
+ {
+ char buf[30];
+
+ if (wfp) {
+ fprintf(wfp, "%d", x);
+ } else {
+ sprintf(buf, "%d", x);
+ add_to_packet(buf);
+ }
+ }
+
+ void
+ add_num_or_dice_to_form(int x, int valtype)
+ {
+ char valbuf [BUFSIZE];
+
+ if (GDLDICE1 == valtype)
+ dice1_desc(valbuf, (DiceRep)x);
+ else if (GDLDICE2 == valtype)
+ dice2_desc(valbuf, (DiceRep)x);
+ else
+ snprintf(valbuf, BUFSIZE, "%d", x);
+ if (wfp)
+ fputs(valbuf, wfp);
+ else
+ add_to_packet(valbuf);
+ }
+
+ void
+ add_form_to_form(Obj *x)
+ {
+ if (wfp) {
+ fprintlisp(wfp, x);
+ } else {
+ /* Even this might not be enough (should have a better strategy
+ for downloading large Lisp objects) */
+ if (onemorebuf == NULL)
+ onemorebuf = (char *)xmalloc(50000);
+ sprintlisp(onemorebuf, x, 50000);
+ add_to_packet(onemorebuf);
+ }
+ }
+
+ void
+ write_bool_prop(
+ char *name,
+ int value,
+ int dflt,
+ int nodefaulting, int addnewline)
+ {
+ if (nodefaulting || value != dflt) {
+ space_form();
+ start_form(name);
+ add_to_form((char *)(value ? "true" : "false"));
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+ }
+
+ void
+ write_num_prop(
+ char *name,
+ int value,
+ int dflt,
+ int nodefaulting, int addnewline)
+ {
+ if (nodefaulting || value != dflt) {
+ space_form();
+ start_form(name);
+ add_num_to_form(value);
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+ }
+
+ void
+ write_str_prop(
+ char *name,
+ char *value,
+ char *dflt,
+ int nodefaulting, int addnewline)
+ {
+ char *tmp = NULL;
+ int len = 0;
+ if (nodefaulting || string_not_default(value, dflt)) {
+ space_form();
+ start_form(name);
+ if (NULL != value){
+ len = strlen(value);
+ if (((BUFSIZE - 3) / 2) < len) {
+ tmp = safe_escaped_string(value, len);
+ add_to_form(tmp);
+ free(tmp);
+ }
+ else {
+ add_to_form(escaped_string(value));
+ }
+ }
+ else {
+ add_to_form(escaped_string(value));
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+ }
+
+ void
+ write_lisp_prop(
+ char *name,
+ Obj *value,
+ Obj *dflt,
+ int nodefaulting, int as_cdr, int addnewline)
+ {
+ Obj *rest;
+
+ /* Sanity check. */
+ if (value == NULL) {
+ run_warning("Property \"%s\" has a bad value NULL, ignoring", name);
+ return;
+ }
+ if (nodefaulting || !equal(value, dflt)) {
+ space_form();
+ start_form(name);
+ if (as_cdr && consp(value)) {
+ for_all_list(value, rest) {
+ space_form();
+ add_form_to_form(car(rest));
+ }
+ } else {
+ space_form();
+ add_form_to_form(value);
+ }
+ end_form();
+ if (addnewline) {
+ newline_form();
+ space_form();
+ }
+ }
+ }
+
+ #if (0) // Temp disable.
+
+ int
+ member(Obj *x, Obj *lis)
+ {
+ if (lis == lispnil) {
+ return FALSE;
+ } else if (!consp(lis)) {
+ /* should probably be an error of some sort */
+ return FALSE;
+ } else if (equal(x, car(lis))) {
+ return TRUE;
+ } else {
+ return member(x, cdr(lis));
+ }
+ }
+
+ /* Return the nth element of a list. */
+
+ Obj *
+ elt(Obj *lis, int n)
+ {
+ while (n-- > 0) {
+ lis = cdr(lis);
+ }
+ return car(lis);
+ }
+
+ Obj *
+ reverse(Obj *lis)
+ {
+ Obj *rslt = lispnil;
+
+ for (; lis != lispnil; lis = cdr(lis)) {
+ rslt = cons(car(lis), rslt);
+ }
+ return rslt;
+ }
+
+ Obj *
+ find_at_key(Obj *lis, char *key)
+ {
+ Obj *rest, *bdgs, *bdg;
+
+ for_all_list(lis, rest) {
+ bdgs = car(rest);
+ bdg = car(bdgs);
+ if (stringp(bdg) && strcmp(key, c_string(bdg)) == 0) {
+ return cdr(bdgs);
+ }
+ }
+ return lispnil;
+ }
+
#ifdef DEBUGGING
Index: namer.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/namer.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** namer.cc 27 May 2006 19:28:16 -0000 1.1
--- namer.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 6,12 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2004-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
--- 6,12 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
***************
*** 123,126 ****
--- 123,150 ----
}
+ void
+ write_namers(void)
+ {
+ extern Obj *namerlist;
+ Obj *rest, *namer;
+
+ for_all_list(namerlist, rest) {
+ namer = car(rest);
+ start_form(key(K_NAMER));
+ space_form();
+ add_form_to_form(namer->v.ptr.sym);
+ newline_form();
+ space_form();
+ space_form();
+ add_form_to_form((Obj *) namer->v.ptr.data);
+ newline_form();
+ space_form();
+ space_form();
+ end_form();
+ newline_form();
+ newline_form();
+ }
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: history.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/history.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** history.cc 23 May 2006 20:59:16 -0000 1.1
--- history.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 6,12 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2004-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
--- 6,12 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
***************
*** 33,38 ****
--- 33,46 ----
*/
+ #include "gdl/base.h"
+ #include <cstdarg>
+
+ #include "gdl/kernel.h"
+ #include "gdl/ui.h"
#include "gdl/types.h"
+ #include "gdl/gvars.h"
+ #include "gdl/unit/pastunit.h"
#include "gdl/history.h"
+ #include "gdl/score.h"
NAMESPACE_XCONQ_BEGIN
***************
*** 54,59 ****
--- 62,330 ----
};
+ // Global Variables
+
HistEvent *history;
+ // Local Variables: Behavior Options
+
+ //! True, if events are being recorded into the history.
+ static int recording_events;
+
+ // Local Function Declarations: History Management
+
+ //! Notify side of event.
+ static void notify_event(Side *side, HistEvent *hevt);
+
+ // Queries
+
+ int
+ find_event_type(Obj *sym)
+ {
+ int i;
+
+ for (i = 0; hevtdefns[i].name != NULL; ++i) {
+ if (strcmp(c_string(sym), hevtdefns[i].name) == 0)
+ return i;
+ }
+ return -1;
+ }
+
+ int
+ pattern_matches_event(Obj *pattern, HistEvent *hevt)
+ {
+ int data0, u;
+ Obj *rest, *subpat;
+ PastUnit *pastunit;
+
+ if (find_event_type(car(pattern)) != hevt->type)
+ return FALSE;
+ data0 = hevt->data[0];
+ for_all_list(cdr(pattern), rest) {
+ subpat = car(rest);
+ if (symbolp(subpat)) {
+ switch (hevt->type) {
+ case H_UNIT_STARVED:
+ case H_UNIT_VANISHED:
+ u = utype_from_name(c_string(subpat));
+ pastunit = find_past_unit(data0);
+ if (pastunit != NULL && pastunit->type == u)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ } else {
+ /* (should warn of bad pattern syntax?) */
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ void
+ event_desc_from_list(Side *side, Obj *lis, HistEvent *hevt, char *buf)
+ {
+ int n;
+ Obj *rest, *item;
+ PastUnit *pastunit;
+
+ buf[0] = '\0';
+ for_all_list(lis, rest) {
+ item = car(rest);
+ if (stringp(item)) {
+ strcat(buf, c_string(item));
+ } else if (numberp(item)) {
+ n = c_number(item);
+ if (between(0, n, 3)) {
+ switch (hevt->type) {
+ case H_UNIT_STARVED:
+ case H_UNIT_VANISHED:
+ pastunit = find_past_unit(hevt->data[0]);
+ if (pastunit != NULL) {
+ strcat(buf, past_unit_handle(side, pastunit));
+ } else {
+ tprintf(buf, "%d?", hevt->data[0]);
+ }
+ break;
+ /* (should add other event types) */
+ default:
+ break;
+ }
+ } else {
+ tprintf(buf, " ??%d?? ", n);
+ }
+ } else {
+ strcat(buf, " ????? ");
+ }
+ }
+ }
+
+ // History Management
+
+ static
+ void
+ notify_event(Side *side, HistEvent *hevt)
+ {
+ char abuf[BUFSIZE];
+ Obj *rest, *head, *pattern, *text;
+ Side *side2;
+ Unit *unit;
+
+ for_all_list(g_event_notices(), rest) {
+ head = car(rest);
+ if (consp(head)) {
+ pattern = car(head);
+ if (symbolp(pattern)
+ && find_event_type(pattern) == hevt->type) {
+ text = cadr(head);
+ if (stringp(text)) {
+ sprintf(abuf, c_string(text));
+ } else {
+ sprintlisp(abuf, text, 50);
+ }
+ notify(side, "%s", abuf);
+ return;
+ } else if (consp(pattern)
+ && symbolp(car(pattern))
+ && pattern_matches_event(pattern, hevt)
+ ) {
+ text = cadr(head);
+ if (stringp(text)) {
+ strcpy(abuf, c_string(text));
+ } else {
+ event_desc_from_list(side, text, hevt, abuf);
+ }
+ notify(side, "%s", abuf);
+ return;
+ }
+ }
+ }
+ /* If we didn't find anything special, still put out some generic
+ messages for important cases. */
+ switch (hevt->type) {
+ case H_SIDE_LOST:
+ if (hevt->data[0] == side_number(side)) {
+ notify(side, "You lost!");
+ } else {
+ notify(side, "%s lost!", side_desig(side_n(hevt->data[0])));
+ }
+ break;
+ case H_SIDE_WON:
+ if (hevt->data[0] == side_number(side)) {
+ notify(side, "You won!");
+ } else {
+ notify(side, "%s won!", side_desig(side_n(hevt->data[0])));
+ }
+ break;
+ #if 0 /* this already has a special message */
+ case H_GAME_ENDED:
+ notify(side, "The game is over!");
+ break;
+ #endif
+ case H_UNIT_COMPLETED:
+ side2 = side_n(hevt->data[0]);
+ unit = find_unit(hevt->data[1]);
+ if (unit != NULL) {
+ if (side2 == side) {
+ notify(side, "You completed %s.",
+ unit_handle(side, unit));
+ } else {
+ notify(side, "%s completed %s.",
+ side_desig(side2), unit_handle(side2, unit));
+ }
+ }
+ break;
+ case H_UNIT_CREATED:
+ side2 = side_n(hevt->data[0]);
+ unit = find_unit(hevt->data[1]);
+ if (unit != NULL) {
+ if (side2 == side) {
+ notify(side, "You created %s.",
+ unit_handle(side, unit));
+ } else {
+ notify(side, "%s created %s.",
+ side_desig(side2), unit_handle(side2, unit));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ HistEvent *
+ record_event(HistEventType type, SideMask observers, ...)
+ {
+ int i, val;
+ char *descs;
+ HistEvent *hevt;
+ Side *side;
+ va_list ap;
+
+ if (!recording_events)
+ return NULL;
+ hevt = create_historical_event(type);
+ hevt->startdate = g_turn();
+ hevt->enddate = g_turn();
+ hevt->observers = observers;
+ descs = hevtdefns[type].datadescs;
+
+ va_start(ap, observers);
+ for (i = 0; descs[i] != '\0'; ++i) {
+ if (i >= 4)
+ run_error("hevt type %d has too many parameters", type);
+ val = va_arg(ap, int);
+ hevt->data[i] = val;
+ }
+ va_end(ap);
+
+ /* Check on plausibility of event data. */
+ for (i = 0; descs[i] != '\0'; ++i) {
+ val = hevt->data[i];
+ switch (descs[i]) {
+ case 'S':
+ if (!between(0, val, numsides))
+ run_warning("invalid side number %d in hist event", val);
+ break;
+ case 'U':
+ /* Note that when validating unit id, the unit may be in
+ the middle of the the process of becoming a past unit,
+ so allowing finding a dead unit. */
+ if (val != 0
+ && find_unit_dead_or_alive(val) == NULL
+ && find_past_unit(val) == NULL)
+ run_warning("invalid unit/pastunit id %d in hist event", val);
+ break;
+ default:
+ break;
+ }
+ }
+ /* Insert the newly created event. */
+ hevt->next = history;
+ hevt->prev = history->prev;
+ history->prev->next = hevt;
+ history->prev = hevt;
+ Dprintf("Recorded event %s (observed by %d)\n",
+ hevtdefns[hevt->type].name, hevt->observers);
+ if (observers != NOSIDES) {
+ /* Let all the observers' interfaces look at this event. */
+ for_all_sides(side) {
+ if (side_in_set(side, observers) && active_display(side)) {
+ update_event_display(side, hevt, TRUE);
+ notify_event(side, hevt);
+ if (g_event_movies() != lispnil) {
+ play_event_movies(side, hevt);
+ }
+ }
+ }
+ }
+ /* Flag that we should look at post-event scorekeepers soon. */
+ if (any_post_event_scores && !beforestart && !endofgame)
+ need_post_event_scores = TRUE;
+ return hevt;
+ }
+
// Lifecycle Management
***************
*** 136,139 ****
--- 407,468 ----
}
+ void
+ write_historical_event(HistEvent *hevt)
+ {
+ int i;
+ char *descs;
+
+ /* Might be reasons not to write this event. */
+ if (hevt->startdate < 0)
+ return;
+ start_form(key(K_EVT));
+ add_num_to_form(hevt->startdate);
+ add_to_form(hevtdefns[hevt->type].name);
+ if (hevt->observers == ALLSIDES)
+ add_to_form(key(K_ALL));
+ else
+ add_num_to_form(hevt->observers);
+ descs = hevtdefns[hevt->type].datadescs;
+ for (i = 0; descs[i] != '\0'; ++i) {
+ switch (descs[i]) {
+ case 'm':
+ case 'n':
+ case 's':
+ case 'S':
+ case 'u':
+ case 'U':
+ case 'x':
+ case 'y':
+ add_num_to_form(hevt->data[i]);
+ break;
+ default:
+ run_warning("'%c' is not a recognized history data desc char",
+ descs[i]);
+ break;
+ }
+ }
+ end_form();
+ newline_form();
+ }
+
+ void
+ write_history(void)
+ {
+ PastUnit *pastunit;
+ HistEvent *hevt;
+
+ /* Write all the past units that might be mentioned in events. These
+ should already be sorted by id. */
+ for (pastunit = past_unit_list; pastunit != NULL; pastunit = pastunit->next)
+ write_past_unit(pastunit);
+ newline_form();
+ /* Now write all the events, doing the first one separately so as to
+ simplify testing for the end of the history list (which is circular). */
+ write_historical_event(history);
+ for (hevt = history->next; hevt != history; hevt = hevt->next)
+ write_historical_event(hevt);
+ newline_form();
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: module.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/module.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** module.cc 30 May 2006 02:51:07 -0000 1.3
--- module.cc 2 Jun 2006 16:57:43 -0000 1.4
***************
*** 6,10 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
Copyright (C) 2004-2006 Eric A. McDonald
--- 6,10 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1897-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
Copyright (C) 2004-2006 Eric A. McDonald
***************
*** 59,62 ****
--- 59,66 ----
Module *curmodule;
+ FILE *wfp;
+
+ Module *reshaper;
+
// Global Variables: Validation
***************
*** 73,76 ****
--- 77,85 ----
PackedBoolTable *G_advances_synopsis = NULL;
+ // Global Variables: Buffers
+
+ //! Buffer for shortest names.
+ char *shortestbuf;
+
// Local Variables
***************
*** 78,81 ****
--- 87,100 ----
static Module *mainmodule;
+ //! Module for capturing snapshot of game state.
+ /*!
+ A pre-allocated module used for when we're saving the game and may
+ not do any more allocation.
+ */
+ static Module *spare_module;
+
+ //! Name of spare module file.
+ static char *spare_file_name;
+
// Local Variables: Behavior Options
***************
*** 182,185 ****
--- 201,207 ----
static void end_conditional(Obj *form, Module *module);
+ //! Serialize variants to GDL.
+ static void write_variants(Variant *varray);
+
// Notifications
***************
*** 1810,1813 ****
--- 1832,2066 ----
}
+ void
+ init_write(void)
+ {
+ spare_module = create_game_module("spare module");
+ shortestbuf = (char *) xmalloc(BUFSIZE);
+ spare_file_name = (char *) xmalloc(PATH_SIZE);
+ }
+
+ static
+ void
+ write_variants(Variant *varray)
+ {
+ int i;
+ Obj *rest;
+ Variant *var;
+
+ for (i = 0; varray[i].id != lispnil; ++i) {
+ var = &(varray[i]);
+ space_form();
+ start_form("");
+ /* Write the variant's string name if different from symbol. */
+ if (!empty_string(var->name)
+ && !(symbolp(var->id)
+ && strcmp(var->name, c_string(var->id)) == 0)) {
+ add_to_form(escaped_string(var->name));
+ space_form();
+ }
+ add_form_to_form(var->id);
+ if (var->dflt != lispnil) {
+ space_form();
+ add_form_to_form(var->dflt);
+ }
+ for_all_list(var->cases, rest) {
+ space_form();
+ add_form_to_form(car(rest));
+ }
+ end_form();
+ }
+ }
+
+ int
+ reshape_the_output(Module *module)
+ {
+ return (module->maybe_reshape
+ && (module->subarea_width != area.width
+ || module->subarea_height != area.height
+ || module->subarea_x != 0
+ || module->subarea_y != 0
+ || module->final_subarea_width != area.width
+ || module->final_subarea_height != area.height
+ || module->final_subarea_x != 0
+ || module->final_subarea_y != 0
+ || module->final_width != area.width
+ || module->final_height != area.height
+ || module->final_circumference != world.circumference));
+ }
+
+ int
+ write_game_module(Module *module, char *fname)
+ {
+ if (module->filename == NULL && tmprid == 0) {
+ /* (should be an error?) */
+ return FALSE;
+ }
+ if (module->filename && fname) {
+ wfp = open_file(fname, "w");
+ } else {
+ wfp = NULL;
+ }
+ if (wfp != NULL || tmprid > 0) {
+ /* Write the definition of this game module. */
+ start_form(key(K_GAME_MODULE));
+ add_to_form(escaped_string(module->name));
+ newline_form();
+ space_form();
+ if (module->def_all) {
+ write_str_prop(key(K_TITLE), module->title,
+ "", FALSE, TRUE);
+ write_lisp_prop(key(K_BLURB), module->blurb,
+ lispnil, FALSE, FALSE, TRUE);
+ write_str_prop(key(K_PICTURE_NAME), module->picturename,
+ "", FALSE, TRUE);
+ write_str_prop(key(K_BASE_MODULE), module->basemodulename,
+ "", FALSE, TRUE);
+ write_str_prop(key(K_DEFAULT_BASE_MODULE), module->defaultbasemodulename,
+ "", FALSE, TRUE);
+ write_str_prop(key(K_BASE_GAME), module->basegame,
+ "", FALSE, TRUE);
+ write_str_prop(key(K_FILENAME), module->filename,
+ "", FALSE, TRUE);
+ write_str_prop(key(K_VERSION), module->version,
+ "", FALSE, TRUE);
+ if (module->variants) {
+ space_form();
+ start_form(key(K_VARIANTS));
+ write_variants(module->variants);
+ end_form();
+ newline_form();
+ }
+ write_str_prop(key(K_ORIGINAL_MODULE), module->origmodulename,
+ "", FALSE, TRUE);
+ if (module->origvariants) {
+ space_form();
+ start_form(key(K_ORIGINAL_VARIANTS));
+ write_variants(module->origvariants);
+ end_form();
+ newline_form();
+ }
+ }
+ space_form();
+ end_form();
+ newline_form();
+ newline_form();
+ if (module->def_all || module->def_types)
+ write_types();
+ if (module->def_all || module->def_tables)
+ write_tables(module->compress_tables);
+ if (module->def_all || module->def_globals)
+ write_globals();
+ if (module->def_all || module->def_scoring)
+ write_scorekeepers();
+ doreshape = reshape_the_output(module);
+ reshaper = module;
+ if (module->def_all || module->def_world)
+ write_world();
+ if (module->def_all || module->def_areas)
+ write_areas(module);
+ if (module->def_all || module->def_sides)
+ write_doctrines();
+ if (module->def_all || module->def_sides)
+ write_sides(module);
+ if (module->def_all || module->def_players)
+ write_players();
+ #if 0
+ if (module->def_all || module->def_agreements)
+ write_agreements();
+ #endif
+ if (module->def_all || module->def_units)
+ write_units(module);
+ if (module->def_all || module->def_history)
+ write_history();
+ if (module->def_all)
+ write_namers();
+ if (module->def_all)
+ write_images();
+ /* Write the game notes here (seems reasonable, no deeper reason). */
+ if (module->instructions != lispnil) {
+ start_form(key(K_GAME_MODULE));
+ space_form();
+ write_lisp_prop(key(K_INSTRUCTIONS), module->instructions,
+ lispnil, FALSE, FALSE, TRUE);
+ newline_form();
+ space_form();
+ space_form();
+ end_form();
+ newline_form();
+ newline_form();
+ }
+ if (module->notes != lispnil) {
+ start_form(key(K_GAME_MODULE));
+ space_form();
+ write_lisp_prop(key(K_NOTES), module->notes,
+ lispnil, FALSE, FALSE, TRUE);
+ newline_form();
+ space_form();
+ space_form();
+ end_form();
+ newline_form();
+ newline_form();
+ }
+ if (module->designnotes != lispnil) {
+ start_form(key(K_GAME_MODULE));
+ space_form();
+ write_lisp_prop(key(K_DESIGN_NOTES), module->designnotes,
+ lispnil, FALSE, FALSE, TRUE);
+ newline_form();
+ space_form();
+ space_form();
+ end_form();
+ newline_form();
+ newline_form();
+ }
+ if (wfp != NULL)
+ fclose(wfp);
+ else
+ flush_write();
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+
+ int
+ write_entire_game_state(char *fname)
+ {
+ Module *module;
+ int rslt;
+
+ /* Record the attempt to save state. Do it before actually saving,
+ so that it appears in the saved history. */
+ if (!memory_exhausted && !debugging_state_sync)
+ record_event(H_GAME_SAVED, ALLSIDES);
+ /* No additional allocation should ever happen during saving,
+ so complain if it does. */
+ xmalloc_warnings = TRUE;
+ module = spare_module;
+ copy_module(module, mainmodule);
+ module->name = mainmodule->name;
+ module->filename = find_name(fname);
+ module->version = NULL;
+ module->variants = NULL;
+ /* We write all types etc, so suppress base module load attempts. */
+ module->basemodulename = NULL;
+ module->defaultbasemodulename = NULL;
+ module->compress_tables = TRUE;
+ module->compress_layers = TRUE;
+ module->def_all = TRUE;
+ rslt = write_game_module(module, fname);
+ xmalloc_warnings = FALSE;
+ /* Record that the game's state is accurately saved away. */
+ if (rslt) {
+ gamestatesafe = TRUE;
+ if (!memory_exhausted && !debugging_state_sync) {
+ /* Report success to the users. We can't use notify_event
+ because we want to report the filename. */
+ notify_all("Game was saved to \"%s\".", fname);
+ }
+ }
+ return rslt;
+ }
+
#if (0) // Temp disable.
***************
*** 1890,1912 ****
}
- /* This is true if any actual reshaping is required. */
-
- int
- reshape_the_output(Module *module)
- {
- return (module->maybe_reshape
- && (module->subarea_width != area.width
- || module->subarea_height != area.height
- || module->subarea_x != 0
- || module->subarea_y != 0
- || module->final_subarea_width != area.width
- || module->final_subarea_height != area.height
- || module->final_subarea_x != 0
- || module->final_subarea_y != 0
- || module->final_width != area.width
- || module->final_height != area.height
- || module->final_circumference != world.circumference));
- }
-
/* Check if the proposed reshape will actually work. */
--- 2143,2146 ----
Index: tables.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/tables.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** tables.cc 28 May 2006 22:31:21 -0000 1.4
--- tables.cc 2 Jun 2006 16:57:43 -0000 1.5
***************
*** 6,12 ****
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2004-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
--- 6,12 ----
/*//////////////////////////// COPYRIGHT NOTICE ////////////////////////////////
! Copyright (C) 1987-1989 Stanley T. Shebs
Copyright (C) 1991-2000 Stanley T. Shebs
! Copyright (C) 2005-2006 Eric A. McDonald
//////////////////////////////////// LICENSE ///////////////////////////////////
***************
*** 90,93 ****
--- 90,98 ----
NAMESPACE_GDL_BEGIN
+ // Local Data Structures
+
+ //! Simple histogram struct - count and value, that's all.
+ struct histo { int count, val; };
+
// Globals
***************
*** 165,168 ****
--- 170,176 ----
Obj *indexes1, Obj *indexes2, Obj *values);
+ //! Sort predicate - *descending* order by count.
+ static int histo_compare(const void *x, const void *y);
+
// Table Accessors
***************
*** 489,492 ****
--- 497,764 ----
}
+ static
+ int
+ histo_compare(const void *x, const void *y)
+ {
+ return ((struct histo *) y)->count - ((struct histo *) x)->count;
+ }
+
+ #if (0)
+ void
+ write_type_value_list(
+ int typ, int *flags, int dim, int (*getter)(int, int), int i)
+ {
+ int j, first = TRUE, listlen = 0;
+
+ for (j = 0; j < dim; ++j)
+ if (flags == NULL || flags[j])
+ ++listlen;
+ if (listlen > 1)
+ start_form("");
+ for (j = 0; j < dim; ++j) {
+ if (flags == NULL || flags[j]) {
+ if (first)
+ first = FALSE;
+ else
+ space_form();
+ add_num_to_form_no_space((*getter)(i, j));
+ }
+ }
+ if (listlen > 1)
+ end_form();
+ }
+ #endif
+
+ void
+ write_table(char *name, int (*getter)(int, int), int dflt, int typ1, int typ2,
+ int valtype, int compress)
+ {
+ int i, j, k, colvalue, constcol, next;
+ int numrandoms, nextrowdiffers, writeconst;
+ int sawfirst, constrands, constval;
+ int dim1 = numtypes_from_index_type(typ1);
+ int dim2 = numtypes_from_index_type(typ2);
+ struct histo mostcommon[500]; /* more than max of num[utma]types */
+ int indexes1[500], randoms[500];
+
+ start_form(key(K_TABLE));
+ add_to_form(name);
+ add_to_form(" ;");
+ add_num_or_dice_to_form(dflt, valtype);
+ if (!compress) {
+ /* Write every value separately. */
+ for (i = 0; i < dim1; ++i) {
+ newline_form();
+ space_form();
+ space_form();
+ start_form(escaped_symbol(name_from_typ(typ1, i)));
+ add_to_form((char *)star_from_typ(typ2));
+ space_form();
+ start_form("");
+ for (j = 0; j < dim2; ++j) {
+ add_num_or_dice_to_form((*getter)(i, j), valtype);
+ }
+ end_form();
+ end_form();
+ }
+ } else if (dim1 <= dim2) {
+ /* Analyze the table by rows. */
+ for (k = 0; k < dim1; ++k)
+ indexes1[k] = FALSE;
+ for (i = 0; i < dim1; ++i) {
+ /* First see if this row has all the same values as the next. */
+ indexes1[i] = TRUE;
+ nextrowdiffers = FALSE;
+ if (i < dim1 - 1) {
+ for (j = 0; j < dim2; ++j) {
+ if ((*getter)(i, j) != (*getter)(i + 1, j)) {
+ nextrowdiffers = TRUE;
+ break;
+ }
+ }
+ } else {
+ /* The last row is *always* "different". */
+ nextrowdiffers = TRUE;
+ }
+ /* (should look at *all* rows to find matching rows before
+ dumping one) */
+ if (nextrowdiffers) {
+ /* Make a histogram of all the values in this row. */
+ mostcommon[0].count = 1;
+ mostcommon[0].val = (*getter)(i, 0);
+ next = 1;
+ for (j = 0; j < dim2; ++j) {
+ for (k = 0; k < next; ++k) {
+ if (mostcommon[k].val == (*getter)(i, j)) {
+ ++(mostcommon[k].count);
+ break;
+ }
+ }
+ if (k == next) {
+ mostcommon[next].count = 1;
+ mostcommon[next].val = (*getter)(i, j);
+ ++next;
+ }
+ }
+ if (next == 1 && mostcommon[0].val == dflt) {
+ /* Entire row(s) is/are just the default table value. */
+ } else {
+ writeconst = FALSE;
+ numrandoms = 0;
+ if (next == 1) {
+ /* Only one value in the row(s). */
+ writeconst = TRUE;
+ } else {
+ qsort(mostcommon, next, sizeof(struct histo),
+ histo_compare);
+ if (mostcommon[0].count >= (3 * dim2) / 4) {
+ /* The most common value in this row(s) is
+ not the only value, but it is worth
+ writing into a separate clause. */
+ writeconst = TRUE;
+ for (j = 0; j < dim2; ++j) {
+ /* Flag the other values as needing to be
+ written separately. */
+ randoms[j] =
+ (mostcommon[0].val != (*getter)(i, j));
+ if (randoms[j])
+ ++numrandoms;
+ }
+ } else {
+ /* Flag all in the row as randoms. */
+ for (j = 0; j < dim2; ++j) {
+ randoms[j] = TRUE;
+ ++numrandoms;
+ }
+ }
+ }
+ /* Write out the most common value (if
+ non-default) in the row(s), expressing it with
+ a clause that applies the value to the entire
+ row(s). */
+ if (writeconst && mostcommon[0].val != dflt) {
+ newline_form();
+ space_form();
+ space_form();
+ start_form("");
+ write_type_name_list(typ1, indexes1, dim1);
+ add_to_form((char *)star_from_typ(typ2));
+ add_num_or_dice_to_form(mostcommon[0].val, valtype);
+ end_form();
+ }
+ /* Now override the most common value with any
+ exceptions. */
+ if (numrandoms > 0) {
+ constrands = TRUE;
+ sawfirst = FALSE;
+ for (j = 0; j < dim2; ++j) {
+ if (randoms[j]) {
+ if (!sawfirst) {
+ constval = (*getter)(i, j);
+ sawfirst = TRUE;
+ }
+ if (sawfirst && constval != (*getter)(i, j)) {
+ constrands = FALSE;
+ break;
+ }
+ }
+ }
+ if (constrands) {
+ newline_form();
+ space_form();
+ space_form();
+ start_form("");
+ write_type_name_list(typ1, indexes1, dim1);
+ space_form();
+ write_type_name_list(typ2, randoms, dim2);
+ add_num_or_dice_to_form(constval, valtype);
+ end_form();
+ } else {
+ /* We have a group of rows with varying data
+ in the columns; write a separate row. */
+ for (j = 0; j < dim2; ++j) {
+ if (randoms[j]) {
+ newline_form();
+ space_form();
+ space_form();
+ start_form("");
+ write_type_name_list(typ1, indexes1, dim1);
+ add_to_form(escaped_symbol(name_from_typ(typ2, j)));
+ add_num_or_dice_to_form((*getter)(i, j), valtype);
+ end_form();
+ }
+ }
+ }
+ }
+ }
+ /* Reset the row flags in preparation for the next group
+ of rows whose contents match each other. */
+ for (k = 0; k < dim1; ++k)
+ indexes1[k] = FALSE;
+ }
+ }
+ } else {
+ /* Analyze the table by columns. */
+ /* Don't work as hard to optimize; this case should be uncommon,
+ since there are usually more types of units than
+ materials or terrain. */
+ for (j = 0; j < dim2; ++j) {
+ constcol = TRUE;
+ colvalue = (*getter)(0, j);
+ for (i = 0; i < dim1; ++i) {
+ if ((*getter)(i, j) != colvalue) {
+ constcol = FALSE;
+ break;
+ }
+ }
+ if (!constcol || colvalue != dflt) {
+ newline_form();
+ space_form();
+ space_form();
+ start_form((char *)star_from_typ(typ1));
+ add_to_form(escaped_symbol(name_from_typ(typ2, j)));
+ /* Write out either a single constant value or a list of
+ varying values, as appropriate. */
+ if (constcol) {
+ add_num_or_dice_to_form(colvalue, valtype);
+ } else {
+ space_form();
+ start_form("");
+ for (i = 0; i < dim1; ++i) {
+ add_num_or_dice_to_form((*getter)(i, j), valtype);
+ }
+ end_form();
+ }
+ end_form();
+ }
+ }
+ }
+ newline_form();
+ space_form();
+ space_form();
+ end_form();
+ newline_form();
+ }
+
+ void
+ write_tables(int compress)
+ {
+ int tbl;
+
+ newline_form();
+ for (tbl = 0; tabledefns[tbl].name != 0; ++tbl) {
+ /* Don't write out tables used internally only, unless debugging. */
+ if ((strncmp(tabledefns[tbl].name, "zz-", 3) == 0) && !Debug)
+ continue;
+ if (*(tabledefns[tbl].table) != NULL) {
+ write_table(tabledefns[tbl].name,
+ tabledefns[tbl].getter, tabledefns[tbl].dflt,
+ tabledefns[tbl].index1, tabledefns[tbl].index2,
+ tabledefns[tbl].valtype, compress);
+ newline_form();
+ }
+ }
+ }
+
NAMESPACE_GDL_END
NAMESPACE_XCONQ_END
Index: Makefile.am
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** Makefile.am 29 May 2006 20:11:12 -0000 1.8
--- Makefile.am 2 Jun 2006 16:57:43 -0000 1.9
***************
*** 11,18 ****
libconq_gdl_la_SOURCES += dir.cc namer.cc pact.cc history.cc
libconq_gdl_la_SOURCES += player.cc score.cc world.cc module.cc
- libconq_gdl_la_SOURCES += write.cc
! libconq_gdl_la_LIBADD = unit/libconq_gdl_media.la
libconq_gdl_la_LIBADD += unit/libconq_gdl_unit.la
libconq_gdl_la_LIBADD += side/libconq_gdl_side.la
! libconq_gdl_la_LIBADD += side/libconq_gdl_gamearea.la
--- 11,17 ----
libconq_gdl_la_SOURCES += dir.cc namer.cc pact.cc history.cc
libconq_gdl_la_SOURCES += player.cc score.cc world.cc module.cc
! libconq_gdl_la_LIBADD = media/libconq_gdl_media.la
libconq_gdl_la_LIBADD += unit/libconq_gdl_unit.la
libconq_gdl_la_LIBADD += side/libconq_gdl_side.la
! libconq_gdl_la_LIBADD += gamearea/libconq_gdl_gamearea.la
Index: score.cc
===================================================================
RCS file: /cvsroot/xconq/xconq/src/gdl/score.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** score.cc 28 May 2006 18:10:41 -0000 1.1
--- score.cc 2 Jun 2006 16:57:43 -0000 1.2
***************
*** 56,59 ****
--- 56,63 ----
Scorekeeper *scorekeepers;
int numscorekeepers;
+ int numscores;
+
+ int any_post_action_scores;
+ int any_post_event...
[truncated message content] |