1 /* Sarien - A Sierra AGI resource interpreter engine
2 * Copyright (C) 1999-2001 Stuart George and Claudio Matsuoka
3 *
4 * $Id: id.c,v 1.34 2001/11/04 02:33:45 cmatsuoka Exp $
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; see docs/COPYING for further details.
9 */
10
11 #ifndef PALMOS
12
13 #include <stdio.h>
14 #include <string.h>
15 #include "sarien.h"
16 #include "agi.h"
17 #include "opcodes.h"
18
19 /*
20 * Determine what AGI v2 system to emulate, these are the major version
21 * to emulate, thus 2.915 comes under 2.917, 2.4xxx is 2.440, etc.
22 *
23 * 0x2089
24 * 0x2272
25 * 0x2440
26 * 0x2917
27 * 0x2936
28 */
29
30 int setup_v2_game(int ver, UINT32 crc);
31 int setup_v3_game(int ver, UINT32 crc);
32 int v4id_game (UINT32 crc);
33
list_games()34 void list_games ()
35 {
36 FILE *f;
37 char *c, *t, buf[256];
38 UINT32 id, ver;
39 int min, maj, i = 0;
40
41 /**/
42 f = fopen (get_config_file(), "r");
43
44 printf (
45 "Game# AGI ver. Title CRC\n"
46 "------ ---------- ---------------------------------------- -------\n"
47 );
48
49 while (!feof (f)) {
50 fgets (buf, 256, f);
51 c = strchr (buf, '#');
52 if (c) *c = 0;
53
54 /* Remove spaces at end of line */
55 if (strlen (buf)) {
56 for (c = buf + strlen (buf) - 1;
57 *c == ' ' || *c == '\t'; *c-- = 0) {}
58 }
59
60
61 t = strtok (buf, " \t\r\n");
62 if (t == NULL)
63 continue;
64 id = strtoul (t, NULL, 0);
65
66 t = strtok (NULL, " \t\r\n");
67 if (t == NULL)
68 continue;
69 ver = strtoul (t, NULL, 0);
70 maj = (ver >> 12) & 0xf;
71 min = ver & 0xfff;
72
73 t = strtok (NULL, "\n\r");
74
75 if (maj == 2) {
76 printf ("[%3d] %x.%03x %-40.40s 0x%05x\n",
77 ++i, maj, min, t, id);
78 } else {
79 printf ("[%3d] %x.002.%03x %-40.40s 0x%05x\n",
80 ++i, maj, min, t, id);
81 }
82 }
83
84 fclose (f);
85 }
86
match_crc(UINT32 crc,char * path)87 static UINT32 match_crc (UINT32 crc, char *path)
88 {
89 FILE *f;
90 char *c, *t, buf[256];
91 UINT32 id, ver;
92
93 if ((f = fopen (path, "r")) == NULL)
94 return 0;
95
96 while (!feof (f)) {
97 fgets (buf, 256, f);
98 c = strchr (buf, '#');
99 if (c) *c = 0;
100
101 /* Remove spaces at end of line */
102 if (strlen (buf)) {
103 for (c = buf + strlen (buf) - 1;
104 *c == ' ' || *c == '\t'; *c-- = 0) {}
105 }
106
107
108 t = strtok (buf, " \t\r\n");
109 if (t == NULL)
110 continue;
111 id = strtoul (t, NULL, 0);
112
113 t = strtok (NULL, " \t\r\n");
114 if (t == NULL)
115 continue;
116 ver = strtoul (t, NULL, 0);
117
118 t = strtok (NULL, "\n\r");
119
120 if (id == crc) {
121 /* Now we must check options enclosed in brackets
122 * like [A] for Amiga
123 */
124
125 if (*t == '[') {
126 while (*t != ']') {
127 switch (*t++) {
128 case 'A':
129 opt.amiga = TRUE;
130 break;
131 case 'a':
132 opt.agds = TRUE;
133 break;
134 #ifdef USE_MOUSE
135 case 'm':
136 opt.agimouse = TRUE;
137 break;
138 #endif
139 }
140 }
141 t++;
142
143 for (; *t == ' ' || *t == '\t'; t++) {}
144 }
145
146 report ("AGI game detected: %s\n\n", t);
147 fclose (f);
148 return ver;
149 }
150 }
151
152 fclose (f);
153
154 return 0;
155 }
156
157
match_version(UINT32 crc)158 static UINT32 match_version (UINT32 crc)
159 {
160 int ver;
161 char *fname;
162
163 fname = get_config_file();
164 ver = match_crc(crc, fname);
165
166 return ver;
167 }
168
169
v2id_game()170 int v2id_game ()
171 {
172 #ifdef __MPW__
173 return err_OK; /* FIXME! */
174 #else
175 int y, ver;
176 UINT32 len, c, crc;
177 UINT8 *buff;
178 FILE *fp;
179 char *fn[] = { "viewdir", "logdir", "picdir", "snddir",
180 "words.tok", "object", "" };
181
182 /*_D (_D_WARN);*/
183 buff = malloc (8192);
184
185 for (crc = y = 0; fn[y][0]; y++) {
186 char *path = fixpath (NO_GAMEDIR, fn[y]);
187 if ((fp = fopen (path, "rb")) != NULL) {
188 for (len = 1; len > 0; ) {
189 memset (buff, 0, 8192);
190 len = fread (buff, 1, 8000, fp);
191 for (c = 0; c < len; c++)
192 crc += *(buff + c);
193 }
194 fclose (fp);
195 }
196 }
197 free (buff);
198
199 report ("Computed CRC: 0x%05x\n", crc);
200 ver = match_version (crc);
201 game.crc = crc;
202 game.ver = ver;
203 agi_set_release (ver);
204 return setup_v2_game(ver, crc);
205 #endif
206 }
207
208 /*
209 * Currently, there is no known difference between v3.002.098 -> v3.002.149
210 * So version emulated;
211 *
212 * 0x0086,
213 * 0x0149
214 */
215
v3id_game()216 int v3id_game ()
217 {
218 int ec = err_OK, y, ver;
219 UINT32 len, c, crc;
220 UINT8 *buff;
221 FILE *fp;
222 char *path, *fn[] = { "words.tok", "object", "" };
223
224 buff = malloc (8192);
225
226 for (crc = 0, y = 0; fn[y][0]!=0x0; y++) {
227 path = fixpath (NO_GAMEDIR, fn[y]);
228 if ((fp = fopen (path, "rb")) != NULL) {
229 len = 1;
230 while (len > 0) {
231 memset (buff, 0, 8192);
232 len = fread (buff, 1, 8000, fp);
233 for (c = 0; c < len; c++)
234 crc += *(buff + c);
235 }
236 fclose(fp);
237 }
238 }
239
240 /* no do the directory file */
241
242 path = fixpath (GAMEDIR, DIR_);
243
244 if ((fp = fopen(path, "rb")) != NULL) {
245 for (len = 1; len > 0; ) {
246 memset (buff, 0, 8192);
247 len = fread (buff, 1, 8000, fp);
248 for (c = 0; c < len; c++)
249 crc += *(buff + c);
250 }
251 fclose (fp);
252 }
253
254 free (buff);
255
256 report ("Computed CRC: 0x%05x\n", crc);
257 ver = match_version (crc);
258 game.crc = crc;
259 game.ver = ver;
260 agi_set_release (ver);
261
262 ec = setup_v3_game(ver, crc);
263
264
265 return ec;
266 }
267
268
269 #ifdef PALMOS
270
v4id_game(UINT32 crc)271 int v4id_game (UINT32 crc)
272 {
273 int ec = err_OK, ver;
274
275 ver = match_version (crc);
276 agi_set_release (ver);
277
278 switch ((ver>>12)&0xFF) {
279 case 2:
280 ec = setup_v2_game (ver, crc);
281 break;
282 case 3:
283 ec = setup_v3_game (ver, crc);
284 break;
285 }
286
287 return ec;
288 }
289
290 #endif
291
292 /**
293 *
294 */
setup_v2_game(int ver,UINT32 crc)295 int setup_v2_game (int ver, UINT32 crc)
296 {
297 int ec=err_OK;
298
299 if (ver == 0) {
300 report ("Unknown v2 Sierra game: %08x\n\n", crc);
301 agi_set_release (0x2917);
302 }
303
304 /* setup the differences in the opcodes and other bits in the
305 * AGI v2 specs
306 */
307 if (opt.emuversion)
308 agi_set_release (opt.emuversion);
309
310 if (opt.agds)
311 agi_set_release (0x2440);/* ALL AGDS games built for 2.440 */
312
313 switch(agi_get_release ()) {
314 case 0x2089:
315 logic_names_cmd[0x86].num_args = 0; /* quit: 0 args */
316 case 0x2272:
317 logic_names_cmd[0x97].num_args = 3; /* print.at: 3 args */
318 logic_names_cmd[0x98].num_args = 3; /* print.at.v: 3 args*/
319 break;
320 case 0x2440:
321 break;
322 case 0x2917:
323 break;
324 case 0x2936:
325 break;
326 default:
327 report ("** Cannot setup for unknown version\n");
328 ec = err_UnknownAGIVersion;
329 break;
330 }
331
332 return ec;
333 }
334
335 /**
336 *
337 */
setup_v3_game(int ver,UINT32 crc)338 int setup_v3_game (int ver, UINT32 crc)
339 {
340 int ec = err_OK;
341
342 if (ver == 0) {
343 report ("Unknown v3 Sierra game: %08x\n\n", crc);
344 agi_set_release (ver = 0x3149);
345 }
346
347 if (opt.emuversion)
348 agi_set_release (ver = opt.emuversion);
349
350 switch(ver) {
351 case 0x3086:
352 logic_names_cmd[0xad].num_args = 1; /* 173 : 1 args */
353 break;
354 case 0x3149:
355 logic_names_cmd[0xad].num_args = 0; /* 173 : 0 args */
356 break;
357 default:
358 report ("Error: cannot setup for unknown version\n");
359 ec = err_UnknownAGIVersion;
360 break;
361 }
362
363 return ec;
364 }
365
366 #endif
367