1 /*
2  * zip.c
3  *
4  * Z code interpreter main routine. Plays Infocom type 1, 2, 3, 4 and 5 games.
5  *
6  * Usage: zip [options] story-file-name
7  *
8  * options are:
9  *
10  *    -l n - number of lines in display
11  *    -c n - number of columns in display
12  *    -r n - right margin (default = 0)
13  *    -t n - top margin (default = 0)
14  *
15  * This is a no bells and whistles Infocom interpreter for type 1 to 5 games.
16  * It will automatically detect which type of game you want to play. It should
17  * support all type 1 to 5 features and is based loosely on the MS-DOS version
18  * with enhancements to aid portability. Read the readme.1st file for
19  * information on building this program on your favourite operating system.
20  * Please mail me, at the address below, if you find bugs in the code.
21  *
22  * Special thanks to David Doherty and Olaf Barthel for testing this program
23  * and providing invaluable help and code to aid its portability.
24  *
25  * Mark Howell 10-Mar-93 V2.0 howell_ma@movies.enet.dec.com
26  *
27  * Disclaimer:
28  *
29  * You are expressly forbidden to use this program if in so doing you violate
30  * the copyright notice supplied with the original Infocom game.
31  *
32  */
33 
34 #include "ztypes.h"
35 
36 #ifdef __STDC__
37 static void configure (zbyte_t, zbyte_t);
38 #else
39 static void configure ();
40 #endif
41 
42 /*
43  * main
44  *
45  * Initialise environment, start interpreter, clean up.
46  *
47  */
48 
49 #ifdef __STDC__
main(int argc,char * argv[])50 int main (int argc, char *argv[])
51 #else
52 int main (argc, argv)
53 int argc;
54 char *argv[];
55 #endif
56 {
57 
58     process_arguments (argc, argv);
59 
60     configure (V1, V8);
61 
62     initialize_screen ();
63 
64     load_cache ();
65 
66     restart ();
67 
68     (void) interpret ();
69 
70     unload_cache ();
71 
72     close_story ();
73 
74     close_script ();
75 
76     reset_screen ();
77 
78     exit (EXIT_SUCCESS);
79 
80     return (0);
81 
82 }/* main */
83 
84 /*
85  * configure
86  *
87  * Initialise global and type specific variables.
88  *
89  */
90 
91 #ifdef __STDC__
configure(zbyte_t min_version,zbyte_t max_version)92 static void configure (zbyte_t min_version, zbyte_t max_version)
93 #else
94 static void configure (min_version, max_version)
95 zbyte_t min_version;
96 zbyte_t max_version;
97 #endif
98 {
99     zbyte_t header[PAGE_SIZE];
100 
101     read_page (0, header);
102     datap = header;
103 
104     h_type = get_byte (H_TYPE);
105 
106     if (h_type < min_version || h_type > max_version || (get_byte (H_CONFIG) & CONFIG_BYTE_SWAPPED))
107         fatal ("wrong game or version");
108 
109     if (h_type < V4) {
110         story_scaler = 2;
111         story_shift = 1;
112         property_mask = P3_MAX_PROPERTIES - 1;
113         property_size_mask = 0xe0;
114     } else if (h_type < V8) {
115         story_scaler = 4;
116         story_shift = 2;
117         property_mask = P4_MAX_PROPERTIES - 1;
118         property_size_mask = 0x3f;
119     } else {
120         story_scaler = 8;
121         story_shift = 3;
122         property_mask = P4_MAX_PROPERTIES - 1;
123         property_size_mask = 0x3f;
124     }
125 
126     h_config = get_byte (H_CONFIG);
127     h_version = get_word (H_VERSION);
128     h_data_size = get_word (H_DATA_SIZE);
129     h_start_pc = get_word (H_START_PC);
130     h_words_offset = get_word (H_WORDS_OFFSET);
131     h_objects_offset = get_word (H_OBJECTS_OFFSET);
132     h_globals_offset = get_word (H_GLOBALS_OFFSET);
133     h_restart_size = get_word (H_RESTART_SIZE);
134     h_flags = get_word (H_FLAGS);
135     h_synonyms_offset = get_word (H_SYNONYMS_OFFSET);
136     h_file_size = get_word (H_FILE_SIZE);
137     if (h_file_size == 0)
138         h_file_size = get_story_size ();
139     h_checksum = get_word (H_CHECKSUM);
140     h_alternate_alphabet_offset = get_word (H_ALTERNATE_ALPHABET_OFFSET);
141 
142     datap = NULL;
143 
144 }/* configure */
145