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/alan2/types.h"
24 #include "glk/alan2/main.h"
25 #include "glk/alan2/reverse.h"
26 
27 namespace Glk {
28 namespace Alan2 {
29 
30 /*----------------------------------------------------------------------
31 
32   reversed()
33 
34   Return the reversed bytes in the Aword
35 
36 */
reversed(Aword w)37 Aword reversed(Aword w /* IN - The ACODE word to swap bytes of */) {
38 	Aword s;                      /* The swapped ACODE word */
39 	char *wp, *sp;
40 
41 	wp = (char *) &w;
42 	sp = (char *) &s;
43 
44 	for (uint i = 0; i < sizeof(Aword); i++)
45 		sp[sizeof(Aword) - 1 - i] = wp[i];
46 
47 	return s;
48 }
49 
reverse(Aword * w)50 void reverse(Aword *w /* IN - The ACODE word to reverse bytes in */) {
51 	*w = reversed(*w);
52 }
53 
reverseTable(Aword adr,int len)54 static void reverseTable(Aword adr, int len) {
55 	Aword *e = &memory[adr];
56 	int i;
57 
58 	if (adr != 0)
59 		while (!endOfTable(e)) {
60 			for (i = 0; i < len / (int)sizeof(Aword); i++) {
61 				reverse(e);
62 				e++;
63 			}
64 		}
65 }
66 
reverseStms(Aword adr)67 static void reverseStms(Aword adr) {
68 	Aword *e = &memory[adr];
69 
70 	if (adr != 0)
71 		while (TRUE) {
72 			reverse(e);
73 			if (*e == ((Aword)C_STMOP << 28 | (Aword)I_RETURN)) break;
74 			e++;
75 		}
76 }
77 
reverseMsgs(Aword adr)78 static void reverseMsgs(Aword adr) {
79 	MsgElem *e = (MsgElem *) &memory[adr];
80 
81 	if (adr != 0 && !endOfTable(e)) {
82 		reverseTable(adr, sizeof(MsgElem));
83 		while (!endOfTable(e)) {
84 			reverseStms(e->stms);
85 			e++;
86 		}
87 	}
88 }
89 
reverseWrds(Aword adr)90 static void reverseWrds(Aword adr) {
91 	WrdElem *e = (WrdElem *) &memory[adr];
92 
93 	if (adr != 0 && !endOfTable(e)) {
94 		reverseTable(adr, sizeof(WrdElem));
95 		while (!endOfTable(e)) {
96 			if ((e->_class & (1L << WRD_SYN)) == 0) { /* Do not do this for synonyms */
97 				reverseTable(e->adjrefs, sizeof(Aword));
98 				reverseTable(e->nounrefs, sizeof(Aword));
99 			}
100 			e++;
101 		}
102 	}
103 }
104 
reverseChks(Aword adr)105 static void reverseChks(Aword adr) {
106 	ChkElem *e = (ChkElem *) &memory[adr];
107 
108 	if (adr != 0 && !endOfTable(e)) {
109 		reverseTable(adr, sizeof(ChkElem));
110 		while (!endOfTable(e)) {
111 			reverseStms(e->exp);
112 			reverseStms(e->stms);
113 			e++;
114 		}
115 	}
116 }
117 
reverseAlts(Aword adr)118 static void reverseAlts(Aword adr) {
119 	AltElem *e = (AltElem *)&memory[adr];
120 
121 	if (adr != 0 && !endOfTable(e) && !e->done) {
122 		reverseTable(adr, sizeof(AltElem));
123 		e->done = TRUE;
124 		while (!endOfTable(e)) {
125 			reverseChks(e->checks);
126 			reverseStms(e->action);
127 			e++;
128 		}
129 	}
130 }
131 
reverseVrbs(Aword adr)132 static void reverseVrbs(Aword adr) {
133 	VrbElem *e = (VrbElem *)&memory[adr];
134 
135 	if (adr != 0 && !endOfTable(e)) {
136 		reverseTable(adr, sizeof(VrbElem));
137 		while (!endOfTable(e)) {
138 			reverseAlts(e->alts);
139 			e++;
140 		}
141 	}
142 }
143 
reverseSteps(Aword adr)144 static void reverseSteps(Aword adr) {
145 	StepElem *e = (StepElem *) &memory[adr];
146 
147 	if (adr != 0 && !endOfTable(e)) {
148 		reverseTable(adr, sizeof(StepElem));
149 		while (!endOfTable(e)) {
150 			reverseStms(e->exp);
151 			reverseStms(e->stm);
152 			e++;
153 		}
154 	}
155 }
156 
reverseScrs(Aword adr)157 static void reverseScrs(Aword adr) {
158 	ScrElem *e = (ScrElem *) &memory[adr];
159 
160 	if (adr != 0 && !endOfTable(e)) {
161 		reverseTable(adr, sizeof(ScrElem));
162 		while (!endOfTable(e)) {
163 			reverseStms(e->dscr);
164 			reverseSteps(e->steps);
165 			e++;
166 		}
167 	}
168 }
169 
reverseActs(Aword adr)170 static void reverseActs(Aword adr) {
171 	ActElem *e = (ActElem *) &memory[adr];
172 
173 	if (adr != 0 && !endOfTable(e)) {
174 		reverseTable(adr, sizeof(ActElem));
175 		while (!endOfTable(e)) {
176 			reverseStms(e->nam);
177 			reverseTable(e->atrs, sizeof(AtrElem));
178 			reverseScrs(e->scradr);
179 			reverseVrbs(e->vrbs);
180 			reverseStms(e->dscr);
181 			e++;
182 		}
183 	}
184 }
185 
reverseObjs(Aword adr,Boolean v2_5)186 static void reverseObjs(Aword adr, Boolean v2_5) {
187 	ObjElem *e = (ObjElem *) &memory[adr];
188 	ObjElem25 *e25 = (ObjElem25 *) &memory[adr];
189 
190 	if (v2_5) {
191 		if (adr != 0 && !endOfTable(e25)) {
192 			reverseTable(adr, sizeof(ObjElem25));
193 			while (!endOfTable(e25)) {
194 				reverseTable(e25->atrs, sizeof(AtrElem));
195 				reverseVrbs(e25->vrbs);
196 				reverseStms(e25->dscr1);
197 				reverseStms(e25->dscr2);
198 				e25++;
199 			}
200 		}
201 	} else {
202 		if (adr != 0 && !endOfTable(e)) {
203 			reverseTable(adr, sizeof(ObjElem));
204 			while (!endOfTable(e)) {
205 				reverseTable(e->atrs, sizeof(AtrElem));
206 				reverseVrbs(e->vrbs);
207 				reverseStms(e->art);
208 				reverseStms(e->dscr1);
209 				reverseStms(e->dscr2);
210 				e++;
211 			}
212 		}
213 	}
214 }
215 
reverseExts(Aword adr)216 static void reverseExts(Aword adr) {
217 	ExtElem *e = (ExtElem *) &memory[adr];
218 
219 	if (adr != 0 && !endOfTable(e)) {
220 		reverseTable(adr, sizeof(ExtElem));
221 		while (!endOfTable(e)) {
222 			if (!e->done) {
223 				reverseChks(e->checks);
224 				reverseStms(e->action);
225 			}
226 			e++;
227 		}
228 	}
229 }
230 
reverseLocs(Aword adr)231 static void reverseLocs(Aword adr) {
232 	LocElem *e = (LocElem *) &memory[adr];
233 
234 	if (adr != 0 && !endOfTable(e)) {
235 		reverseTable(adr, sizeof(LocElem));
236 		while (!endOfTable(e)) {
237 			reverseStms(e->nams);
238 			reverseStms(e->dscr);
239 			reverseStms(e->does);
240 			reverseTable(e->atrs, sizeof(AtrElem));
241 			reverseExts(e->exts);
242 			reverseVrbs(e->vrbs);
243 			e++;
244 		}
245 	}
246 }
247 
reverseClas(Aword adr)248 static void reverseClas(Aword adr) {
249 	ClaElem *e = (ClaElem *) &memory[adr];
250 
251 	if (adr != 0 && !endOfTable(e)) {
252 		reverseTable(adr, sizeof(ClaElem));
253 		while (!endOfTable(e)) {
254 			reverseStms(e->stms);
255 			e++;
256 		}
257 	}
258 	if (adr)
259 		reverse(&((Aword *)e)[1]);  /* The verb code is stored after the table */
260 }
261 
reverseElms(Aword adr)262 static void reverseElms(Aword adr) {
263 	ElmElem *e = (ElmElem *) &memory[adr];
264 
265 	if (adr != 0 && !endOfTable(e)) {
266 		reverseTable(adr, sizeof(ElmElem));
267 		while (!endOfTable(e)) {
268 			if (e->code == EOS) reverseClas(e->next);
269 			else reverseElms(e->next);
270 			e++;
271 		}
272 	}
273 }
274 
reverseStxs(Aword adr)275 static void reverseStxs(Aword adr) {
276 	StxElem *e = (StxElem *) &memory[adr];
277 
278 	if (adr != 0 && !endOfTable(e)) {
279 		reverseTable(adr, sizeof(StxElem));
280 		while (!endOfTable(e)) {
281 			reverseElms(e->elms);
282 			e++;
283 		}
284 	}
285 }
286 
reverseEvts(Aword adr)287 static void reverseEvts(Aword adr) {
288 	EvtElem *e = (EvtElem *) &memory[adr];
289 
290 	if (adr != 0 && !endOfTable(e)) {
291 		reverseTable(adr, sizeof(EvtElem));
292 		while (!endOfTable(e)) {
293 			reverseStms(e->code);
294 			e++;
295 		}
296 	}
297 }
298 
reverseLims(Aword adr)299 static void reverseLims(Aword adr) {
300 	LimElem *e = (LimElem *) &memory[adr];
301 
302 	if (adr != 0 && !endOfTable(e)) {
303 		reverseTable(adr, sizeof(LimElem));
304 		while (!endOfTable(e)) {
305 			reverseStms(e->stms);
306 			e++;
307 		}
308 	}
309 }
310 
reverseCnts(Aword adr)311 static void reverseCnts(Aword adr) {
312 	CntElem *e = (CntElem *) &memory[adr];
313 
314 	if (adr != 0 && !endOfTable(e)) {
315 		reverseTable(adr, sizeof(CntElem));
316 		while (!endOfTable(e)) {
317 			reverseLims(e->lims);
318 			reverseStms(e->header);
319 			reverseStms(e->empty);
320 			reverseStms(e->nam);
321 			e++;
322 		}
323 	}
324 }
325 
reverseRuls(Aword adr)326 static void reverseRuls(Aword adr) {
327 	RulElem *e = (RulElem *) &memory[adr];
328 
329 	if (adr != 0 && !endOfTable(e)) {
330 		reverseTable(adr, sizeof(RulElem));
331 		while (!endOfTable(e)) {
332 			reverseStms(e->exp);
333 			reverseStms(e->stms);
334 			e++;
335 		}
336 	}
337 }
338 
339 
340 /*----------------------------------------------------------------------
341 
342   reverseHdr()
343 
344   Reverse the header structure.
345 
346 */
reverseHdr(AcdHdr * hdr)347 void reverseHdr(AcdHdr *hdr) {
348 	// Reverse all words in the header except the first (version marking)
349 	for (uint i = 1; i < sizeof(AcdHdr) / sizeof(Aword); i++)
350 		reverse(&((Aword *)hdr)[i]);
351 }
352 
353 /*----------------------------------------------------------------------
354 
355   reverseACD()
356 
357   Traverse all the data structures and reverse all integers.
358   Only performed in architectures with reversed byte ordering, which
359   makes the .ACD files fully compatible across architectures
360 
361   */
reverseACD(Boolean v2_5)362 void reverseACD(Boolean v2_5) {
363 	reverseHdr(header);
364 	reverseWrds(header->dict);
365 	reverseTable(header->oatrs, sizeof(AtrElem));
366 	reverseTable(header->latrs, sizeof(AtrElem));
367 	reverseTable(header->aatrs, sizeof(AtrElem));
368 	reverseActs(header->acts);
369 	reverseObjs(header->objs, v2_5);
370 	reverseLocs(header->locs);
371 	reverseStxs(header->stxs);
372 	reverseVrbs(header->vrbs);
373 	reverseEvts(header->evts);
374 	reverseCnts(header->cnts);
375 	reverseRuls(header->ruls);
376 	reverseTable(header->init, sizeof(IniElem));
377 	reverseStms(header->start);
378 	reverseMsgs(header->msgs);
379 
380 	reverseTable(header->scores, sizeof(Aword));
381 	reverseTable(header->freq, sizeof(Aword));
382 }
383 
384 } // End of namespace Alan2
385 } // End of namespace Glk
386