Files
scummvm/engines/wintermute/base/scriptables/script_ext_array.cpp
T
Einar Johan Trøan Sømåen 5683f07633 WINTERMUTE: Rename CamelCased filenames to prefixed_under_score-filenames
This is mostly a lead-up to namespacing the Ad/Base folders, and then
possibly removing the prefixes from the files, it also has the added
benefit of getting rid of the odd case-typos that makes for issues
on platforms that don't ignore case.
2012-07-21 19:15:33 +02:00

239 lines
7.0 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.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/system/sys_instance.h"
#include "engines/wintermute/base/scriptables/script_ext_array.h"
namespace WinterMute {
IMPLEMENT_PERSISTENT(CSXArray, false)
CBScriptable *makeSXArray(CBGame *inGame, CScStack *stack) {
return new CSXArray(inGame, stack);
}
//////////////////////////////////////////////////////////////////////////
CSXArray::CSXArray(CBGame *inGame, CScStack *stack): CBScriptable(inGame) {
_length = 0;
_values = new CScValue(_gameRef);
int numParams = stack->pop()->getInt(0);
if (numParams == 1) _length = stack->pop()->getInt(0);
else if (numParams > 1) {
_length = numParams;
char paramName[20];
for (int i = 0; i < numParams; i++) {
sprintf(paramName, "%d", i);
_values->setProp(paramName, stack->pop());
}
}
}
//////////////////////////////////////////////////////////////////////////
CSXArray::CSXArray(CBGame *inGame): CBScriptable(inGame) {
_length = 0;
_values = new CScValue(_gameRef);
}
//////////////////////////////////////////////////////////////////////////
CSXArray::~CSXArray() {
delete _values;
_values = NULL;
}
//////////////////////////////////////////////////////////////////////////
const char *CSXArray::scToString() {
static char dummy[32768]; // TODO: Get rid of static.
strcpy(dummy, "");
char propName[20];
for (int i = 0; i < _length; i++) {
sprintf(propName, "%d", i);
CScValue *val = _values->getProp(propName);
if (val) {
if (strlen(dummy) + strlen(val->getString()) < 32768) {
strcat(dummy, val->getString());
}
}
if (i < _length - 1 && strlen(dummy) + 1 < 32768) strcat(dummy, ",");
}
return dummy;
}
//////////////////////////////////////////////////////////////////////////
bool CSXArray::scCallMethod(CScScript *script, CScStack *stack, CScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// Push
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Push") == 0) {
int numParams = stack->pop()->getInt(0);
char paramName[20];
for (int i = 0; i < numParams; i++) {
_length++;
sprintf(paramName, "%d", _length - 1);
_values->setProp(paramName, stack->pop(), true);
}
stack->pushInt(_length);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Pop
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Pop") == 0) {
stack->correctParams(0);
if (_length > 0) {
char paramName[20];
sprintf(paramName, "%d", _length - 1);
stack->push(_values->getProp(paramName));
_values->deleteProp(paramName);
_length--;
} else stack->pushNULL();
return STATUS_OK;
}
else return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
CScValue *CSXArray::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("array");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Length
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Length") == 0) {
_scValue->setInt(_length);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// [number]
//////////////////////////////////////////////////////////////////////////
else {
char ParamName[20];
if (validNumber(name, ParamName)) {
return _values->getProp(ParamName);
} else return _scValue;
}
}
//////////////////////////////////////////////////////////////////////////
bool CSXArray::scSetProperty(const char *name, CScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Length
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Length") == 0) {
int OrigLength = _length;
_length = MAX(value->getInt(0), 0);
char PropName[20];
if (_length < OrigLength) {
for (int i = _length; i < OrigLength; i++) {
sprintf(PropName, "%d", i);
_values->deleteProp(PropName);
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// [number]
//////////////////////////////////////////////////////////////////////////
else {
char paramName[20];
if (validNumber(name, paramName)) {
int Index = atoi(paramName);
if (Index >= _length) _length = Index + 1;
return _values->setProp(paramName, value);
} else return STATUS_FAILED;
}
}
//////////////////////////////////////////////////////////////////////////
bool CSXArray::persist(CBPersistMgr *persistMgr) {
CBScriptable::persist(persistMgr);
persistMgr->transfer(TMEMBER(_length));
persistMgr->transfer(TMEMBER(_values));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool CSXArray::validNumber(const char *origStr, char *outStr) {
bool isNumber = true;
for (uint32 i = 0; i < strlen(origStr); i++) {
if (!(origStr[i] >= '0' && origStr[i] <= '9')) {
isNumber = false;
break;
}
}
if (isNumber) {
int index = atoi(origStr);
sprintf(outStr, "%d", index);
return true;
} else return false;
}
//////////////////////////////////////////////////////////////////////////
bool CSXArray::push(CScValue *val) {
char paramName[20];
_length++;
sprintf(paramName, "%d", _length - 1);
_values->setProp(paramName, val, true);
return STATUS_OK;
}
} // end of namespace WinterMute