1 /*  Sarien - A Sierra AGI resource interpreter engine
2  *  Copyright (C) 1999,2001 Stuart George and Claudio Matsuoka
3  *
4  *  $Id: objects.c,v 1.18 2001/07/31 18:00:01 matt_hargett 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 #include "sarien.h"
15 #include "agi.h"
16 
17 extern int decode_objects(UINT8* mem, UINT32 flen);
18 
19 /**
20  * AGI object
21  */
22 struct agi_object {
23         int location;
24         char *name;
25 };
26 
27 static struct agi_object *objects;		/* objects in the game */
28 
decode_objects(UINT8 * mem,UINT32 flen)29 int decode_objects(UINT8* mem, UINT32 flen)
30 {
31 #ifndef PALMOS
32 	unsigned int i, so, padsize;
33 
34 	padsize = game.game_flags & ID_AMIGA ? 4 : 3;
35 
36 	game.num_objects = 0;
37 	objects = NULL;
38 
39 	/* check if first pointer exceeds file size
40 	 * if so, its encrypted, else it is not
41 	 */
42 
43 	if (lohi_getword (mem) > flen) {
44 		report ("Decrypting objects... ");
45 		decrypt (mem, flen);
46 		report ("done.\n");
47 	}
48 
49 	/* alloc memory for object list
50 	 * byte 3 = number of animated objects. this is ignored.. ??
51 	 */
52 	if (lohi_getword(mem) / padsize >= 256)
53 	{
54 #ifdef AGDS_SUPPORT
55     		/* die with no error! AGDS game needs not to die to work!! :( */
56 		return err_OK;
57 #else
58 		/* no AGDS support, die with error */
59 		return err_BadResource;
60 #endif
61 	}
62 
63 	game.num_objects = lohi_getword(mem) / padsize;
64 	_D ("num_objects = %d", game.num_objects);
65 
66     	if ((objects = calloc (game.num_objects, sizeof(struct agi_object))) == NULL) {
67     		return err_NotEnoughMemory;
68 	}
69 
70     	/* build the object list */
71     	for (i = 0, so = padsize; i < game.num_objects; i++, so += padsize) {
72 		(objects + i)->location = lohi_getbyte (mem + so + 2);
73     		if ((lohi_getword (mem + so) + padsize) < flen) {
74 			(objects+i)->name = strdup (mem +
75 				(lohi_getword (mem + so) + padsize));
76 	    	} else {
77 	    		printf ("ERROR: object %i name beyond object filesize! "
78 				"(%04x)\n", i, (lohi_getword (mem + so) + 3));
79 	    		(objects+i)->name = strdup ("");
80 	    	}
81     	}
82 	report ("Reading objects: %d objects read.\n", game.num_objects);
83 
84 #endif
85 	return err_OK;
86 
87 }
88 
load_objects(char * fname)89 int load_objects (char *fname)
90 {
91 #ifndef PALMOS
92 	FILE *fp;
93 	UINT32 flen;
94 	UINT8 *mem;
95 	char *path;
96 
97 	objects=NULL;
98 	game.num_objects = 0;
99 
100 	_D ("(fname = %s)", fname);
101 	path = fixpath (NO_GAMEDIR, fname);
102 	report ("Loading objects: %s\n", path);
103 
104 	if ((fp = fopen(path, "rb")) == NULL)
105 		return err_BadFileOpen;
106 
107 	fseek (fp, 0, SEEK_END);
108 	flen = ftell (fp);
109 	fseek (fp, 0, SEEK_SET);
110 
111 	if ((mem = calloc (1, flen + 32)) == NULL) {
112 		fclose (fp);
113 		return err_NotEnoughMemory;
114 	}
115 
116 	fread (mem, 1, flen, fp);
117 	fclose(fp);
118 
119 	decode_objects(mem, flen);
120 	free(mem);
121 #endif
122 	return err_OK;
123 }
124 
unload_objects()125 void unload_objects ()
126 {
127 	unsigned int i;
128 
129 	if (objects != NULL) {
130 		for (i = 0; i < game.num_objects; i++)
131 			free (objects[i].name);
132 		free (objects);
133 	}
134 }
135 
136 #ifdef OPT_LIST_OBJECTS
show_objects()137 int show_objects ()
138 {
139 	unsigned int i;
140 
141 	printf(" ID   Objects\n");
142 	for (i = 0; i < game.num_objects; i++)
143 		printf ("%3i - %s\n", (objects+i)->location, (objects+i)->name);
144 
145 	printf ("\n%i objects\n", game.num_objects);
146 
147 	return err_OK;
148 }
149 #endif
150 
object_set_location(unsigned int n,int i)151 void object_set_location (unsigned int n, int i)
152 {
153 	if (n >= game.num_objects) {
154 		report ("Error: Can't access object %d.", n);
155 		return;
156 	}
157 	objects[n].location = i;
158 }
159 
object_get_location(unsigned int n)160 int object_get_location (unsigned int n)
161 {
162 	if (n >= game.num_objects) {
163 		report ("Error: Can't access object %d.", n);
164 		return 0;
165 	}
166 	return objects[n].location;
167 }
168 
object_name(unsigned int n)169 char *object_name (unsigned int n)
170 {
171 	if (n >= game.num_objects) {
172 		report ("Error: Can't access object %d.", n);
173 		return "";
174 	}
175 	return objects[n].name;
176 }
177