mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-08 02:42:34 +00:00
657 lines
16 KiB
C++
657 lines
16 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/alan3/types.h"
|
|
#include "glk/alan3/lists.h"
|
|
#include "glk/alan3/checkentry.h"
|
|
#include "glk/alan3/rules.h"
|
|
#include "glk/alan3/msg.h"
|
|
#include "glk/alan3/utils.h"
|
|
#include "glk/alan3/compatibility.h"
|
|
#include "glk/alan3/syserr.h"
|
|
#include "glk/alan3/memory.h"
|
|
|
|
namespace Glk {
|
|
namespace Alan3 {
|
|
|
|
extern Aword *memory;
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
static Aaddr memorySize = 0;
|
|
static Aword *addressesDone = NULL;
|
|
static int numberDone = 0;
|
|
static int doneSize = 0;
|
|
|
|
static bool alreadyDone(Aaddr address) {
|
|
int i;
|
|
|
|
if (address == 0) return TRUE;
|
|
|
|
/* Have we already done it? */
|
|
for (i = 0; i < numberDone; i++)
|
|
if (addressesDone[i] == address)
|
|
return TRUE;
|
|
|
|
if (doneSize == numberDone) {
|
|
doneSize += 100;
|
|
addressesDone = (Aword *)realloc(addressesDone, doneSize * sizeof(Aword));
|
|
}
|
|
addressesDone[numberDone] = address;
|
|
numberDone++;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
#define NATIVE(w) \
|
|
( (((Aword)((w)[3]) ) & 0x000000ff) \
|
|
| (((Aword)((w)[2]) << 8) & 0x0000ff00) \
|
|
| (((Aword)((w)[1]) << 16) & 0x00ff0000) \
|
|
| (((Aword)((w)[0]) << 24) & 0xff000000))
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
Aword reversed(Aword w) { /* IN - The ACODE word to swap bytes of */
|
|
#ifdef TRYNATIVE
|
|
return NATIVE(&w);
|
|
#else
|
|
Aword s; /* The swapped ACODE word */
|
|
char *wp, *sp;
|
|
uint i;
|
|
|
|
wp = (char *) &w;
|
|
sp = (char *) &s;
|
|
|
|
for (i = 0; i < sizeof(Aword); i++)
|
|
sp[sizeof(Aword) - 1 - i] = wp[i];
|
|
|
|
return s;
|
|
#endif
|
|
}
|
|
|
|
|
|
void reverseWord(Aword *w) { /* IN - The ACODE word to reverse bytes in */
|
|
*w = reversed(*w);
|
|
}
|
|
|
|
void reverse(Aword *w) { /* IN - The ACODE word to reverse bytes in */
|
|
if (w < &memory[0] || w > &memory[memorySize])
|
|
syserr("Reversing address outside of memory");
|
|
reverseWord(w);
|
|
}
|
|
|
|
|
|
static void reverseTable(Aword adr, int elementSize) {
|
|
Aword *e = &memory[adr];
|
|
uint i;
|
|
|
|
if (elementSize < (int)sizeof(Aword) || elementSize % (int)sizeof(Aword) != 0)
|
|
syserr("***Wrong size in 'reverseTable()' ***");
|
|
|
|
if (adr == 0) return;
|
|
|
|
while (!isEndOfArray(e)) {
|
|
for (i = 0; i < elementSize / sizeof(Aword); i++) {
|
|
reverse(e);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseStms(Aword adr) {
|
|
Aword *e = &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
while (TRUE) {
|
|
reverse(e);
|
|
if (*e == ((Aword)C_STMOP << 28 | (Aword)I_RETURN)) break;
|
|
e++;
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseMsgs(Aword adr) {
|
|
MessageEntry *e = (MessageEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(MessageEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseDictionary(Aword adr) {
|
|
DictionaryEntry *e = (DictionaryEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(DictionaryEntry));
|
|
while (!isEndOfArray(e)) {
|
|
if ((e->classBits & SYNONYM_BIT) == 0) { /* Do not do this for synonyms */
|
|
reverseTable(e->adjectiveRefs, sizeof(Aword));
|
|
reverseTable(e->nounRefs, sizeof(Aword));
|
|
reverseTable(e->pronounRefs, sizeof(Aword));
|
|
}
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseChks(Aword adr) {
|
|
CheckEntry *e = (CheckEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(CheckEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->exp);
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseAlts(Aword adr) {
|
|
AltEntry *e = (AltEntry *)&memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(AltEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseChks(e->checks);
|
|
reverseStms(e->action);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseVerbs(Aword adr) {
|
|
VerbEntry *e = (VerbEntry *)&memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(VerbEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseAlts(e->alts);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseSteps(Aword adr) {
|
|
StepEntry *e = (StepEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(StepEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->after);
|
|
reverseStms(e->exp);
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseScrs(Aword adr) {
|
|
ScriptEntry *e = (ScriptEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ScriptEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->description);
|
|
reverseSteps(e->steps);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseExits(Aword adr) {
|
|
ExitEntry *e = (ExitEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ExitEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseChks(e->checks);
|
|
reverseStms(e->action);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseClasses(Aword adr) {
|
|
ClassEntry *e = (ClassEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ClassEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->name);
|
|
reverseStms(e->initialize);
|
|
reverseChks(e->descriptionChecks);
|
|
reverseStms(e->description);
|
|
reverseStms(e->entered);
|
|
reverseStms(e->definite.address);
|
|
reverseStms(e->indefinite.address);
|
|
reverseStms(e->negative.address);
|
|
reverseStms(e->mentioned);
|
|
reverseVerbs(e->verbs);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseInstances(Aword adr) {
|
|
InstanceEntry *e = (InstanceEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(InstanceEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->name);
|
|
reverseTable(e->initialAttributes, sizeof(AttributeHeaderEntry));
|
|
reverseStms(e->initialize);
|
|
reverseStms(e->definite.address);
|
|
reverseStms(e->indefinite.address);
|
|
reverseStms(e->negative.address);
|
|
reverseStms(e->mentioned);
|
|
reverseChks(e->checks);
|
|
reverseStms(e->description);
|
|
reverseVerbs(e->verbs);
|
|
reverseStms(e->entered);
|
|
reverseExits(e->exits);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseRestrictions(Aword adr) {
|
|
RestrictionEntry *e = (RestrictionEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(RestrictionEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseElms(Aword adr) {
|
|
ElementEntry *e = (ElementEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ElementEntry));
|
|
while (!isEndOfArray(e)) {
|
|
if ((uint)e->code == EOS) reverseRestrictions(e->next);
|
|
else reverseElms(e->next);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseSyntaxTableCurrent(Aword adr) {
|
|
SyntaxEntry *e = (SyntaxEntry *) &memory[adr];
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(SyntaxEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseElms(e->elms);
|
|
reverseTable(e->parameterNameTable, sizeof(Aaddr));
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseSyntaxTablePreBeta2(Aword adr) {
|
|
SyntaxEntryPreBeta2 *e = (SyntaxEntryPreBeta2 *) &memory[adr];
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(SyntaxEntryPreBeta2));
|
|
while (!isEndOfArray(e)) {
|
|
reverseElms(e->elms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseSyntaxTable(Aword adr, byte version[]) {
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (isPreBeta2(version))
|
|
reverseSyntaxTablePreBeta2(adr);
|
|
else
|
|
reverseSyntaxTableCurrent(adr);
|
|
}
|
|
|
|
|
|
static void reverseParameterNames(Aaddr parameterMapAddress) {
|
|
Aaddr *e;
|
|
Aaddr adr;
|
|
|
|
adr = addressAfterTable(parameterMapAddress, sizeof(ParameterMapEntry));
|
|
reverse(&memory[adr]);
|
|
adr = memory[adr];
|
|
|
|
reverseTable(adr, sizeof(Aaddr));
|
|
|
|
e = (Aaddr *) &memory[adr];
|
|
while (!isEndOfArray(e)) {
|
|
reverseTable(*e, sizeof(Aaddr));
|
|
e++;
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseParameterTable(Aword adr) {
|
|
ParameterMapEntry *e = (ParameterMapEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ParameterMapEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseTable(e->parameterMapping, sizeof(Aword));
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseEvts(Aword adr) {
|
|
EventEntry *e = (EventEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(EventEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->code);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseLims(Aword adr) {
|
|
LimitEntry *e = (LimitEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(LimitEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseContainers(Aword adr) {
|
|
ContainerEntry *e = (ContainerEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(ContainerEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseLims(e->limits);
|
|
reverseStms(e->header);
|
|
reverseStms(e->empty);
|
|
reverseChks(e->extractChecks);
|
|
reverseStms(e->extractStatements);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseRuls(Aword adr) {
|
|
RuleEntry *e = (RuleEntry *) &memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(RuleEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseStms(e->exp);
|
|
reverseStms(e->stms);
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void reverseSetInitTable(Aaddr adr) {
|
|
SetInitEntry *e = (SetInitEntry *)&memory[adr];
|
|
|
|
if (!adr || alreadyDone(adr)) return;
|
|
|
|
if (!isEndOfArray(e)) {
|
|
reverseTable(adr, sizeof(SetInitEntry));
|
|
while (!isEndOfArray(e)) {
|
|
reverseTable(e->setAddress, sizeof(Aword));
|
|
e++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reversePreAlpha5Header(Pre3_0alpha5Header *hdr) {
|
|
uint i;
|
|
|
|
/* Reverse all words in the header except the tag */
|
|
for (i = 1; i < sizeof(*hdr) / sizeof(Aword); i++)
|
|
reverseWord(&((Aword *)hdr)[i]);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reversePreAlpha5() {
|
|
/* NOTE that the reversePreXXX() have different header definitions */
|
|
Pre3_0alpha5Header *hdr = (Pre3_0alpha5Header *)memory;
|
|
|
|
reversePreAlpha5Header(hdr);
|
|
memorySize = hdr->size;
|
|
|
|
reverseDictionary(hdr->dictionary);
|
|
reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
|
|
reverseParameterTable(hdr->parameterMapAddress);
|
|
reverseVerbs(hdr->verbTableAddress);
|
|
reverseClasses(hdr->classTableAddress);
|
|
reverseInstances(hdr->instanceTableAddress);
|
|
reverseScrs(hdr->scriptTableAddress);
|
|
reverseContainers(hdr->containerTableAddress);
|
|
reverseEvts(hdr->eventTableAddress);
|
|
reverseRuls(hdr->ruleTableAddress);
|
|
reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
|
|
reverseSetInitTable(hdr->setInitTable);
|
|
reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
|
|
reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
|
|
reverseStms(hdr->start);
|
|
reverseMsgs(hdr->messageTableAddress);
|
|
|
|
reverseTable(hdr->scores, sizeof(Aword));
|
|
reverseTable(hdr->freq, sizeof(Aword));
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reversePreBeta2Header(Pre3_0beta2Header *hdr) {
|
|
uint i;
|
|
|
|
/* Reverse all words in the header except the tag */
|
|
for (i = 1; i < sizeof(*hdr) / sizeof(Aword); i++)
|
|
reverseWord(&((Aword *)hdr)[i]);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reversePreBeta2() {
|
|
/* NOTE that the reversePreXXX() have different header definitions */
|
|
Pre3_0beta2Header *hdr = (Pre3_0beta2Header *)memory;
|
|
|
|
reversePreBeta2Header(hdr);
|
|
memorySize = hdr->size;
|
|
|
|
reverseDictionary(hdr->dictionary);
|
|
reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
|
|
reverseParameterTable(hdr->parameterMapAddress);
|
|
reverseVerbs(hdr->verbTableAddress);
|
|
reverseClasses(hdr->classTableAddress);
|
|
reverseInstances(hdr->instanceTableAddress);
|
|
reverseScrs(hdr->scriptTableAddress);
|
|
reverseContainers(hdr->containerTableAddress);
|
|
reverseEvts(hdr->eventTableAddress);
|
|
reverseRuls(hdr->ruleTableAddress);
|
|
reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
|
|
reverseSetInitTable(hdr->setInitTable);
|
|
reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
|
|
reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
|
|
reverseStms(hdr->start);
|
|
reverseMsgs(hdr->messageTableAddress);
|
|
|
|
reverseTable(hdr->scores, sizeof(Aword));
|
|
reverseTable(hdr->freq, sizeof(Aword));
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void reverseHdr(ACodeHeader *hdr) {
|
|
uint i;
|
|
|
|
/* Reverse all words in the header except the tag and the version marking */
|
|
for (i = 1; i < sizeof(*hdr) / sizeof(Aword); i++)
|
|
reverseWord(&((Aword *)hdr)[i]);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reverseInstanceIdTable(ACodeHeader *hdr) {
|
|
reverseTable(hdr->instanceTableAddress + hdr->instanceMax * sizeof(InstanceEntry) / sizeof(Aword) + 1, sizeof(Aword));
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void reverseNative() {
|
|
/* NOTE that the reversePreXXX() have different hdr definitions */
|
|
ACodeHeader *hdr = (ACodeHeader *)memory;
|
|
|
|
reverseHdr(hdr);
|
|
memorySize = hdr->size;
|
|
|
|
reverseDictionary(hdr->dictionary);
|
|
reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
|
|
if (hdr->debug && !isPreBeta3(hdr->version))
|
|
reverseParameterNames(hdr->parameterMapAddress);
|
|
reverseParameterTable(hdr->parameterMapAddress);
|
|
reverseVerbs(hdr->verbTableAddress);
|
|
reverseClasses(hdr->classTableAddress);
|
|
reverseInstances(hdr->instanceTableAddress);
|
|
if (hdr->debug && !isPreBeta3(hdr->version))
|
|
reverseInstanceIdTable(hdr);
|
|
reverseScrs(hdr->scriptTableAddress);
|
|
reverseContainers(hdr->containerTableAddress);
|
|
reverseEvts(hdr->eventTableAddress);
|
|
reverseRuls(hdr->ruleTableAddress);
|
|
reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
|
|
reverseSetInitTable(hdr->setInitTable);
|
|
reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
|
|
reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
|
|
reverseStms(hdr->prompt);
|
|
reverseStms(hdr->start);
|
|
reverseMsgs(hdr->messageTableAddress);
|
|
|
|
reverseTable(hdr->scores, sizeof(Aword));
|
|
reverseTable(hdr->freq, sizeof(Aword));
|
|
}
|
|
|
|
|
|
/*======================================================================
|
|
|
|
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(void) {
|
|
ACodeHeader *hdr = (ACodeHeader *)memory;
|
|
byte version[4];
|
|
int i;
|
|
|
|
/* Make a copy of the version marking to reverse */
|
|
for (i = 0; i <= 3; i++)
|
|
version[i] = hdr->version[i];
|
|
reverseWord((Aword *)&version);
|
|
|
|
if (isPreAlpha5(version))
|
|
reversePreAlpha5();
|
|
else if (isPreBeta2(version))
|
|
reversePreBeta2();
|
|
else
|
|
reverseNative();
|
|
|
|
free(addressesDone);
|
|
}
|
|
|
|
} // End of namespace Alan3
|
|
} // End of namespace Glk
|