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