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