1 /*  Sarien - A Sierra AGI resource interpreter engine
2  *  Copyright (C) 1999-2001 Stuart George and Claudio Matsuoka
3  *
4  *  $Id: agi.c,v 1.44 2001/10/31 00:27:25 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 #include <stdio.h>
12 #include <string.h>
13 #include <limits.h>
14 
15 #include "sarien.h"
16 #include "agi.h"
17 #include "opcodes.h"
18 #include "keyboard.h"
19 #include "rand.h"
20 #include "menu.h"
21 #include "savegame.h"
22 
23 static struct agi_loader *loader;		/* loader */
24 
25 
26 #ifndef PALMOS
27 extern struct agi_loader agi_v2;
28 extern struct agi_loader agi_v3;
29 #else
30 extern struct agi_loader agi_v4;
31 #endif
32 
33 
init_pri_bands()34 static void init_pri_bands ()
35 {
36 	int i, p, y = 0;
37 
38 #if 0
39 	if (*game.pri_table != 0xff)
40 		return;
41 #endif
42 
43 	for (p = 1; p < 15; p++) {
44 		for (i = 0; i < 12; i++) {
45 			game.pri_table[y++] = p < 4 ? 4 : p;
46 		}
47 	}
48 }
49 
agi_init()50 int agi_init ()
51 {
52 	int ec, i;
53 
54 	_D("initializing");
55 
56 	/* reset all flags to false and all variables to 0 */
57 	for (i = 0; i < MAX_FLAGS; i++)
58 		setflag (i, 0);
59 	for (i = 0; i < MAX_VARS; i++)
60 		setvar(i, 0);
61 
62 	/* clear all resources and events */
63 	memset (&game.views, 0, MAX_DIRS * sizeof (struct agi_view));
64 	memset (&game.pictures, 0, MAX_DIRS * sizeof (struct agi_picture));
65 	memset (&game.logics, 0, MAX_DIRS * sizeof (struct agi_logic));
66 	memset (&game.sounds, 0, MAX_DIRS * sizeof (struct agi_sound));
67 	memset (&game.ev_scan, 0, MAX_DIRS * sizeof (struct agi_event));
68 	memset (&game.ev_keyp, 0, MAX_DIRS * sizeof (struct agi_event));
69 
70 	init_words ();
71 	set_rnd_seed ();
72 	init_menus ();
73 	init_pri_bands ();
74 
75 	/* clear string buffer */
76 	for (i = 0; i < MAX_WORDS1; i++)
77 		game.strings[i][0] = 0;
78 
79 	/* setup emulation */
80 
81 	report ("Emulating Sierra AGI v");
82 	switch (loader->int_version >> 12) {
83 	case 2:
84 		report ("%x.%03x\n",
85 			(int)(loader->int_version >> 12) & 0xF,
86 			(int)(loader->int_version) & 0xFFF);
87 		break;
88 	case 3:
89 		report ("%x.002.%03x\n",
90 			(int)(loader->int_version >> 12) & 0xF,
91 			(int)(loader->int_version) & 0xFFF);
92 		break;
93 	}
94 
95 	game.game_flags |= opt.amiga ? ID_AMIGA : 0;
96 	game.game_flags |= opt.agds ? ID_AGDS : 0;
97 
98 	if (game.game_flags & ID_AMIGA)
99 		report ("Amiga padded game detected.\n");
100 
101 	if (game.game_flags & ID_AGDS)
102 		report ("AGDS mode enabled.\n");
103 
104 	ec = loader->init ();		/* load vol files, etc */
105 
106 	if (ec == err_OK)
107 		ec = loader->load_objects(OBJECTS);
108 
109 	/* CM: ec= commented out, demogs has no words.tok */
110 	if(ec == err_OK)
111 		/*ec =*/ loader->load_words(WORDS);
112 
113 	/* FIXME: load IIgs instruments and samples */
114 	/* load_instruments("kq.sys16"); */
115 
116 	/* Load logic 0 into memory, set cache flag for logic 0 */
117 	if (ec == err_OK) {
118 		ec = loader->load_resource (rLOGIC, 0);
119 		game.dir_logic[0].flags |= RES_CACHED;	/* keep this one cached */
120 	}
121 
122 	/* if cached, enable caching options */
123 	if (opt.cache) {
124 		for (i = 0; i < MAX_DIRS; i++) {
125 			game.dir_logic[i].flags |= RES_CACHED;
126 			game.dir_pic[i].flags |= RES_CACHED;
127 			game.dir_view[i].flags |= RES_CACHED;
128 			game.dir_sound[i].flags |= RES_CACHED;
129 		}
130 	}
131 
132 	/* if forced, load all cacheable objects */
133 	if (opt.forceload && ec == err_OK) {
134 		for(i = 0; i < MAX_DIRS; i++) {
135 			loader->load_resource (rLOGIC, i);
136 			loader->load_resource (rPICTURE, i);
137 			loader->load_resource (rVIEW, i);
138 		}
139 		printf("\n");
140 	}
141 
142 	return ec;
143 }
144 
145 
146 /* unload all resources */
unload_resources()147 static void unload_resources ()
148 {
149 	int i;
150 
151 	for(i = 0; i < MAX_DIRS; i++) {
152 		game.dir_view[i].flags &= ~RES_CACHED;	/* clear cache flag */
153 		loader->unload_resource (rVIEW, i);	/* free view */
154 
155 		game.dir_pic[i].flags &= ~RES_CACHED;	/* clear cache flag */
156 		loader->unload_resource (rPICTURE, i);	/* free resource */
157 
158 		game.dir_logic[i].flags &= ~RES_CACHED;	/* clear cache flag */
159 		loader->unload_resource (rLOGIC, i);	/* free resource */
160 
161 		game.dir_sound[i].flags &= ~RES_CACHED;	/* clear cache flag */
162 		loader->unload_resource (rSOUND, i);	/* free resource */
163 	}
164 }
165 
166 
agi_deinit()167 int agi_deinit ()
168 {
169 	int ec;
170 
171 	clean_input ();			/* remove all words from memory */
172 	deinit_menus ();		/* unload the menus */
173 	unload_resources ();		/* unload resources in memory */
174 	ec = loader->deinit ();
175 	unload_objects();
176 	unload_words();
177 
178 	clear_image_stack();
179 
180 	return ec;
181 }
182 
183 
agi_detect_game(char * gn)184 int agi_detect_game (char *gn)
185 {
186 	int ec = err_OK;
187 
188 	_D ("(gn = %s)", gn);
189 	if (gn == NULL)		/* assume current directory */
190 		gn = get_current_directory ();
191 
192 #ifndef PALMOS
193 	loader = &agi_v2;
194 	ec = loader->detect_game (gn);
195 
196 	if (ec != err_OK) {
197 		loader = &agi_v3;
198 		ec = loader->detect_game (gn);
199 	}
200 
201 #else
202 	loader = &agi_v4;
203 	ec = loader->detect_game(gn);
204 #endif
205 
206 	return ec;
207 }
208 
209 
agi_version()210 int agi_version ()
211 {
212 	return loader->version;
213 }
214 
215 
agi_get_release()216 int agi_get_release ()
217 {
218 	return loader->int_version;
219 }
220 
221 
agi_set_release(int n)222 void agi_set_release (int n)
223 {
224 	loader->int_version = n;
225 }
226 
227 
agi_load_resource(int r,int n)228 int agi_load_resource (int r, int n)
229 {
230 	int i;
231 
232 	i = loader->load_resource (r, n);
233 #ifdef DISABLE_COPYPROTECTION
234 	if (r == rLOGIC)
235 		patch_logic (n);
236 #endif
237 
238 	return i;
239 }
240 
241 
agi_unload_resource(int r,int n)242 int agi_unload_resource (int r, int n)
243 {
244 	return loader->unload_resource (r, n);
245 }
246 
247