324 lines
9.4 KiB
C++
324 lines
9.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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "glk/alan3/params.h"
|
|
#include "glk/alan3/glkio.h"
|
|
#include "glk/alan3/lists.h"
|
|
#include "glk/alan3/literal.h"
|
|
#include "glk/alan3/memory.h"
|
|
#include "glk/alan3/syserr.h"
|
|
|
|
namespace Glk {
|
|
namespace Alan3 {
|
|
|
|
/* PUBLIC DATA */
|
|
Parameter *globalParameters = nullptr;
|
|
|
|
/*======================================================================*/
|
|
Parameter *newParameter(int id) {
|
|
Parameter *parameter = NEW(Parameter);
|
|
parameter->instance = id;
|
|
parameter->candidates = nullptr;
|
|
|
|
return parameter;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
Parameter *newParameterArray(void) {
|
|
Parameter *newArray = (Parameter *)allocate((MAXINSTANCE + 1) * sizeof(Parameter));
|
|
setEndOfArray(newArray);
|
|
return newArray;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void freeParameterArray(ParameterArray arrayPointer) {
|
|
Parameter *p;
|
|
|
|
for (p = arrayPointer; !isEndOfArray(p); p++)
|
|
if (p->candidates != nullptr)
|
|
freeParameterArray(p->candidates);
|
|
deallocate(arrayPointer);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
Parameter *ensureParameterArrayAllocated(ParameterArray currentArray) {
|
|
if (currentArray == nullptr)
|
|
return newParameterArray();
|
|
else {
|
|
clearParameterArray(currentArray);
|
|
return currentArray;
|
|
}
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
bool parameterArrayIsEmpty(ParameterArray array) {
|
|
return array == nullptr || lengthOfParameterArray(array) == 0;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void clearParameter(Parameter *parameter) {
|
|
Parameter *candidates = parameter->candidates;
|
|
memset(parameter, 0, sizeof(Parameter));
|
|
parameter->candidates = candidates;
|
|
if (parameter->candidates != nullptr)
|
|
clearParameterArray(parameter->candidates);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void setGlobalParameters(ParameterArray newParameters) {
|
|
if (globalParameters == nullptr)
|
|
globalParameters = newParameterArray();
|
|
copyParameterArray(globalParameters, newParameters);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
Parameter *getGlobalParameters(void) {
|
|
if (globalParameters == nullptr)
|
|
globalParameters = newParameterArray();
|
|
return globalParameters;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
Parameter *getGlobalParameter(int parameterIndex) {
|
|
return &globalParameters[parameterIndex];
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
Parameter *findEndOfParameterArray(Parameter *parameters) {
|
|
Parameter *parameter;
|
|
for (parameter = parameters; !isEndOfArray(parameter); parameter++);
|
|
return parameter;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
/* A parameter position with code == 0 means this is a multiple position.
|
|
* We must loop over this position (and replace it by each present in the
|
|
* matched list)
|
|
*/
|
|
int findMultiplePosition(Parameter parameters[]) {
|
|
// TODO: this should look at the isAll and isExplicitMultiple flags instead
|
|
int multiplePosition;
|
|
for (multiplePosition = 0; !isEndOfArray(¶meters[multiplePosition]); multiplePosition++)
|
|
if (parameters[multiplePosition].instance == 0)
|
|
return multiplePosition;
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void compressParameterArray(Parameter theArray[]) {
|
|
int i, j;
|
|
|
|
for (i = 0, j = 0; !isEndOfArray(&theArray[j]); j++)
|
|
if (theArray[j].instance != 0)
|
|
theArray[i++] = theArray[j];
|
|
setEndOfArray(&theArray[i]);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
int lengthOfParameterArray(Parameter theArray[]) {
|
|
int i = 0;
|
|
|
|
if (theArray == nullptr) return 0;
|
|
|
|
while (!isEndOfArray(&theArray[i]))
|
|
i++;
|
|
return i;
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
bool equalParameterArrays(Parameter parameters1[], Parameter parameters2[]) {
|
|
int i;
|
|
|
|
if ((parameters1 == nullptr) != (parameters2 == nullptr))
|
|
return FALSE;
|
|
if (parameters1 == nullptr) // Because then parameter2 is also NULL
|
|
return TRUE;
|
|
for (i = 0; !isEndOfArray(¶meters1[i]); i++) {
|
|
if (isEndOfArray(¶meters2[i])) return FALSE;
|
|
if (parameters1[i].instance != parameters2[i].instance) return FALSE;
|
|
}
|
|
return isEndOfArray(¶meters2[i]);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
bool inParameterArray(Parameter theArray[], Aword theCode) {
|
|
int i;
|
|
|
|
for (i = 0; !isEndOfArray(&theArray[i]) && theArray[i].instance != theCode; i++);
|
|
return (theArray[i].instance == theCode);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void copyParameter(Parameter *to, Parameter *from) {
|
|
Parameter *toCandidates = to->candidates;
|
|
|
|
*to = *from;
|
|
if (from->candidates != nullptr) {
|
|
if (toCandidates == nullptr)
|
|
to->candidates = newParameterArray();
|
|
else
|
|
to->candidates = toCandidates;
|
|
copyParameterArray(to->candidates, from->candidates);
|
|
} else if (toCandidates != nullptr)
|
|
freeParameterArray(toCandidates);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void addParameterToParameterArray(ParameterArray theArray, Parameter *theParameter) {
|
|
if (theArray == nullptr) syserr("Adding to null parameter array");
|
|
|
|
uint i;
|
|
|
|
for (i = 0; !isEndOfArray(&theArray[i]) && i < MAXINSTANCE; i++)
|
|
;
|
|
if (isEndOfArray(&theArray[i])) {
|
|
copyParameter(&theArray[i], theParameter);
|
|
setEndOfArray(&theArray[i + 1]);
|
|
} else
|
|
syserr("Couldn't find end of ParameterArray");
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void copyParameterArray(ParameterArray to, ParameterArray from) {
|
|
int i;
|
|
|
|
if (to == nullptr && from == nullptr) return;
|
|
|
|
if (to == nullptr)
|
|
syserr("Copying to null parameter array");
|
|
else {
|
|
clearParameterArray(to);
|
|
for (i = 0; !isEndOfArray(&from[i]); i++)
|
|
addParameterToParameterArray(to, &from[i]);
|
|
}
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void subtractParameterArrays(Parameter theArray[], Parameter remove[]) {
|
|
int i;
|
|
|
|
if (remove == nullptr) return;
|
|
|
|
for (i = 0; !isEndOfArray(&theArray[i]); i++)
|
|
if (inParameterArray(remove, theArray[i].instance))
|
|
theArray[i].instance = 0; /* Mark empty */
|
|
compressParameterArray(theArray);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void clearParameterArray(Parameter theArray[]) {
|
|
Parameter *p = &theArray[0];
|
|
|
|
for (p = &theArray[0]; !isEndOfArray(p); p++)
|
|
clearParameter(p);
|
|
setEndOfArray(theArray);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void intersectParameterArrays(Parameter one[], Parameter other[]) {
|
|
int i, last = 0;
|
|
|
|
|
|
for (i = 0; !isEndOfArray(&one[i]); i++)
|
|
if (inParameterArray(other, one[i].instance))
|
|
one[last++] = one[i];
|
|
setEndOfArray(&one[last]);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void copyReferencesToParameterArray(Aint references[], Parameter parameterArray[]) {
|
|
int i;
|
|
|
|
for (i = 0; !isEndOfArray(&references[i]); i++) {
|
|
parameterArray[i].instance = references[i];
|
|
parameterArray[i].firstWord = EOD; /* Ensure that there is no word that can be used */
|
|
}
|
|
setEndOfArray(¶meterArray[i]);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void addParameterForInstance(Parameter *parameters, int instance) {
|
|
Parameter *parameter = findEndOfParameterArray(parameters);
|
|
|
|
parameter->instance = instance;
|
|
parameter->useWords = FALSE;
|
|
|
|
setEndOfArray(parameter + 1);
|
|
}
|
|
|
|
|
|
/*======================================================================*/
|
|
void addParameterForInteger(ParameterArray parameters, int value) {
|
|
Parameter *parameter = findEndOfParameterArray(parameters);
|
|
|
|
createIntegerLiteral(value);
|
|
parameter->instance = instanceFromLiteral(litCount);
|
|
parameter->useWords = FALSE;
|
|
|
|
setEndOfArray(parameter + 1);
|
|
}
|
|
|
|
/*======================================================================*/
|
|
void addParameterForString(Parameter *parameters, char *value) {
|
|
Parameter *parameter = findEndOfParameterArray(parameters);
|
|
|
|
createStringLiteral(value);
|
|
parameter->instance = instanceFromLiteral(litCount);
|
|
parameter->useWords = FALSE;
|
|
|
|
setEndOfArray(parameter + 1);
|
|
}
|
|
|
|
/*======================================================================*/
|
|
void printParameterArray(Parameter parameters[]) {
|
|
int i;
|
|
printf("[");
|
|
for (i = 0; !isEndOfArray(¶meters[i]); i++) {
|
|
printf("%d ", (int)parameters[i].instance);
|
|
}
|
|
printf("]\n");
|
|
}
|
|
|
|
} // End of namespace Alan3
|
|
} // End of namespace Glk
|