1 /*
2 * A Z-Machine
3 * Copyright (C) 2000 Andrew Hunter
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * Deal with the .zoomrc file
22 */
23
24 #include "../config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "zmachine.h"
31 #include "rc.h"
32 #include "rcp.h"
33 #include "hash.h"
34
35 extern FILE* yyin;
36 extern int rc_parse(void);
37 extern int _rc_line;
38
39 hash rc_hash = NULL;
40 static rc_game* game = NULL;
41 rc_game* rc_defgame = NULL;
42
43 #ifdef DATADIR
44 # define ZOOMRC DATADIR "/zoomrc"
45 # define GAMEDIR DATADIR "/games"
46 #else
47 # define ZOOMRC "zoomrc"
48 # define GAMEDIR NULL
49 #endif
50
rc_error(char * erm)51 void rc_error(char* erm)
52 {
53 zmachine_info("Error while parsing .zoomrc (line %i): %s",
54 _rc_line, erm);
55 }
56
rc_load(void)57 void rc_load(void)
58 {
59 char* home;
60 char* filename;
61 int domerge = 1;
62
63 if (rc_hash == NULL)
64 rc_hash = hash_create();
65
66 rc_merging = 0;
67
68 #if WINDOW_SYSTEM != 2
69 home = getenv("HOME");
70 if (home==NULL)
71 {
72 filename = "zoomrc";
73 }
74 else
75 {
76 filename = malloc(strlen(home)+9);
77 strcpy(filename, home);
78 strcat(filename, "/.zoomrc");
79 }
80
81 yyin = fopen(filename, "r");
82
83 if (yyin==NULL)
84 {
85 domerge = 0;
86
87 yyin = fopen(ZOOMRC, "r");
88 if (yyin == NULL)
89 zmachine_fatal("Unable to open resource file '%s', or the systems default file at " ZOOMRC, filename);
90 }
91 #else
92 yyin = fopen("zoomrc", "r");
93 if (yyin == NULL)
94 zmachine_fatal("Unable to open resource file 'zoomrc'. Make sure that it is in the current directory");
95 #endif
96
97 _rc_line = 1;
98 if (rc_parse() != 0)
99 {
100 zmachine_fatal("Unable to recover from errors found in '.zoomrc'");
101 }
102 fclose(yyin);
103
104 #if WINDOW_SYSTEM == 1
105 if (domerge)
106 {
107 rc_merge(ZOOMRC);
108 }
109 #endif
110 }
111
rc_merge(char * filename)112 void rc_merge(char* filename)
113 {
114 if (rc_hash == NULL)
115 rc_hash = hash_create();
116
117 rc_merging = 1;
118 yyin = fopen(filename, "r");
119 if (yyin == NULL)
120 {
121 zmachine_warning("Unable to open resource file '%s'", filename);
122 return;
123 }
124 _rc_line = 1;
125 if (rc_parse() == 1)
126 {
127 zmachine_info("Zoomrc file '%s' has errors", filename);
128 }
129 fclose(yyin);
130 }
131
rc_set_game(char * serial,int revision,int checksum)132 void rc_set_game(char* serial, int revision, int checksum)
133 {
134 char hash[40];
135
136 sprintf(hash, "%i.%.6s.%04x", revision, serial, (unsigned)checksum);
137 game = hash_get(rc_hash, (unsigned char*)hash, strlen(hash));
138
139 if (game == NULL)
140 {
141 sprintf(hash, "%i.%.6s", revision, serial);
142 game = hash_get(rc_hash, (unsigned char*)hash, strlen(hash));
143 }
144 if (game == NULL)
145 game = hash_get(rc_hash, (unsigned char*)"default", 7);
146 if (game == NULL)
147 zmachine_fatal("No .zoomrc entry for your game, and no default entry either");
148 rc_defgame = hash_get(rc_hash, (unsigned char*)"default", 7);
149 if (rc_defgame == NULL)
150 zmachine_fatal("No default entry in .zoomrc");
151 }
152
rc_get_game_name(char * serial,int revision)153 char* rc_get_game_name(char* serial, int revision)
154 {
155 char hash[20];
156 rc_game* game;
157
158 sprintf(hash, "%i.%.6s", revision, serial);
159 game = hash_get(rc_hash, (unsigned char*)hash, strlen(hash));
160 if (game == NULL)
161 return NULL;
162 return game->name;
163 }
164
rc_get_name(void)165 char* rc_get_name(void)
166 {
167 if (game == NULL)
168 zmachine_fatal("Programmer is a spoon");
169
170 return game->name;
171 }
172
rc_get_fonts(int * n_fonts)173 rc_font* rc_get_fonts(int* n_fonts)
174 {
175 rc_font* deffonts;
176 int x, y;
177
178 if (game == NULL)
179 zmachine_fatal("Programmer is a spoon");
180
181 if (game->fonts == NULL)
182 {
183 *n_fonts = rc_defgame->n_fonts;
184 return rc_defgame->fonts;
185 }
186
187 deffonts = rc_defgame->fonts;
188 for (x=0; x<rc_defgame->n_fonts; x++)
189 {
190 int found = 0;
191
192 for (y=0; y<game->n_fonts; y++)
193 {
194 if (game->fonts[y].num == rc_defgame->fonts[x].num)
195 found = 1;
196 }
197
198 if (!found)
199 {
200 game->n_fonts++;
201 game->fonts = realloc(game->fonts,
202 sizeof(rc_font)*game->n_fonts);
203 game->fonts[game->n_fonts-1] = rc_defgame->fonts[x];
204 }
205 }
206
207 *n_fonts = game->n_fonts;
208 return game->fonts;
209 }
210
rc_get_colours(int * n_cols)211 rc_colour* rc_get_colours(int* n_cols)
212 {
213 if (game == NULL)
214 zmachine_fatal("Programmer is a spoon");
215
216 if (game->colours == NULL)
217 {
218 *n_cols = rc_defgame->n_colours;
219 return rc_defgame->colours;
220 }
221
222 *n_cols = game->n_colours;
223 return game->colours;
224 }
225
rc_get_antialias(void)226 int rc_get_antialias(void)
227 {
228 if (game->antialias == -1)
229 return rc_defgame->antialias==-1?1:rc_defgame->antialias;
230 return game->antialias;
231 }
232
rc_get_interpreter(void)233 int rc_get_interpreter(void)
234 {
235 if (game->interpreter == -1)
236 return rc_defgame->interpreter;
237 return game->interpreter;
238 }
239
rc_get_revision(void)240 int rc_get_revision(void)
241 {
242 if (game->revision == -1)
243 return rc_defgame->revision;
244 return game->revision;
245 }
246
rc_get_gamedir(void)247 char* rc_get_gamedir(void)
248 {
249 if (game->gamedir == NULL)
250 {
251 if (rc_defgame->gamedir == NULL)
252 return GAMEDIR;
253 return rc_defgame->gamedir;
254 }
255 return game->gamedir;
256 }
257
rc_get_savedir(void)258 char* rc_get_savedir(void)
259 {
260 if (game->savedir == NULL)
261 {
262 if (rc_defgame->savedir == NULL)
263 {
264 #if WINDOW_SYSTEM != 2
265 static char* dir = NULL;
266
267 if (dir == NULL && machine.story_file != NULL)
268 {
269 int x;
270
271 for (x=strlen(machine.story_file)-1;
272 x>0 && machine.story_file[x] != '/';
273 x--);
274
275 if (x != 0)
276 {
277 dir = malloc(x+2);
278 strncpy(dir, machine.story_file, x+1);
279 dir[x+1] = 0;
280 }
281 }
282
283 if (dir != NULL)
284 return dir;
285
286 return "./";
287 #else
288 return NULL;
289 #endif
290 }
291 return rc_defgame->savedir;
292 }
293 return game->savedir;
294 }
295
rc_get_graphics(void)296 char* rc_get_graphics(void)
297 {
298 if (game->graphics == NULL)
299 return rc_defgame->graphics;
300 return game->graphics;
301 }
302
rc_get_sounds(void)303 char* rc_get_sounds(void)
304 {
305 if (game->sounds == NULL)
306 return rc_defgame->sounds;
307 return game->sounds;
308 }
309
rc_get_xsize(void)310 int rc_get_xsize(void)
311 {
312 if (game->xsize == -1)
313 {
314 if (rc_defgame->xsize == -1)
315 return 80;
316 return rc_defgame->xsize;
317 }
318 return game->xsize;
319 }
320
rc_get_ysize(void)321 int rc_get_ysize(void)
322 {
323 if (game->ysize == -1)
324 {
325 if (rc_defgame->ysize == -1)
326 return 30;
327 return rc_defgame->ysize;
328 }
329 return game->ysize;
330 }
331
rc_get_foreground(void)332 int rc_get_foreground (void) {
333 if (game->fg_col == -1) return 0;
334 return game->fg_col;
335 }
336
rc_get_background(void)337 int rc_get_background (void) {
338 if (game->bg_col == -1) return 7;
339 return game->bg_col;
340 }
341