mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 20:01:25 +00:00
386 lines
8.4 KiB
C++
386 lines
8.4 KiB
C++
/* 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 */) {
|
|
Aword s; /* The swapped ACODE word */
|
|
char *wp, *sp;
|
|
|
|
wp = (char *) &w;
|
|
sp = (char *) &s;
|
|
|
|
for (uint i = 0; i < sizeof(Aword); i++)
|
|
sp[sizeof(Aword) - 1 - i] = wp[i];
|
|
|
|
return s;
|
|
}
|
|
|
|
void reverse(Aword *w /* IN - The ACODE word to reverse bytes in */) {
|
|
*w = reversed(*w);
|
|
}
|
|
|
|
static void reverseTable(Aword adr, int len) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
// Reverse all words in the header except the first (version marking)
|
|
for (uint i = 1; i < sizeof(AcdHdr) / sizeof(Aword); i++)
|
|
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) {
|
|
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
|