scummvm/engines/glk/alan2/reverse.cpp

386 lines
8.4 KiB
C++
Raw Normal View History

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "glk/alan2/types.h"
#include "glk/alan2/main.h"
#include "glk/alan2/reverse.h"
namespace Glk {
namespace Alan2 {
/*----------------------------------------------------------------------
reversed()
Return the reversed bytes in the Aword
*/
Aword reversed(Aword w /* IN - The ACODE word to swap bytes of */) {
2019-06-22 03:43:17 +01:00
Aword s; /* The swapped ACODE word */
char *wp, *sp;
2019-06-22 03:43:17 +01:00
wp = (char *) &w;
sp = (char *) &s;
2019-06-22 04:15:20 +01:00
for (uint i = 0; i < sizeof(Aword); i++)
2019-06-22 03:43:17 +01:00
sp[sizeof(Aword) - 1 - i] = wp[i];
return s;
}
void reverse(Aword *w /* IN - The ACODE word to reverse bytes in */) {
2019-06-22 03:43:17 +01:00
*w = reversed(*w);
}
static void reverseTable(Aword adr, int len) {
2019-06-22 03:43:17 +01:00
Aword *e = &memory[adr];
int i;
if (adr != 0)
while (!endOfTable(e)) {
for (i = 0; i < len / (int)sizeof(Aword); i++) {
reverse(e);
e++;
}
}
}
static void reverseStms(Aword adr) {
2019-06-22 03:43:17 +01:00
Aword *e = &memory[adr];
if (adr != 0)
while (TRUE) {
reverse(e);
if (*e == ((Aword)C_STMOP << 28 | (Aword)I_RETURN)) break;
e++;
}
}
static void reverseMsgs(Aword adr) {
2019-06-22 03:43:17 +01:00
MsgElem *e = (MsgElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(MsgElem));
while (!endOfTable(e)) {
reverseStms(e->stms);
e++;
}
}
}
static void reverseWrds(Aword adr) {
2019-06-22 03:43:17 +01:00
WrdElem *e = (WrdElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(WrdElem));
while (!endOfTable(e)) {
if ((e->_class & (1L << WRD_SYN)) == 0) { /* Do not do this for synonyms */
reverseTable(e->adjrefs, sizeof(Aword));
reverseTable(e->nounrefs, sizeof(Aword));
}
e++;
}
}
}
static void reverseChks(Aword adr) {
2019-06-22 03:43:17 +01:00
ChkElem *e = (ChkElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ChkElem));
while (!endOfTable(e)) {
reverseStms(e->exp);
reverseStms(e->stms);
e++;
}
}
}
static void reverseAlts(Aword adr) {
2019-06-22 03:43:17 +01:00
AltElem *e = (AltElem *)&memory[adr];
if (adr != 0 && !endOfTable(e) && !e->done) {
reverseTable(adr, sizeof(AltElem));
e->done = TRUE;
while (!endOfTable(e)) {
reverseChks(e->checks);
reverseStms(e->action);
e++;
}
}
}
static void reverseVrbs(Aword adr) {
2019-06-22 03:43:17 +01:00
VrbElem *e = (VrbElem *)&memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(VrbElem));
while (!endOfTable(e)) {
reverseAlts(e->alts);
e++;
}
}
}
static void reverseSteps(Aword adr) {
2019-06-22 03:43:17 +01:00
StepElem *e = (StepElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(StepElem));
while (!endOfTable(e)) {
reverseStms(e->exp);
reverseStms(e->stm);
e++;
}
}
}
static void reverseScrs(Aword adr) {
2019-06-22 03:43:17 +01:00
ScrElem *e = (ScrElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ScrElem));
while (!endOfTable(e)) {
reverseStms(e->dscr);
reverseSteps(e->steps);
e++;
}
}
}
static void reverseActs(Aword adr) {
2019-06-22 03:43:17 +01:00
ActElem *e = (ActElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ActElem));
while (!endOfTable(e)) {
reverseStms(e->nam);
reverseTable(e->atrs, sizeof(AtrElem));
reverseScrs(e->scradr);
reverseVrbs(e->vrbs);
reverseStms(e->dscr);
e++;
}
}
}
static void reverseObjs(Aword adr, Boolean v2_5) {
2019-06-22 03:43:17 +01:00
ObjElem *e = (ObjElem *) &memory[adr];
ObjElem25 *e25 = (ObjElem25 *) &memory[adr];
if (v2_5) {
if (adr != 0 && !endOfTable(e25)) {
reverseTable(adr, sizeof(ObjElem25));
while (!endOfTable(e25)) {
reverseTable(e25->atrs, sizeof(AtrElem));
reverseVrbs(e25->vrbs);
reverseStms(e25->dscr1);
reverseStms(e25->dscr2);
e25++;
}
}
} else {
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ObjElem));
while (!endOfTable(e)) {
reverseTable(e->atrs, sizeof(AtrElem));
reverseVrbs(e->vrbs);
reverseStms(e->art);
reverseStms(e->dscr1);
reverseStms(e->dscr2);
e++;
}
}
}
}
static void reverseExts(Aword adr) {
2019-06-22 03:43:17 +01:00
ExtElem *e = (ExtElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ExtElem));
while (!endOfTable(e)) {
if (!e->done) {
reverseChks(e->checks);
reverseStms(e->action);
}
e++;
}
}
}
static void reverseLocs(Aword adr) {
2019-06-22 03:43:17 +01:00
LocElem *e = (LocElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(LocElem));
while (!endOfTable(e)) {
reverseStms(e->nams);
reverseStms(e->dscr);
reverseStms(e->does);
reverseTable(e->atrs, sizeof(AtrElem));
reverseExts(e->exts);
reverseVrbs(e->vrbs);
e++;
}
}
}
static void reverseClas(Aword adr) {
2019-06-22 03:43:17 +01:00
ClaElem *e = (ClaElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ClaElem));
while (!endOfTable(e)) {
reverseStms(e->stms);
e++;
}
}
if (adr)
reverse(&((Aword *)e)[1]); /* The verb code is stored after the table */
}
static void reverseElms(Aword adr) {
2019-06-22 03:43:17 +01:00
ElmElem *e = (ElmElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(ElmElem));
while (!endOfTable(e)) {
if (e->code == EOS) reverseClas(e->next);
else reverseElms(e->next);
e++;
}
}
}
static void reverseStxs(Aword adr) {
2019-06-22 03:43:17 +01:00
StxElem *e = (StxElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(StxElem));
while (!endOfTable(e)) {
reverseElms(e->elms);
e++;
}
}
}
static void reverseEvts(Aword adr) {
2019-06-22 03:43:17 +01:00
EvtElem *e = (EvtElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(EvtElem));
while (!endOfTable(e)) {
reverseStms(e->code);
e++;
}
}
}
static void reverseLims(Aword adr) {
2019-06-22 03:43:17 +01:00
LimElem *e = (LimElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(LimElem));
while (!endOfTable(e)) {
reverseStms(e->stms);
e++;
}
}
}
static void reverseCnts(Aword adr) {
2019-06-22 03:43:17 +01:00
CntElem *e = (CntElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(CntElem));
while (!endOfTable(e)) {
reverseLims(e->lims);
reverseStms(e->header);
reverseStms(e->empty);
reverseStms(e->nam);
e++;
}
}
}
static void reverseRuls(Aword adr) {
2019-06-22 03:43:17 +01:00
RulElem *e = (RulElem *) &memory[adr];
if (adr != 0 && !endOfTable(e)) {
reverseTable(adr, sizeof(RulElem));
while (!endOfTable(e)) {
reverseStms(e->exp);
reverseStms(e->stms);
e++;
}
}
}
/*----------------------------------------------------------------------
reverseHdr()
Reverse the header structure.
*/
void reverseHdr(AcdHdr *hdr) {
2019-06-22 04:15:20 +01:00
// Reverse all words in the header except the first (version marking)
for (uint i = 1; i < sizeof(AcdHdr) / sizeof(Aword); i++)
2019-06-22 03:43:17 +01:00
reverse(&((Aword *)hdr)[i]);
}
/*----------------------------------------------------------------------
reverseACD()
Traverse all the data structures and reverse all integers.
Only performed in architectures with reversed byte ordering, which
makes the .ACD files fully compatible across architectures
*/
void reverseACD(Boolean v2_5) {
2019-06-22 03:43:17 +01:00
reverseHdr(header);
reverseWrds(header->dict);
reverseTable(header->oatrs, sizeof(AtrElem));
reverseTable(header->latrs, sizeof(AtrElem));
reverseTable(header->aatrs, sizeof(AtrElem));
reverseActs(header->acts);
reverseObjs(header->objs, v2_5);
reverseLocs(header->locs);
reverseStxs(header->stxs);
reverseVrbs(header->vrbs);
reverseEvts(header->evts);
reverseCnts(header->cnts);
reverseRuls(header->ruls);
reverseTable(header->init, sizeof(IniElem));
reverseStms(header->start);
reverseMsgs(header->msgs);
reverseTable(header->scores, sizeof(Aword));
reverseTable(header->freq, sizeof(Aword));
}
} // End of namespace Alan2
} // End of namespace Glk