1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "glk/alan3/params.h"
24 #include "glk/alan3/glkio.h"
25 #include "glk/alan3/lists.h"
26 #include "glk/alan3/literal.h"
27 #include "glk/alan3/memory.h"
28 #include "glk/alan3/syserr.h"
29
30 namespace Glk {
31 namespace Alan3 {
32
33 /* PUBLIC DATA */
34 Parameter *globalParameters = NULL;
35
36 /*======================================================================*/
newParameter(int id)37 Parameter *newParameter(int id) {
38 Parameter *parameter = NEW(Parameter);
39 parameter->instance = id;
40 parameter->candidates = NULL;
41
42 return parameter;
43 }
44
45
46 /*======================================================================*/
newParameterArray(void)47 Parameter *newParameterArray(void) {
48 Parameter *newArray = (Parameter *)allocate((MAXINSTANCE + 1) * sizeof(Parameter));
49 setEndOfArray(newArray);
50 return newArray;
51 }
52
53
54 /*======================================================================*/
freeParameterArray(ParameterArray arrayPointer)55 void freeParameterArray(ParameterArray arrayPointer) {
56 Parameter *p;
57
58 for (p = arrayPointer; !isEndOfArray(p); p++)
59 if (p->candidates != NULL)
60 freeParameterArray(p->candidates);
61 deallocate(arrayPointer);
62 }
63
64
65 /*======================================================================*/
ensureParameterArrayAllocated(ParameterArray currentArray)66 Parameter *ensureParameterArrayAllocated(ParameterArray currentArray) {
67 if (currentArray == NULL)
68 return newParameterArray();
69 else {
70 clearParameterArray(currentArray);
71 return currentArray;
72 }
73 }
74
75
76 /*======================================================================*/
parameterArrayIsEmpty(ParameterArray array)77 bool parameterArrayIsEmpty(ParameterArray array) {
78 return array == NULL || lengthOfParameterArray(array) == 0;
79 }
80
81
82 /*======================================================================*/
clearParameter(Parameter * parameter)83 void clearParameter(Parameter *parameter) {
84 Parameter *candidates = parameter->candidates;
85 memset(parameter, 0, sizeof(Parameter));
86 parameter->candidates = candidates;
87 if (parameter->candidates != NULL)
88 clearParameterArray(parameter->candidates);
89 }
90
91
92 /*======================================================================*/
setGlobalParameters(ParameterArray newParameters)93 void setGlobalParameters(ParameterArray newParameters) {
94 if (globalParameters == NULL)
95 globalParameters = newParameterArray();
96 copyParameterArray(globalParameters, newParameters);
97 }
98
99
100 /*======================================================================*/
getGlobalParameters(void)101 Parameter *getGlobalParameters(void) {
102 if (globalParameters == NULL)
103 globalParameters = newParameterArray();
104 return globalParameters;
105 }
106
107
108 /*======================================================================*/
getGlobalParameter(int parameterIndex)109 Parameter *getGlobalParameter(int parameterIndex) {
110 return &globalParameters[parameterIndex];
111 }
112
113
114 /*======================================================================*/
findEndOfParameterArray(Parameter * parameters)115 Parameter *findEndOfParameterArray(Parameter *parameters) {
116 Parameter *parameter;
117 for (parameter = parameters; !isEndOfArray(parameter); parameter++);
118 return parameter;
119 }
120
121
122 /*======================================================================*/
123 /* A parameter position with code == 0 means this is a multiple position.
124 * We must loop over this position (and replace it by each present in the
125 * matched list)
126 */
findMultiplePosition(Parameter parameters[])127 int findMultiplePosition(Parameter parameters[]) {
128 // TODO: this should look at the isAll and isExplicitMultiple flags instead
129 int multiplePosition;
130 for (multiplePosition = 0; !isEndOfArray(¶meters[multiplePosition]); multiplePosition++)
131 if (parameters[multiplePosition].instance == 0)
132 return multiplePosition;
133 return -1;
134 }
135
136
137 /*======================================================================*/
compressParameterArray(Parameter theArray[])138 void compressParameterArray(Parameter theArray[]) {
139 int i, j;
140
141 for (i = 0, j = 0; !isEndOfArray(&theArray[j]); j++)
142 if (theArray[j].instance != 0)
143 theArray[i++] = theArray[j];
144 setEndOfArray(&theArray[i]);
145 }
146
147
148 /*======================================================================*/
lengthOfParameterArray(Parameter theArray[])149 int lengthOfParameterArray(Parameter theArray[]) {
150 int i = 0;
151
152 if (theArray == NULL) return 0;
153
154 while (!isEndOfArray(&theArray[i]))
155 i++;
156 return i;
157 }
158
159
160 /*======================================================================*/
equalParameterArrays(Parameter parameters1[],Parameter parameters2[])161 bool equalParameterArrays(Parameter parameters1[], Parameter parameters2[]) {
162 int i;
163
164 if ((parameters1 == NULL) != (parameters2 == NULL))
165 return FALSE;
166 if (parameters1 == NULL) // Because then parameter2 is also NULL
167 return TRUE;
168 for (i = 0; !isEndOfArray(¶meters1[i]); i++) {
169 if (isEndOfArray(¶meters2[i])) return FALSE;
170 if (parameters1[i].instance != parameters2[i].instance) return FALSE;
171 }
172 return isEndOfArray(¶meters2[i]);
173 }
174
175
176 /*======================================================================*/
inParameterArray(Parameter theArray[],Aword theCode)177 bool inParameterArray(Parameter theArray[], Aword theCode) {
178 int i;
179
180 for (i = 0; !isEndOfArray(&theArray[i]) && theArray[i].instance != theCode; i++);
181 return (theArray[i].instance == theCode);
182 }
183
184
185 /*======================================================================*/
copyParameter(Parameter * to,Parameter * from)186 void copyParameter(Parameter *to, Parameter *from) {
187 Parameter *toCandidates = to->candidates;
188
189 *to = *from;
190 if (from->candidates != NULL) {
191 if (toCandidates == NULL)
192 to->candidates = newParameterArray();
193 else
194 to->candidates = toCandidates;
195 copyParameterArray(to->candidates, from->candidates);
196 } else if (toCandidates != NULL)
197 freeParameterArray(toCandidates);
198 }
199
200
201 /*======================================================================*/
addParameterToParameterArray(ParameterArray theArray,Parameter * theParameter)202 void addParameterToParameterArray(ParameterArray theArray, Parameter *theParameter) {
203 if (theArray == NULL) syserr("Adding to null parameter array");
204
205 uint i;
206
207 for (i = 0; !isEndOfArray(&theArray[i]) && i < MAXINSTANCE; i++)
208 ;
209 if (isEndOfArray(&theArray[i])) {
210 copyParameter(&theArray[i], theParameter);
211 setEndOfArray(&theArray[i + 1]);
212 } else
213 syserr("Couldn't find end of ParameterArray");
214 }
215
216
217 /*======================================================================*/
copyParameterArray(ParameterArray to,ParameterArray from)218 void copyParameterArray(ParameterArray to, ParameterArray from) {
219 int i;
220
221 if (to == NULL && from == NULL) return;
222
223 if (to == NULL)
224 syserr("Copying to null parameter array");
225 else {
226 clearParameterArray(to);
227 for (i = 0; !isEndOfArray(&from[i]); i++)
228 addParameterToParameterArray(to, &from[i]);
229 }
230 }
231
232
233 /*======================================================================*/
subtractParameterArrays(Parameter theArray[],Parameter remove[])234 void subtractParameterArrays(Parameter theArray[], Parameter remove[]) {
235 int i;
236
237 if (remove == NULL) return;
238
239 for (i = 0; !isEndOfArray(&theArray[i]); i++)
240 if (inParameterArray(remove, theArray[i].instance))
241 theArray[i].instance = 0; /* Mark empty */
242 compressParameterArray(theArray);
243 }
244
245
246 /*======================================================================*/
clearParameterArray(Parameter theArray[])247 void clearParameterArray(Parameter theArray[]) {
248 Parameter *p = &theArray[0];
249
250 for (p = &theArray[0]; !isEndOfArray(p); p++)
251 clearParameter(p);
252 setEndOfArray(theArray);
253 }
254
255
256 /*======================================================================*/
intersectParameterArrays(Parameter one[],Parameter other[])257 void intersectParameterArrays(Parameter one[], Parameter other[]) {
258 int i, last = 0;
259
260
261 for (i = 0; !isEndOfArray(&one[i]); i++)
262 if (inParameterArray(other, one[i].instance))
263 one[last++] = one[i];
264 setEndOfArray(&one[last]);
265 }
266
267
268 /*======================================================================*/
copyReferencesToParameterArray(Aint references[],Parameter parameterArray[])269 void copyReferencesToParameterArray(Aint references[], Parameter parameterArray[]) {
270 int i;
271
272 for (i = 0; !isEndOfArray(&references[i]); i++) {
273 parameterArray[i].instance = references[i];
274 parameterArray[i].firstWord = EOD; /* Ensure that there is no word that can be used */
275 }
276 setEndOfArray(¶meterArray[i]);
277 }
278
279
280 /*======================================================================*/
addParameterForInstance(Parameter * parameters,int instance)281 void addParameterForInstance(Parameter *parameters, int instance) {
282 Parameter *parameter = findEndOfParameterArray(parameters);
283
284 parameter->instance = instance;
285 parameter->useWords = FALSE;
286
287 setEndOfArray(parameter + 1);
288 }
289
290
291 /*======================================================================*/
addParameterForInteger(ParameterArray parameters,int value)292 void addParameterForInteger(ParameterArray parameters, int value) {
293 Parameter *parameter = findEndOfParameterArray(parameters);
294
295 createIntegerLiteral(value);
296 parameter->instance = instanceFromLiteral(litCount);
297 parameter->useWords = FALSE;
298
299 setEndOfArray(parameter + 1);
300 }
301
302 /*======================================================================*/
addParameterForString(Parameter * parameters,char * value)303 void addParameterForString(Parameter *parameters, char *value) {
304 Parameter *parameter = findEndOfParameterArray(parameters);
305
306 createStringLiteral(value);
307 parameter->instance = instanceFromLiteral(litCount);
308 parameter->useWords = FALSE;
309
310 setEndOfArray(parameter + 1);
311 }
312
313 /*======================================================================*/
printParameterArray(Parameter parameters[])314 void printParameterArray(Parameter parameters[]) {
315 int i;
316 printf("[");
317 for (i = 0; !isEndOfArray(¶meters[i]); i++) {
318 printf("%d ", (int)parameters[i].instance);
319 }
320 printf("]\n");
321 }
322
323 } // End of namespace Alan3
324 } // End of namespace Glk
325