/* Sarien - A Sierra AGI resource interpreter engine * Copyright (C) 1999-2001 Stuart George and Claudio Matsuoka * * $Id: id.c,v 1.34 2001/11/04 02:33:45 cmatsuoka Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; see docs/COPYING for further details. */ #ifndef PALMOS #include #include #include "sarien.h" #include "agi.h" #include "opcodes.h" /* * Determine what AGI v2 system to emulate, these are the major version * to emulate, thus 2.915 comes under 2.917, 2.4xxx is 2.440, etc. * * 0x2089 * 0x2272 * 0x2440 * 0x2917 * 0x2936 */ int setup_v2_game(int ver, UINT32 crc); int setup_v3_game(int ver, UINT32 crc); int v4id_game (UINT32 crc); void list_games () { FILE *f; char *c, *t, buf[256]; UINT32 id, ver; int min, maj, i = 0; /**/ f = fopen (get_config_file(), "r"); printf ( "Game# AGI ver. Title CRC\n" "------ ---------- ---------------------------------------- -------\n" ); while (!feof (f)) { fgets (buf, 256, f); c = strchr (buf, '#'); if (c) *c = 0; /* Remove spaces at end of line */ if (strlen (buf)) { for (c = buf + strlen (buf) - 1; *c == ' ' || *c == '\t'; *c-- = 0) {} } t = strtok (buf, " \t\r\n"); if (t == NULL) continue; id = strtoul (t, NULL, 0); t = strtok (NULL, " \t\r\n"); if (t == NULL) continue; ver = strtoul (t, NULL, 0); maj = (ver >> 12) & 0xf; min = ver & 0xfff; t = strtok (NULL, "\n\r"); if (maj == 2) { printf ("[%3d] %x.%03x %-40.40s 0x%05x\n", ++i, maj, min, t, id); } else { printf ("[%3d] %x.002.%03x %-40.40s 0x%05x\n", ++i, maj, min, t, id); } } fclose (f); } static UINT32 match_crc (UINT32 crc, char *path) { FILE *f; char *c, *t, buf[256]; UINT32 id, ver; if ((f = fopen (path, "r")) == NULL) return 0; while (!feof (f)) { fgets (buf, 256, f); c = strchr (buf, '#'); if (c) *c = 0; /* Remove spaces at end of line */ if (strlen (buf)) { for (c = buf + strlen (buf) - 1; *c == ' ' || *c == '\t'; *c-- = 0) {} } t = strtok (buf, " \t\r\n"); if (t == NULL) continue; id = strtoul (t, NULL, 0); t = strtok (NULL, " \t\r\n"); if (t == NULL) continue; ver = strtoul (t, NULL, 0); t = strtok (NULL, "\n\r"); if (id == crc) { /* Now we must check options enclosed in brackets * like [A] for Amiga */ if (*t == '[') { while (*t != ']') { switch (*t++) { case 'A': opt.amiga = TRUE; break; case 'a': opt.agds = TRUE; break; #ifdef USE_MOUSE case 'm': opt.agimouse = TRUE; break; #endif } } t++; for (; *t == ' ' || *t == '\t'; t++) {} } report ("AGI game detected: %s\n\n", t); fclose (f); return ver; } } fclose (f); return 0; } static UINT32 match_version (UINT32 crc) { int ver; char *fname; fname = get_config_file(); ver = match_crc(crc, fname); return ver; } int v2id_game () { #ifdef __MPW__ return err_OK; /* FIXME! */ #else int y, ver; UINT32 len, c, crc; UINT8 *buff; FILE *fp; char *fn[] = { "viewdir", "logdir", "picdir", "snddir", "words.tok", "object", "" }; /*_D (_D_WARN);*/ buff = malloc (8192); for (crc = y = 0; fn[y][0]; y++) { char *path = fixpath (NO_GAMEDIR, fn[y]); if ((fp = fopen (path, "rb")) != NULL) { for (len = 1; len > 0; ) { memset (buff, 0, 8192); len = fread (buff, 1, 8000, fp); for (c = 0; c < len; c++) crc += *(buff + c); } fclose (fp); } } free (buff); report ("Computed CRC: 0x%05x\n", crc); ver = match_version (crc); game.crc = crc; game.ver = ver; agi_set_release (ver); return setup_v2_game(ver, crc); #endif } /* * Currently, there is no known difference between v3.002.098 -> v3.002.149 * So version emulated; * * 0x0086, * 0x0149 */ int v3id_game () { int ec = err_OK, y, ver; UINT32 len, c, crc; UINT8 *buff; FILE *fp; char *path, *fn[] = { "words.tok", "object", "" }; buff = malloc (8192); for (crc = 0, y = 0; fn[y][0]!=0x0; y++) { path = fixpath (NO_GAMEDIR, fn[y]); if ((fp = fopen (path, "rb")) != NULL) { len = 1; while (len > 0) { memset (buff, 0, 8192); len = fread (buff, 1, 8000, fp); for (c = 0; c < len; c++) crc += *(buff + c); } fclose(fp); } } /* no do the directory file */ path = fixpath (GAMEDIR, DIR_); if ((fp = fopen(path, "rb")) != NULL) { for (len = 1; len > 0; ) { memset (buff, 0, 8192); len = fread (buff, 1, 8000, fp); for (c = 0; c < len; c++) crc += *(buff + c); } fclose (fp); } free (buff); report ("Computed CRC: 0x%05x\n", crc); ver = match_version (crc); game.crc = crc; game.ver = ver; agi_set_release (ver); ec = setup_v3_game(ver, crc); return ec; } #ifdef PALMOS int v4id_game (UINT32 crc) { int ec = err_OK, ver; ver = match_version (crc); agi_set_release (ver); switch ((ver>>12)&0xFF) { case 2: ec = setup_v2_game (ver, crc); break; case 3: ec = setup_v3_game (ver, crc); break; } return ec; } #endif /** * */ int setup_v2_game (int ver, UINT32 crc) { int ec=err_OK; if (ver == 0) { report ("Unknown v2 Sierra game: %08x\n\n", crc); agi_set_release (0x2917); } /* setup the differences in the opcodes and other bits in the * AGI v2 specs */ if (opt.emuversion) agi_set_release (opt.emuversion); if (opt.agds) agi_set_release (0x2440);/* ALL AGDS games built for 2.440 */ switch(agi_get_release ()) { case 0x2089: logic_names_cmd[0x86].num_args = 0; /* quit: 0 args */ case 0x2272: logic_names_cmd[0x97].num_args = 3; /* print.at: 3 args */ logic_names_cmd[0x98].num_args = 3; /* print.at.v: 3 args*/ break; case 0x2440: break; case 0x2917: break; case 0x2936: break; default: report ("** Cannot setup for unknown version\n"); ec = err_UnknownAGIVersion; break; } return ec; } /** * */ int setup_v3_game (int ver, UINT32 crc) { int ec = err_OK; if (ver == 0) { report ("Unknown v3 Sierra game: %08x\n\n", crc); agi_set_release (ver = 0x3149); } if (opt.emuversion) agi_set_release (ver = opt.emuversion); switch(ver) { case 0x3086: logic_names_cmd[0xad].num_args = 1; /* 173 : 1 args */ break; case 0x3149: logic_names_cmd[0xad].num_args = 0; /* 173 : 0 args */ break; default: report ("Error: cannot setup for unknown version\n"); ec = err_UnknownAGIVersion; break; } return ec; } #endif