Add properties to Frotz plugin
[projects/chimara/chimara.git] / interpreters / chimara-frotz-plugin.c
1 #include <glib-object.h>
2 #include <config.h>
3 #include <glib/gi18n-lib.h>
4 #include <gtk/gtk.h>
5 #include <libpeas/peas.h>
6 #include <libpeas-gtk/peas-gtk.h>
7 #include "chimara-frotz-plugin.h"
8 #include "frotz/frotz.h"
9
10 typedef struct _ChimaraFrotzPluginPrivate {
11         int random_seed;
12         gboolean random_seed_set;
13         gboolean tandy_bit;
14 } ChimaraFrotzPluginPrivate;
15
16 #define CHIMARA_FROTZ_PLUGIN_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_FROTZ_PLUGIN, ChimaraFrotzPluginPrivate))
17 #define CHIMARA_FROTZ_PLUGIN_USE_PRIVATE ChimaraFrotzPluginPrivate *priv = CHIMARA_FROTZ_PLUGIN_PRIVATE(self)
18
19
20 static void chimara_frotz_plugin_configurable_init(PeasGtkConfigurableInterface *);
21 static GtkWidget *chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurable *);
22
23 G_DEFINE_DYNAMIC_TYPE_EXTENDED(ChimaraFrotzPlugin, chimara_frotz_plugin, PEAS_TYPE_EXTENSION_BASE, 0,
24         G_IMPLEMENT_INTERFACE_DYNAMIC(PEAS_GTK_TYPE_CONFIGURABLE, chimara_frotz_plugin_configurable_init));
25
26 enum {
27         PROP_0,
28         PROP_DEBUG_MESSAGES,
29         PROP_IGNORE_ERRORS,
30         PROP_PIRACY_MODE,
31         PROP_QUETZAL_SAVE_FORMAT,
32         PROP_TANDY_BIT,
33         PROP_EXPAND_ABBREVIATIONS,
34         PROP_RANDOM_SEED,
35         PROP_RANDOM_SEED_SET,
36         PROP_TRANSCRIPT_COLUMNS,
37         PROP_UNDO_SLOTS
38 };
39
40 G_MODULE_EXPORT void
41 peas_register_types(PeasObjectModule *module)
42 {
43         chimara_frotz_plugin_register_type(G_TYPE_MODULE(module));
44         peas_object_module_register_extension_type(module, PEAS_GTK_TYPE_CONFIGURABLE, CHIMARA_TYPE_FROTZ_PLUGIN);
45 }
46
47 static void
48 chimara_frotz_plugin_init(ChimaraFrotzPlugin *self)
49 {
50         CHIMARA_FROTZ_PLUGIN_USE_PRIVATE;
51         priv->random_seed_set = FALSE;
52         priv->tandy_bit = FALSE;
53 }
54
55 #define PROCESS_FLAG(name) ((flags & (name))? 1 : 0)
56
57 static void
58 chimara_frotz_plugin_set_property(GObject *self, unsigned prop_id, const GValue *value, GParamSpec *pspec)
59 {
60         CHIMARA_FROTZ_PLUGIN_USE_PRIVATE;
61
62         switch(prop_id) {
63                 case PROP_DEBUG_MESSAGES:
64                 {
65                         unsigned flags = g_value_get_uint(value);
66                         option_attribute_assignment = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING);
67                         option_attribute_testing = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING);
68                         option_object_movement = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT);
69                         option_object_locating = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING);
70                         g_object_notify(self, "debug-messages");
71                         break;
72                 }
73                 case PROP_IGNORE_ERRORS:
74                         option_ignore_errors = g_value_get_boolean(value);
75                         g_object_notify(self, "ignore-errors");
76                         break;
77                 case PROP_PIRACY_MODE:
78                         option_piracy = g_value_get_boolean(value);
79                         g_object_notify(self, "piracy-mode");
80                         break;
81                 case PROP_QUETZAL_SAVE_FORMAT:
82                         option_save_quetzal = g_value_get_boolean(value);
83                         g_object_notify(self, "quetzal-save-format");
84                         break;
85                 case PROP_TANDY_BIT:
86                         priv->tandy_bit = g_value_get_boolean(value);
87                         g_object_notify(self, "tandy-bit");
88                         break;
89                 case PROP_EXPAND_ABBREVIATIONS:
90                         option_expand_abbreviations = g_value_get_boolean(value);
91                         g_object_notify(self, "expand-abbreviations");
92                         break;
93                 case PROP_RANDOM_SEED:
94                         priv->random_seed = g_value_get_int(value);
95                         g_object_notify(self, "random-seed");
96                         break;
97                 case PROP_RANDOM_SEED_SET:
98                         priv->random_seed_set = g_value_get_boolean(value);
99                         g_object_notify(self, "random-seed-set");
100                         break;
101                 case PROP_TRANSCRIPT_COLUMNS:
102                         option_script_cols = g_value_get_uint(value);
103                         g_object_notify(self, "transcript-columns");
104                         break;
105                 case PROP_UNDO_SLOTS:
106                         option_undo_slots = g_value_get_uint(value);
107                         g_object_notify(self, "undo-slots");
108                         break;
109                 default:
110                         G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec);
111         }
112 }
113
114 #undef PROCESS_FLAG
115
116 static void
117 chimara_frotz_plugin_get_property(GObject *self, unsigned prop_id, GValue *value, GParamSpec *pspec)
118 {
119         CHIMARA_FROTZ_PLUGIN_USE_PRIVATE;
120
121         switch(prop_id) {
122                 case PROP_DEBUG_MESSAGES:
123                 {
124                         unsigned flags = option_attribute_assignment << 0
125                                 | option_attribute_testing << 1
126                                 | option_object_movement << 2
127                                 | option_object_locating << 3;
128                         g_value_set_uint(value, flags);
129                         break;
130                 }
131                 case PROP_IGNORE_ERRORS:
132                         g_value_set_boolean(value, option_ignore_errors);
133                         break;
134                 case PROP_PIRACY_MODE:
135                         g_value_set_boolean(value, option_piracy);
136                         break;
137                 case PROP_QUETZAL_SAVE_FORMAT:
138                         g_value_set_boolean(value, option_save_quetzal);
139                         break;
140                 case PROP_TANDY_BIT:
141                         g_value_set_boolean(value, priv->tandy_bit);
142                         break;
143                 case PROP_EXPAND_ABBREVIATIONS:
144                         g_value_set_boolean(value, option_expand_abbreviations);
145                         break;
146                 case PROP_RANDOM_SEED:
147                         g_value_set_int(value, priv->random_seed);
148                         break;
149                 case PROP_RANDOM_SEED_SET:
150                         g_value_set_boolean(value, priv->random_seed_set);
151                         break;
152                 case PROP_TRANSCRIPT_COLUMNS:
153                         g_value_set_uint(value, option_script_cols);
154                         break;
155                 case PROP_UNDO_SLOTS:
156                         g_value_set_uint(value, option_undo_slots);
157                         break;
158                 default:
159                         G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec);
160         }
161 }
162
163 static void
164 chimara_frotz_plugin_class_init(ChimaraFrotzPluginClass *klass)
165 {
166         GObjectClass *object_class = G_OBJECT_CLASS(klass);
167         object_class->set_property = chimara_frotz_plugin_set_property;
168         object_class->get_property = chimara_frotz_plugin_get_property;
169
170         /* Private data */
171         g_type_class_add_private(klass, sizeof(ChimaraFrotzPluginPrivate));
172
173         /* Properties */
174         /**
175          * ChimaraFrotzPlugin:debug-messages:
176          *
177          * Set of flags to control which debugging messages, if any, Frotz prints
178          * while interpreting the story. See #ChimaraFrotzDebugFlags.
179          */
180         /* TODO: register a flags type and use g_param_spec_flags() */
181         g_object_class_install_property(object_class, PROP_DEBUG_MESSAGES,
182                 g_param_spec_uint("debug-messages", _("Kinds of debugging messages"),
183                         _("Control which kinds of debugging messages to print"),
184                         0, 255, CHIMARA_FROTZ_DEBUG_NONE,
185                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
186         /**
187          * ChimaraFrotzPlugin:ignore-errors:
188          *
189          * Setting this property to %TRUE will cause the interpreter to ignore
190          * fatal Z-machine runtime errors.
191          */
192         g_object_class_install_property(object_class, PROP_IGNORE_ERRORS,
193                 g_param_spec_boolean("ignore-errors", _("Ignore errors"),
194                 _("Do not warn the user about fatal Z-machine errors"), FALSE,
195                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
196         /**
197          * ChimaraFrotzPlugin:piracy-mode:
198          *
199          * The Z-machine specification defines a facility for games to ask the
200          * interpreter they are running on whether this copy of the game is pirated.
201          * How the interpreter is supposed to magically determine that it is running
202          * pirate software is unclear, and so the majority of games and interpreters
203          * ignore this feature. Set this property to %TRUE if you want the
204          * interpreter to pretend it has detected a pirated game.
205          */
206         g_object_class_install_property(object_class, PROP_PIRACY_MODE,
207                 g_param_spec_boolean("piracy-mode", _("Piracy mode"),
208                 _("Pretend the game is pirated"), FALSE,
209                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
210         /**
211          * ChimaraFrotzPlugin:quetzal-save-format:
212          *
213          * If set to %TRUE, use the newer-style Quetzal format for saved games.
214          * (This is the default.)
215          */
216         g_object_class_install_property(object_class, PROP_QUETZAL_SAVE_FORMAT,
217                 g_param_spec_boolean("quetzal-save-format", _("Use Quetzal save format"),
218                         _("Use the Quetzal format for saved games"), TRUE,
219                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
220         /**
221          * ChimaraFrotzPlugin:tandy-bit:
222          *
223          * Some early Infocom games were sold by the Tandy Corporation. Setting this
224          * property to %TRUE changes the wording of some Version 3 Infocom games
225          * slightly, so as to be less offensive. See <ulink
226          * url="http://www.ifarchive.org/if-archive/infocom/info/tandy_bits.html">
227          * http://www.ifarchive.org/if-archive/infocom/info/tandy_bits.html</ulink>.
228          *
229          * Only affects Z-machine interpreters.
230          */
231         g_object_class_install_property(object_class, PROP_TANDY_BIT,
232                 g_param_spec_boolean("tandy-bit", _("Tandy bit"),
233                 _("Censor certain Infocom games"), FALSE,
234                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
235         /**
236          * ChimaraIF:expand-abbreviations:
237          *
238          * Most Z-machine games, in particular ones compiled with the Inform
239          * library, support the following one-letter abbreviations:
240          * <simplelist>
241          * <member>D &mdash; Down</member>
242          * <member>E &mdash; East</member>
243          * <member>G &mdash; aGain</member>
244          * <member>I &mdash; Inventory</member>
245          * <member>L &mdash; Look</member>
246          * <member>N &mdash; North</member>
247          * <member>O &mdash; Oops</member>
248          * <member>Q &mdash; Quit</member>
249          * <member>S &mdash; South</member>
250          * <member>U &mdash; Up</member>
251          * <member>W &mdash; West</member>
252          * <member>X &mdash; eXamine</member>
253          * <member>Y &mdash; Yes</member>
254          * <member>Z &mdash; wait (ZZZZ...)</member>
255          * </simplelist>
256          * Some early Infocom games might not recognize these abbreviations.
257          * However, Frotz can expand G, X, and Z regardless of what the game
258          * recognizes. Setting this property to %TRUE will cause Frotz to expand
259          * these abbreviations to the full words before passing the commands on to
260          * the game.
261          */
262         g_object_class_install_property(object_class, PROP_EXPAND_ABBREVIATIONS,
263                 g_param_spec_boolean("expand-abbreviations", _("Expand abbreviations"),
264                 _("Expand abbreviations such as X for EXAMINE"), FALSE,
265                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
266         /**
267          * ChimaraFrotzPlugin:random-seed:
268          *
269          * If the #ChimaraFrotzPlugin:random-seed-set property is %TRUE, then the
270          * interpreter will use the value of this property as a seed for the random
271          * number generator. Use this feature to duplicate sequences of random
272          * numbers for testing games.
273          *
274          * Note that the value -1 will cause Frotz to pick an arbitrary seed even
275          * when #ChimaraFrotzPlugin:random-seed-set is %TRUE.
276          */
277         g_object_class_install_property(object_class, PROP_RANDOM_SEED,
278                 g_param_spec_int("random-seed", _("Random seed"),
279                 _("Seed for the random number generator"), G_MININT, G_MAXINT, 0,
280                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
281         /**
282          * ChimaraFrotzPlugin:random-seed-set:
283          *
284          * Whether to use or ignore the #ChimaraFrotzPlugin:random-seed property.
285          */
286         g_object_class_install_property(object_class, PROP_RANDOM_SEED_SET,
287                 g_param_spec_boolean("random-seed-set", _("Random seed set"),
288                 _("Whether the seed for the random number generator should be set manually"), FALSE,
289                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
290         /**
291          * ChimaraFrotzPlugin:transcript-columns:
292          *
293          * How many columns to make the transcript output.
294          */
295         g_object_class_install_property(object_class, PROP_TRANSCRIPT_COLUMNS,
296                 g_param_spec_uint("transcript-columns", _("Transcript columns"),
297                         _("Number of columns for transcript output"),
298                         0, G_MAXUINT, 80,
299                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
300         /**
301          * ChimaraFrotzPlugin:undo-slots:
302          *
303          * How many slots to reserve for multiple Undo commands.
304          */
305         g_object_class_install_property(object_class, PROP_UNDO_SLOTS,
306                 g_param_spec_uint("undo-slots", _("Undo slots"),
307                         _("Number of slots to reserve for multiple undo"),
308                         0, MAX_UNDO_SLOTS, MAX_UNDO_SLOTS,
309                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS));
310 }
311
312 static void
313 chimara_frotz_plugin_class_finalize(ChimaraFrotzPluginClass *klass)
314 {
315 }
316
317 static void
318 chimara_frotz_plugin_configurable_init(PeasGtkConfigurableInterface *iface)
319 {
320         iface->create_configure_widget = chimara_frotz_plugin_create_configure_widget;
321 }
322
323 static GtkWidget *
324 chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurable *self)
325 {
326         return gtk_label_new("Configure Widget");
327 }