From 9543f384fef0a1ceaa719c910e02fac80624c437 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 6 Oct 2012 12:04:51 -0700 Subject: [PATCH] Add properties to Frotz plugin --- interpreters/chimara-frotz-plugin.c | 282 ++++++++++++++++++++++++++++ interpreters/chimara-frotz-plugin.h | 23 +++ 2 files changed, 305 insertions(+) diff --git a/interpreters/chimara-frotz-plugin.c b/interpreters/chimara-frotz-plugin.c index 527d547..705b12c 100644 --- a/interpreters/chimara-frotz-plugin.c +++ b/interpreters/chimara-frotz-plugin.c @@ -1,8 +1,21 @@ #include +#include +#include #include #include #include #include "chimara-frotz-plugin.h" +#include "frotz/frotz.h" + +typedef struct _ChimaraFrotzPluginPrivate { + int random_seed; + gboolean random_seed_set; + gboolean tandy_bit; +} ChimaraFrotzPluginPrivate; + +#define CHIMARA_FROTZ_PLUGIN_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_FROTZ_PLUGIN, ChimaraFrotzPluginPrivate)) +#define CHIMARA_FROTZ_PLUGIN_USE_PRIVATE ChimaraFrotzPluginPrivate *priv = CHIMARA_FROTZ_PLUGIN_PRIVATE(self) + static void chimara_frotz_plugin_configurable_init(PeasGtkConfigurableInterface *); static GtkWidget *chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurable *); @@ -10,6 +23,20 @@ static GtkWidget *chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurab G_DEFINE_DYNAMIC_TYPE_EXTENDED(ChimaraFrotzPlugin, chimara_frotz_plugin, PEAS_TYPE_EXTENSION_BASE, 0, G_IMPLEMENT_INTERFACE_DYNAMIC(PEAS_GTK_TYPE_CONFIGURABLE, chimara_frotz_plugin_configurable_init)); +enum { + PROP_0, + PROP_DEBUG_MESSAGES, + PROP_IGNORE_ERRORS, + PROP_PIRACY_MODE, + PROP_QUETZAL_SAVE_FORMAT, + PROP_TANDY_BIT, + PROP_EXPAND_ABBREVIATIONS, + PROP_RANDOM_SEED, + PROP_RANDOM_SEED_SET, + PROP_TRANSCRIPT_COLUMNS, + PROP_UNDO_SLOTS +}; + G_MODULE_EXPORT void peas_register_types(PeasObjectModule *module) { @@ -20,11 +47,266 @@ peas_register_types(PeasObjectModule *module) static void chimara_frotz_plugin_init(ChimaraFrotzPlugin *self) { + CHIMARA_FROTZ_PLUGIN_USE_PRIVATE; + priv->random_seed_set = FALSE; + priv->tandy_bit = FALSE; +} + +#define PROCESS_FLAG(name) ((flags & (name))? 1 : 0) + +static void +chimara_frotz_plugin_set_property(GObject *self, unsigned prop_id, const GValue *value, GParamSpec *pspec) +{ + CHIMARA_FROTZ_PLUGIN_USE_PRIVATE; + + switch(prop_id) { + case PROP_DEBUG_MESSAGES: + { + unsigned flags = g_value_get_uint(value); + option_attribute_assignment = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING); + option_attribute_testing = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING); + option_object_movement = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT); + option_object_locating = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING); + g_object_notify(self, "debug-messages"); + break; + } + case PROP_IGNORE_ERRORS: + option_ignore_errors = g_value_get_boolean(value); + g_object_notify(self, "ignore-errors"); + break; + case PROP_PIRACY_MODE: + option_piracy = g_value_get_boolean(value); + g_object_notify(self, "piracy-mode"); + break; + case PROP_QUETZAL_SAVE_FORMAT: + option_save_quetzal = g_value_get_boolean(value); + g_object_notify(self, "quetzal-save-format"); + break; + case PROP_TANDY_BIT: + priv->tandy_bit = g_value_get_boolean(value); + g_object_notify(self, "tandy-bit"); + break; + case PROP_EXPAND_ABBREVIATIONS: + option_expand_abbreviations = g_value_get_boolean(value); + g_object_notify(self, "expand-abbreviations"); + break; + case PROP_RANDOM_SEED: + priv->random_seed = g_value_get_int(value); + g_object_notify(self, "random-seed"); + break; + case PROP_RANDOM_SEED_SET: + priv->random_seed_set = g_value_get_boolean(value); + g_object_notify(self, "random-seed-set"); + break; + case PROP_TRANSCRIPT_COLUMNS: + option_script_cols = g_value_get_uint(value); + g_object_notify(self, "transcript-columns"); + break; + case PROP_UNDO_SLOTS: + option_undo_slots = g_value_get_uint(value); + g_object_notify(self, "undo-slots"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); + } +} + +#undef PROCESS_FLAG + +static void +chimara_frotz_plugin_get_property(GObject *self, unsigned prop_id, GValue *value, GParamSpec *pspec) +{ + CHIMARA_FROTZ_PLUGIN_USE_PRIVATE; + + switch(prop_id) { + case PROP_DEBUG_MESSAGES: + { + unsigned flags = option_attribute_assignment << 0 + | option_attribute_testing << 1 + | option_object_movement << 2 + | option_object_locating << 3; + g_value_set_uint(value, flags); + break; + } + case PROP_IGNORE_ERRORS: + g_value_set_boolean(value, option_ignore_errors); + break; + case PROP_PIRACY_MODE: + g_value_set_boolean(value, option_piracy); + break; + case PROP_QUETZAL_SAVE_FORMAT: + g_value_set_boolean(value, option_save_quetzal); + break; + case PROP_TANDY_BIT: + g_value_set_boolean(value, priv->tandy_bit); + break; + case PROP_EXPAND_ABBREVIATIONS: + g_value_set_boolean(value, option_expand_abbreviations); + break; + case PROP_RANDOM_SEED: + g_value_set_int(value, priv->random_seed); + break; + case PROP_RANDOM_SEED_SET: + g_value_set_boolean(value, priv->random_seed_set); + break; + case PROP_TRANSCRIPT_COLUMNS: + g_value_set_uint(value, option_script_cols); + break; + case PROP_UNDO_SLOTS: + g_value_set_uint(value, option_undo_slots); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); + } } static void chimara_frotz_plugin_class_init(ChimaraFrotzPluginClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->set_property = chimara_frotz_plugin_set_property; + object_class->get_property = chimara_frotz_plugin_get_property; + + /* Private data */ + g_type_class_add_private(klass, sizeof(ChimaraFrotzPluginPrivate)); + + /* Properties */ + /** + * ChimaraFrotzPlugin:debug-messages: + * + * Set of flags to control which debugging messages, if any, Frotz prints + * while interpreting the story. See #ChimaraFrotzDebugFlags. + */ + /* TODO: register a flags type and use g_param_spec_flags() */ + g_object_class_install_property(object_class, PROP_DEBUG_MESSAGES, + g_param_spec_uint("debug-messages", _("Kinds of debugging messages"), + _("Control which kinds of debugging messages to print"), + 0, 255, CHIMARA_FROTZ_DEBUG_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:ignore-errors: + * + * Setting this property to %TRUE will cause the interpreter to ignore + * fatal Z-machine runtime errors. + */ + g_object_class_install_property(object_class, PROP_IGNORE_ERRORS, + g_param_spec_boolean("ignore-errors", _("Ignore errors"), + _("Do not warn the user about fatal Z-machine errors"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:piracy-mode: + * + * The Z-machine specification defines a facility for games to ask the + * interpreter they are running on whether this copy of the game is pirated. + * How the interpreter is supposed to magically determine that it is running + * pirate software is unclear, and so the majority of games and interpreters + * ignore this feature. Set this property to %TRUE if you want the + * interpreter to pretend it has detected a pirated game. + */ + g_object_class_install_property(object_class, PROP_PIRACY_MODE, + g_param_spec_boolean("piracy-mode", _("Piracy mode"), + _("Pretend the game is pirated"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:quetzal-save-format: + * + * If set to %TRUE, use the newer-style Quetzal format for saved games. + * (This is the default.) + */ + g_object_class_install_property(object_class, PROP_QUETZAL_SAVE_FORMAT, + g_param_spec_boolean("quetzal-save-format", _("Use Quetzal save format"), + _("Use the Quetzal format for saved games"), TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:tandy-bit: + * + * Some early Infocom games were sold by the Tandy Corporation. Setting this + * property to %TRUE changes the wording of some Version 3 Infocom games + * slightly, so as to be less offensive. See + * http://www.ifarchive.org/if-archive/infocom/info/tandy_bits.html. + * + * Only affects Z-machine interpreters. + */ + g_object_class_install_property(object_class, PROP_TANDY_BIT, + g_param_spec_boolean("tandy-bit", _("Tandy bit"), + _("Censor certain Infocom games"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraIF:expand-abbreviations: + * + * Most Z-machine games, in particular ones compiled with the Inform + * library, support the following one-letter abbreviations: + * + * D — Down + * E — East + * G — aGain + * I — Inventory + * L — Look + * N — North + * O — Oops + * Q — Quit + * S — South + * U — Up + * W — West + * X — eXamine + * Y — Yes + * Z — wait (ZZZZ...) + * + * Some early Infocom games might not recognize these abbreviations. + * However, Frotz can expand G, X, and Z regardless of what the game + * recognizes. Setting this property to %TRUE will cause Frotz to expand + * these abbreviations to the full words before passing the commands on to + * the game. + */ + g_object_class_install_property(object_class, PROP_EXPAND_ABBREVIATIONS, + g_param_spec_boolean("expand-abbreviations", _("Expand abbreviations"), + _("Expand abbreviations such as X for EXAMINE"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:random-seed: + * + * If the #ChimaraFrotzPlugin:random-seed-set property is %TRUE, then the + * interpreter will use the value of this property as a seed for the random + * number generator. Use this feature to duplicate sequences of random + * numbers for testing games. + * + * Note that the value -1 will cause Frotz to pick an arbitrary seed even + * when #ChimaraFrotzPlugin:random-seed-set is %TRUE. + */ + g_object_class_install_property(object_class, PROP_RANDOM_SEED, + g_param_spec_int("random-seed", _("Random seed"), + _("Seed for the random number generator"), G_MININT, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:random-seed-set: + * + * Whether to use or ignore the #ChimaraFrotzPlugin:random-seed property. + */ + g_object_class_install_property(object_class, PROP_RANDOM_SEED_SET, + g_param_spec_boolean("random-seed-set", _("Random seed set"), + _("Whether the seed for the random number generator should be set manually"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:transcript-columns: + * + * How many columns to make the transcript output. + */ + g_object_class_install_property(object_class, PROP_TRANSCRIPT_COLUMNS, + g_param_spec_uint("transcript-columns", _("Transcript columns"), + _("Number of columns for transcript output"), + 0, G_MAXUINT, 80, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + /** + * ChimaraFrotzPlugin:undo-slots: + * + * How many slots to reserve for multiple Undo commands. + */ + g_object_class_install_property(object_class, PROP_UNDO_SLOTS, + g_param_spec_uint("undo-slots", _("Undo slots"), + _("Number of slots to reserve for multiple undo"), + 0, MAX_UNDO_SLOTS, MAX_UNDO_SLOTS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); } static void diff --git a/interpreters/chimara-frotz-plugin.h b/interpreters/chimara-frotz-plugin.h index a3eeba2..ee9ee12 100644 --- a/interpreters/chimara-frotz-plugin.h +++ b/interpreters/chimara-frotz-plugin.h @@ -24,6 +24,29 @@ struct _ChimaraFrotzPluginClass { PeasExtensionBaseClass parent_class; }; +/** + * ChimaraFrotzDebugFlags: + * @CHIMARA_FROTZ_DEBUG_NONE: No debugging messages + * @CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING: Print a debug message whenever a + * Z-machine object attribute is set or cleared. + * @CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING: Print a debug message whenever a + * Z-machine object attribute is tested. + * @CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT: Print a debug message whenever a + * Z-machine object is inserted into or removed from another object. + * @CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING: Print a debug message whenever the + * location of a Z-machine object is checked. + * + * Controls what debugging messages Frotz should print. See the + * :debug-messages property. + */ +typedef enum { + CHIMARA_FROTZ_DEBUG_NONE = 0, + CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING = 1 << 0, + CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING = 1 << 1, + CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT = 1 << 2, + CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING = 1 << 3, +} ChimaraFrotzDebugFlags; + GType chimara_frotz_plugin_get_type(void) G_GNUC_CONST; G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); -- 2.30.2