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