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