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(&parameters[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(&parameters1[i]); i++) {
169 		if (isEndOfArray(&parameters2[i])) return FALSE;
170 		if (parameters1[i].instance != parameters2[i].instance) return FALSE;
171 	}
172 	return isEndOfArray(&parameters2[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(&parameterArray[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(&parameters[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