Added chimara_if_run() which, given a game file, autodetects the type by its extensio...
authorfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Tue, 13 Oct 2009 22:49:10 +0000 (22:49 +0000)
committerfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Tue, 13 Oct 2009 22:49:10 +0000 (22:49 +0000)
configure.ac
interpreters/frotz/Makefile.am
interpreters/git/Makefile.am
interpreters/glulxe/Makefile.am
interpreters/nitfol/Makefile.am
libchimara/Makefile.am
libchimara/chimara-glk.c
libchimara/chimara-glk.h
libchimara/chimara-if.c
libchimara/chimara-if.h
tests/main.c

index 51a5cf2d215e65c4cf011cb6876a0bc866be4975..17185929430b8600ab1759389e18d5d4129e949e 100644 (file)
@@ -26,8 +26,8 @@ AC_SUBST(LT_VERSION_INFO)
 
 ### DECLARE COMPILERS #########################################################
 
-AC_PROG_CC                   # C compiler
 AC_USE_SYSTEM_EXTENSIONS     # Define _GNU_SOURCE if using GCC
+AC_PROG_CC                   # C compiler
 AM_PROG_CC_C_O               # Automake requires this for per-target CFLAGS
 AC_C_INLINE                  # Define inline keyword 
 AC_PROG_YACC                 # Building nitfol requires yacc
@@ -87,6 +87,12 @@ PKG_CHECK_MODULES([TEST], [
        gmodule-2.0
 ])
 
+# Plugin flags; include '-module' in each Makefile.am, because AC_SUBSTed
+# variables are black boxes to Automake, so it has to know about it being a
+# module in the makefile itself.
+PLUGIN_LIBTOOL_FLAGS='-avoid-version -shared -export-symbols-regex "^glk"'
+AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
+
 ### OUTPUT ####################################################################
 
 # Output platform-specific definitions to config.h
index 02d88efc188bee624f3428f5cb71704cdd4565b4..f1a010026927ac8979744e044b5c024bee8b11a7 100644 (file)
@@ -1,12 +1,10 @@
-PLUGIN_LIBTOOL_FLAGS=-module -avoid-version -export-symbols-regex "^glk"
-
 pkglib_LTLIBRARIES = frotz.la
 frotz_la_SOURCES = buffer.c err.c fastmem.c files.c input.c main.c math.c \
        object.c process.c quetzal.c random.c redirect.c sound.c stream.c table.c \
        text.c variable.c glkscreen.c glkmisc.c frotz.h glkfrotz.h glkio.h setup.h
 frotz_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libchimara
 frotz_la_CFLAGS = -Wno-pointer-sign $(AM_CFLAGS)
-frotz_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+frotz_la_LDFLAGS = -module $(PLUGIN_LIBTOOL_FLAGS)
 
 frotzdocdir = $(datadir)/doc/$(PACKAGE)/frotz
 dist_frotzdoc_DATA = AUTHORS COPYING README TODO
index 051eeb35c2fd79cb3bdfcbf3130e5710dc8f01ef..ac41315f2374e90b5ada28b04553f7c298014878 100644 (file)
@@ -1,5 +1,3 @@
-PLUGIN_LIBTOOL_FLAGS=-module -avoid-version -export-symbols-regex "^glk"
-
 # Automatically generate version.h
 MAJOR = 1
 MINOR = 2
@@ -18,7 +16,7 @@ git_la_SOURCES = version.h git.h config.h compiler.h memory.h opcodes.h \
     accel.c
 git_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libchimara
 git_la_CFLAGS = -DCHIMARA_EXTENSIONS -DUSE_INLINE $(AM_CFLAGS)
-git_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+git_la_LDFLAGS = -module $(PLUGIN_LIBTOOL_FLAGS)
 
 gitdocdir = $(datadir)/doc/$(PACKAGE)/git
 dist_gitdoc_DATA = README.txt
index eb2b661796bb92a9263017e3a2eb96fffe5cbe8c..8c36f6af0fcdabc236d0835d422ec93a3989ccaf 100644 (file)
@@ -1,5 +1,3 @@
-PLUGIN_LIBTOOL_FLAGS=-module -avoid-version -export-symbols-regex "^glk"
-
 pkglib_LTLIBRARIES = glulxe.la
 glulxe_la_SOURCES = accel.c exec.c files.c funcs.c gestalt.c gestalt.h glkop.c \
     glulxe.h heap.c main.c opcodes.h operand.c osdepend.c profile.c search.c \
@@ -7,7 +5,7 @@ glulxe_la_SOURCES = accel.c exec.c files.c funcs.c gestalt.c gestalt.h glkop.c \
 glulxe_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libchimara
 glulxe_la_CFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused \
     -DOS_UNIX $(AM_CFLAGS)
-glulxe_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+glulxe_la_LDFLAGS = -module $(PLUGIN_LIBTOOL_FLAGS)
 
 glulxedocdir = $(datadir)/doc/$(PACKAGE)/glulxe
 dist_glulxedoc_DATA = README
index ccb415ab3cb255cdde0601bb9fb0ca51546620dd..c1031b1203183f007c78aded9296dd9e246fcef7 100644 (file)
@@ -1,5 +1,3 @@
-PLUGIN_LIBTOOL_FLAGS=-module -avoid-version -export-symbols-regex "^glk"
-
 GRAPHICS = no_graph.c no_graph.h
 # GRAPHICS = graphics.c graphics.h
 BLORB = blorb.c 
@@ -25,7 +23,7 @@ nitfol_la_SOURCES = automap.c automap.h binary.h copying.h debug.c debug.h \
 nodist_nitfol_la_SOURCES = copying.c dbg_help.h startunix.c
 nitfol_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libchimara \
        -DSMART_TOKENISER -DUSE_INLINE
-nitfol_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+nitfol_la_LDFLAGS = -module $(PLUGIN_LIBTOOL_FLAGS)
 
 info_TEXINFOS = nitfol.texi
 nitfol_TEXINFOS = dbg_help.texi options.texi
index dd205572ef70029867e2ea653d3dff0cb7ee5c07..b7a79e3709791163304a1e813b2f5f8ef6292470 100644 (file)
@@ -37,15 +37,17 @@ libchimara_la_SOURCES = \
 libchimara_la_CPPFLAGS = \
        -DG_LOG_DOMAIN=\"Chimara\" \
        -DLOCALEDIR=\""$(datadir)/locale"\" \
+       -DPLUGINDIR=\""$(pkglibdir)"\" \
        -I$(top_srcdir)
 libchimara_la_CFLAGS = @CHIMARA_CFLAGS@ $(AM_CFLAGS)
 libchimara_la_LIBADD = @CHIMARA_LIBS@
 libchimara_la_LDFLAGS = -version-info $(LT_VERSION_INFO) \
        -no-undefined \
-       -export-symbols-regex "^(glk|chimara_glk|glkunix|giblorb|gidispatch|garglk)_"
+       -export-symbols-regex "^(glk|chimara|glkunix|giblorb|gidispatch|garglk)_"
 libchimara_includedir = $(includedir)/chimara/libchimara
 libchimara_include_HEADERS = \
        chimara-glk.h \
+       chimara-if.h \
        glk.h \
        glkstart.h \
        gi_blorb.h \
index da4419306b38f9539c42d2baca221086b44fc0c2..40fddfe048734569564166c8025d6633c9c7fc4a 100644 (file)
@@ -87,14 +87,14 @@ chimara_glk_init(ChimaraGlk *self)
        priv->default_styles = g_hash_table_new(g_str_hash, g_str_equal);
     priv->program = NULL;
     priv->thread = NULL;
-    priv->event_queue = NULL;
-    priv->event_lock = NULL;
-    priv->event_queue_not_empty = NULL;
-    priv->event_queue_not_full = NULL;
-    priv->abort_lock = NULL;
+    priv->event_queue = g_queue_new();
+    priv->event_lock = g_mutex_new();
+    priv->event_queue_not_empty = g_cond_new();
+    priv->event_queue_not_full = g_cond_new();
+    priv->abort_lock = g_mutex_new();
     priv->abort_signalled = FALSE;
-       priv->arrange_lock = NULL;
-       priv->rearranged = NULL;
+       priv->arrange_lock = g_mutex_new();
+       priv->rearranged = g_cond_new();
        priv->needs_rearrange = FALSE;
        priv->ignore_next_arrange_event = FALSE;
     priv->interrupt_handler = NULL;
@@ -547,31 +547,31 @@ chimara_glk_stopped(ChimaraGlk *self)
 static void
 chimara_glk_started(ChimaraGlk *self)
 {
-       /* TODO: Add default signal handler implementation here */
+       /* Default signal handler */
 }
 
 static void
 chimara_glk_waiting(ChimaraGlk *self)
 {
-       /* TODO: Add default signal handler */
+       /* Default signal handler */
 }
 
 static void
 chimara_glk_char_input(ChimaraGlk *self, guint window_rock, guint keysym)
 {
-       /* TODO: Add default signal handler */
+       /* Default signal handler */
 }
 
 static void
 chimara_glk_line_input(ChimaraGlk *self, guint window_rock, gchar *text)
 {
-       /* TODO: Add default signal handler */
+       /* Default signal handler */
 }
 
 static void
 chimara_glk_text_buffer_output(ChimaraGlk *self, guint window_rock, gchar *text)
 {
-       /* TODO: Add default signal handler */
+       /* Default signal handler */
 }
 
 /* G_PARAM_STATIC_STRINGS only appeared in GTK 2.13.0 */
@@ -738,18 +738,7 @@ chimara_glk_new(void)
        /* This is a library entry point; initialize the library */
        chimara_init();
 
-    ChimaraGlk *self = CHIMARA_GLK(g_object_new(CHIMARA_TYPE_GLK, NULL));
-    ChimaraGlkPrivate *priv = CHIMARA_GLK_PRIVATE(self);
-    
-    priv->event_queue = g_queue_new();
-    priv->event_lock = g_mutex_new();
-    priv->event_queue_not_empty = g_cond_new();
-    priv->event_queue_not_full = g_cond_new();
-    priv->abort_lock = g_mutex_new();
-       priv->arrange_lock = g_mutex_new();
-       priv->rearranged = g_cond_new();
-
-    return GTK_WIDGET(self);
+    return GTK_WIDGET(g_object_new(CHIMARA_TYPE_GLK, NULL));
 }
 
 /**
@@ -1048,7 +1037,7 @@ glk_enter(struct StartupData *startup)
  * Return value: %TRUE if the Glk program was started successfully.
  */
 gboolean
-chimara_glk_run(ChimaraGlk *glk, gchar *plugin, int argc, char *argv[], GError **error)
+chimara_glk_run(ChimaraGlk *glk, const gchar *plugin, int argc, char *argv[], GError **error)
 {
     g_return_val_if_fail(glk || CHIMARA_IS_GLK(glk), FALSE);
     g_return_val_if_fail(plugin, FALSE);
@@ -1063,11 +1052,13 @@ chimara_glk_run(ChimaraGlk *glk, gchar *plugin, int argc, char *argv[], GError *
     if(!priv->program)
     {
         g_warning( "Error opening module: %s", g_module_error() );
+        /* TODO: set error */
         return FALSE;
     }
     if( !g_module_symbol(priv->program, "glk_main", (gpointer *) &startup->glk_main) )
     {
         g_warning( "Error finding glk_main(): %s", g_module_error() );
+        /* TODO: set error */
         return FALSE;
     }
 
index 32725de98968334294eec85e63fdbb7463e6db2d..fc3ab79439b9ad987825d3ffc011ce8e5f90bed4 100644 (file)
@@ -52,7 +52,7 @@ void chimara_glk_set_monospace_font_string(ChimaraGlk *glk, const gchar *font);
 PangoFontDescription *chimara_glk_get_monospace_font_description(ChimaraGlk *glk);
 void chimara_glk_set_spacing(ChimaraGlk *glk, guint spacing);
 guint chimara_glk_get_spacing(ChimaraGlk *glk);
-gboolean chimara_glk_run(ChimaraGlk *glk, gchar *plugin, int argc, char *argv[], GError **error);
+gboolean chimara_glk_run(ChimaraGlk *glk, const gchar *plugin, int argc, char *argv[], GError **error);
 void chimara_glk_stop(ChimaraGlk *glk);
 void chimara_glk_wait(ChimaraGlk *glk);
 
index b740e5e0895a5131a093c1ca4fb4c04fb22e3a67..e3553b1c3248b353013a3f9854345d2042dff79b 100644 (file)
@@ -1,3 +1,5 @@
+#include <errno.h>
+#include <stdlib.h>
 #include <glib.h>
 #include <glib-object.h>
 #include <config.h>
@@ -12,17 +14,24 @@ static gboolean supported_formats[CHIMARA_IF_NUM_FORMATS][CHIMARA_IF_NUM_INTERPR
        { TRUE,  TRUE,  FALSE, FALSE }, /* Z5 */
        { TRUE,  TRUE,  FALSE, FALSE }, /* Z6 */
        { TRUE,  TRUE,  FALSE, FALSE }, /* Z8 */
-       { FALSE, FALSE, TRUE,  TRUE  }  /* Glulx */
+       { TRUE,  TRUE,  FALSE, FALSE }, /* Zblorb */
+       { FALSE, FALSE, TRUE,  TRUE  }, /* Glulx */
+       { FALSE, FALSE, TRUE,  TRUE  }  /* Gblorb */
 };
 static gchar *format_names[CHIMARA_IF_NUM_FORMATS] = {
        N_("Z-code version 5"),
        N_("Z-code version 6"),
        N_("Z-code version 8"),
-       N_("Glulx")
+       N_("Blorbed Z-code"),
+       N_("Glulx"),
+       N_("Blorbed Glulx")
 };
 static gchar *interpreter_names[CHIMARA_IF_NUM_INTERPRETERS] = {
        N_("Frotz"), N_("Nitfol"), N_("Glulxe"), N_("Git")
 };
+static gchar *plugin_names[CHIMARA_IF_NUM_INTERPRETERS] = {
+       "frotz", "nitfol", "glulxe", "git"
+};
 
 typedef struct _ChimaraIFPrivate {
        ChimaraIFInterpreter preferred_interpreter[CHIMARA_IF_NUM_FORMATS];
@@ -52,7 +61,9 @@ chimara_if_init(ChimaraIF *self)
        priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z5] = CHIMARA_IF_INTERPRETER_FROTZ;
        priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z6] = CHIMARA_IF_INTERPRETER_FROTZ;
        priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z8] = CHIMARA_IF_INTERPRETER_FROTZ;
+       priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z_BLORB] = CHIMARA_IF_INTERPRETER_FROTZ;
        priv->preferred_interpreter[CHIMARA_IF_FORMAT_GLULX] = CHIMARA_IF_INTERPRETER_GLULXE;
+       priv->preferred_interpreter[CHIMARA_IF_FORMAT_GLULX_BLORB] = CHIMARA_IF_INTERPRETER_GLULXE;
 }
 
 static void
@@ -85,7 +96,7 @@ chimara_if_finalize(GObject *object)
 static void
 chimara_if_command(ChimaraIF *self, gchar *input, gchar *response)
 {
-       /* TODO: Add default signal handler */
+       /* Default signal handler */
 }
 
 static void
@@ -134,7 +145,7 @@ chimara_if_new(void)
 void
 chimara_if_set_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format, ChimaraIFInterpreter interpreter)
 {
-       g_return_if_fail(self);
+       g_return_if_fail(self && CHIMARA_IS_IF(self));
        g_return_if_fail(format < CHIMARA_IF_NUM_FORMATS);
        g_return_if_fail(format < CHIMARA_IF_NUM_INTERPRETERS);
 
@@ -149,8 +160,115 @@ chimara_if_set_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format, Ch
 ChimaraIFInterpreter
 chimara_if_get_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format)
 {
-       g_return_val_if_fail(self, -1);
+       g_return_val_if_fail(self && CHIMARA_IS_IF(self), -1);
        g_return_val_if_fail(format < CHIMARA_IF_NUM_FORMATS, -1);
        CHIMARA_IF_USE_PRIVATE(self, priv);
        return priv->preferred_interpreter[format];
 }
+
+/* Opens a '.la' file and finds the name of the plugin library. g_free() the
+ * string when done. */
+static gchar *
+find_dlname(const gchar *pluginfile, GError **error)
+{
+       /* Find the name of the shared library */
+       gchar *dlname;
+       FILE *plugin = fopen(pluginfile, "r");
+       if(!plugin)
+       {
+               g_set_error(error, G_FILE_ERROR, errno, "Error opening '%s': %s", pluginfile, g_strerror(errno));
+               return NULL;
+       }
+       gchar *line = NULL;
+       size_t buflen;
+       ssize_t length;
+       while((length = getline(&line, &buflen, plugin)) != -1)
+       {       
+               if(g_str_has_prefix(line, "dlname='"))
+               {
+                       dlname = g_strndup(line + 8, length - 10);
+                       break;
+               }
+       }
+       free(line);
+       if(!dlname)
+       {
+               g_set_error(error, G_FILE_ERROR, errno, "Error reading '%s': %s", pluginfile, g_strerror(errno));
+               return NULL;
+       }
+       if(fclose(plugin))
+       {
+               g_set_error(error, G_FILE_ERROR, errno, "Error closing '%s': %s", pluginfile, g_strerror(errno));
+               return NULL;
+       }
+       return dlname;
+}
+
+gboolean 
+chimara_if_run_game(ChimaraIF *self, gchar *gamefile, GError **error)
+{
+       g_return_val_if_fail(self && CHIMARA_IS_IF(self), FALSE);
+       g_return_val_if_fail(gamefile, FALSE);
+       
+       CHIMARA_IF_USE_PRIVATE(self, priv);
+
+       /* Find out what format the game is */
+       /* TODO: Look inside the file instead of just looking at the extension */
+       ChimaraIFFormat format = CHIMARA_IF_FORMAT_Z5;
+       if(g_str_has_suffix(gamefile, ".z5"))
+               format = CHIMARA_IF_FORMAT_Z5;
+       else if(g_str_has_suffix(gamefile, ".z6"))
+               format = CHIMARA_IF_FORMAT_Z6;
+       else if(g_str_has_suffix(gamefile, ".z8"))
+               format = CHIMARA_IF_FORMAT_Z8;
+       else if(g_str_has_suffix(gamefile, ".zlb") || g_str_has_suffix(gamefile, ".zblorb"))
+               format = CHIMARA_IF_FORMAT_Z_BLORB;
+       else if(g_str_has_suffix(gamefile, ".ulx"))
+               format = CHIMARA_IF_FORMAT_GLULX;
+       else if(g_str_has_suffix(gamefile, ".blb") || g_str_has_suffix(gamefile, ".blorb") || g_str_has_suffix(gamefile, ".glb") || g_str_has_suffix(gamefile, ".gblorb"))
+               format = CHIMARA_IF_FORMAT_GLULX_BLORB;
+       
+       /* Now decide what interpreter to use */
+       ChimaraIFInterpreter interpreter = priv->preferred_interpreter[format];
+       gchar *libtoolfile = g_strconcat(plugin_names[interpreter], ".la", NULL);
+#ifndef RELEASE
+       /* If there is a plugin in the source tree, use that */
+       gboolean use_installed = FALSE;
+       gchar *libtoolpath = g_build_filename("..", "interpreters", plugin_names[interpreter], libtoolfile, NULL);
+       if( !g_file_test(libtoolpath, G_FILE_TEST_EXISTS) ) 
+       {
+               g_free(libtoolpath);
+#endif
+               gchar *libtoolpath = g_build_filename(PLUGINDIR, libtoolfile, NULL);
+               if( !g_file_test(libtoolpath, G_FILE_TEST_EXISTS) ) 
+               {
+                       g_free(libtoolpath);
+                       g_free(libtoolfile);
+                       g_warning("Cannot open %s plugin file", interpreter_names[interpreter]);
+                       /* TODO: set error */
+                       return FALSE;
+               }
+#ifndef RELEASE
+               use_installed = TRUE;
+       }
+#endif
+       g_free(libtoolfile);
+       
+       gchar *dlname = find_dlname(libtoolpath, error);
+       g_free(libtoolpath);
+       if(!dlname)
+               return FALSE;
+       gchar *pluginpath;
+#ifndef RELEASE
+       if(use_installed)
+#endif
+               pluginpath = g_build_filename(PLUGINDIR, dlname, NULL);
+#ifndef RELEASE
+       else
+               pluginpath = g_build_filename("..", "interpreters", plugin_names[interpreter], LT_OBJDIR, dlname, NULL);
+#endif
+       char *argv[3] = { pluginpath, gamefile, NULL };
+       gboolean retval = chimara_glk_run(CHIMARA_GLK(self), pluginpath, 2, argv, error);
+       g_free(dlname);
+       return retval;
+}
index ea5aed0d6a2937ad09f2803a6ff0a135040d2408..f081aaf3e7392687b3e1e5dcc65cad57394a8d9e 100644 (file)
@@ -17,7 +17,9 @@ typedef enum _ChimaraIFFormat {
        CHIMARA_IF_FORMAT_Z5,
        CHIMARA_IF_FORMAT_Z6,
        CHIMARA_IF_FORMAT_Z8,
+       CHIMARA_IF_FORMAT_Z_BLORB,
        CHIMARA_IF_FORMAT_GLULX,
+       CHIMARA_IF_FORMAT_GLULX_BLORB,
        CHIMARA_IF_NUM_FORMATS
 } ChimaraIFFormat;
 
@@ -43,6 +45,7 @@ GType chimara_if_get_type(void) G_GNUC_CONST;
 GtkWidget *chimara_if_new(void);
 void chimara_if_set_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format, ChimaraIFInterpreter interpreter);
 ChimaraIFInterpreter chimara_if_get_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format);
+gboolean chimara_if_run_game(ChimaraIF *self, gchar *gamefile, GError **error);
 
 G_END_DECLS
 
index e73df826ca98c0a92f35970d58f6705870f76978..5c38111167ad9e63571cb7a17bbe0967b22cbc93 100644 (file)
@@ -43,6 +43,7 @@
 #include "callbacks.h"
 #include "error.h"
 #include <libchimara/chimara-glk.h>
+#include <libchimara/chimara-if.h>
 
 /* Global pointers to widgets */
 GtkBuilder *builder = NULL;
@@ -63,27 +64,9 @@ on_stopped(ChimaraGlk *glk)
 }
 
 static void
-on_waiting(ChimaraGlk *glk)
+on_command(ChimaraGlk *glk, gchar *input, gchar *response)
 {
-       g_printerr("Waiting!\n");
-}
-
-static void
-on_char_input(ChimaraGlk *glk, guint32 window_rock, guint keysym)
-{
-       g_printerr("Character input in window %d: key %d\n", window_rock, keysym);
-}
-
-static void
-on_line_input(ChimaraGlk *glk, guint32 window_rock, gchar *text)
-{
-       g_printerr("Line input in window %d: '%s'\n", window_rock, text);
-}
-
-static void
-on_text_buffer_output(ChimaraGlk *glk, guint32 window_rock, gchar *text)
-{
-       g_printerr("Text buffer output in window %d: '%s'\n", window_rock, text);
+       g_printerr("Command!\n");
 }
 
 static GObject *
@@ -131,16 +114,13 @@ create_window(void)
                return;
        }
        
-       glk = chimara_glk_new();
+       glk = chimara_if_new();
        g_object_set(glk, "border-width", 6, "spacing", 6, NULL);
        chimara_glk_set_default_font_string(CHIMARA_GLK(glk), "Serif 12");
        chimara_glk_set_monospace_font_string(CHIMARA_GLK(glk), "Monospace 12");
        g_signal_connect(glk, "started", G_CALLBACK(on_started), NULL);
        g_signal_connect(glk, "stopped", G_CALLBACK(on_stopped), NULL);
-       g_signal_connect(glk, "waiting", G_CALLBACK(on_waiting), NULL);
-       g_signal_connect(glk, "char-input", G_CALLBACK(on_char_input), NULL);
-       g_signal_connect(glk, "line-input", G_CALLBACK(on_line_input), NULL);
-       g_signal_connect(glk, "text-buffer-output", G_CALLBACK(on_text_buffer_output), NULL);
+       g_signal_connect(glk, "command", G_CALLBACK(on_command), NULL);
        
        GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") );                      
        if(vbox == NULL)
@@ -182,7 +162,12 @@ main(int argc, char *argv[])
        g_object_unref( G_OBJECT(builder) );
        g_object_unref( G_OBJECT(uimanager) );
 
-    if( !chimara_glk_run(CHIMARA_GLK(glk), "../interpreters/frotz/.libs/frotz.so", argc, argv, &error) ) {
+       if(argc < 2) {
+               error_dialog(GTK_WINDOW(window), NULL, "Must provide a game file");
+               return 1;
+       }
+       
+    if( !chimara_if_run_game(CHIMARA_IF(glk), argv[1], &error) ) {
                error_dialog(GTK_WINDOW(window), error, "Error starting Glk library: ");
                return 1;
        }