38779a2d788443d4e8eb1bed9c4cfbad0ea201d5
[projects/chimara/chimara.git] / interpreters / glulxe / unixstrt.c
1 /* unixstrt.c: Unix-specific code for Glulxe.
2     Designed by Andrew Plotkin <erkyrath@eblong.com>
3     http://eblong.com/zarf/glulx/index.html
4 */
5
6 #include <string.h>
7 #include "glk.h"
8 #include "glulxe.h"
9 #include "glkstart.h" /* This comes with the Glk library. */
10
11 /* The only command-line argument is the filename. And the profiling switch,
12    if that's compiled in. The only *two* command-line arguments are... 
13 */
14 glkunix_argumentlist_t glkunix_arguments[] = {
15
16 #if VM_PROFILING
17   { "--profile", glkunix_arg_ValueFollows, "Generate profiling information to a file." },
18 #endif /* VM_PROFILING */
19
20   { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
21
22   { NULL, glkunix_arg_End, NULL }
23 };
24
25 int glkunix_startup_code(glkunix_startup_t *data)
26 {
27   /* It turns out to be more convenient if we return TRUE from here, even 
28      when an error occurs, and display an error in glk_main(). */
29   int ix;
30   char *filename = NULL;
31   unsigned char buf[12];
32   int res;
33
34 #ifdef GARGLK
35   char *cx;
36   garglk_set_program_name("Glulxe 0.4.7");
37   garglk_set_program_info("Glulxe 0.4.7 by Andrew Plotkin");
38 #endif
39
40   /* Parse out the arguments. They've already been checked for validity,
41      and the library-specific ones stripped out.
42      As usual for Unix, the zeroth argument is the executable name. */
43   for (ix=1; ix<data->argc; ix++) {
44
45 #if VM_PROFILING
46     if (!strcmp(data->argv[ix], "--profile")) {
47       ix++;
48       if (ix<data->argc) {
49         strid_t profstr = glkunix_stream_open_pathname_gen(data->argv[ix], TRUE, FALSE, 1);
50         if (!profstr) {
51           init_err = "Unable to open profile output file.";
52           init_err2 = data->argv[ix];
53           return TRUE;
54         }
55         setup_profile(profstr, NULL);
56       }
57       continue;
58     }
59 #endif /* VM_PROFILING */
60
61     if (filename) {
62       init_err = "You must supply exactly one game file.";
63       return TRUE;
64     }
65     filename = data->argv[ix];
66   }
67
68   if (!filename) {
69     init_err = "You must supply the name of a game file.";
70 #ifdef GARGLK
71     return TRUE; /* Hack! but I want error message in glk window */
72 #endif
73         return FALSE;
74   }
75     
76   gamefile = glkunix_stream_open_pathname(filename, FALSE, 1);
77   if (!gamefile) {
78     init_err = "The game file could not be opened.";
79     init_err2 = filename;
80     return TRUE;
81   }
82
83 #ifdef GARGLK
84   cx = strrchr(filename, '/');
85   if (!cx) cx = strrchr(filename, '\\');
86   garglk_set_story_name(cx ? cx + 1 : filename);
87 #endif
88
89   /* Now we have to check to see if it's a Blorb file. */
90
91   glk_stream_set_position(gamefile, 0, seekmode_Start);
92   res = glk_get_buffer_stream(gamefile, (char *)buf, 12);
93   if (!res) {
94     init_err = "The data in this stand-alone game is too short to read.";
95     return TRUE;
96   }
97     
98   if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') {
99     locate_gamefile(FALSE);
100     return TRUE;
101   }
102   else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M'
103     && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') {
104     locate_gamefile(TRUE);
105     return TRUE;
106   }
107   else {
108     init_err = "This is neither a Glulx game file nor a Blorb file "
109       "which contains one.";
110     return TRUE;
111   }
112 }
113