/* 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/ScValue.h" #include "engines/wintermute/Base/scriptables/ScStack.h" #include "engines/wintermute/Sys/SysInstance.h" #include "engines/wintermute/Base/scriptables/SXArray.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(Game); 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(Game); } ////////////////////////////////////////////////////////////////////////// CSXArray::~CSXArray() { delete _values; _values = NULL; } ////////////////////////////////////////////////////////////////////////// const char *CSXArray::scToString() { static char Dummy[32768]; 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; } ////////////////////////////////////////////////////////////////////////// HRESULT 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 S_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 S_OK; } else return E_FAIL; } ////////////////////////////////////////////////////////////////////////// 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; } } ////////////////////////////////////////////////////////////////////////// HRESULT 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 S_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 E_FAIL; } } ////////////////////////////////////////////////////////////////////////// HRESULT CSXArray::persist(CBPersistMgr *persistMgr) { CBScriptable::persist(persistMgr); persistMgr->transfer(TMEMBER(_length)); persistMgr->transfer(TMEMBER(_values)); return S_OK; } ////////////////////////////////////////////////////////////////////////// bool CSXArray::ValidNumber(const char *OrigStr, char *OutStr) { bool IsNumber = true; for (int 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; } ////////////////////////////////////////////////////////////////////////// HRESULT CSXArray::Push(CScValue *Val) { char ParamName[20]; _length++; sprintf(ParamName, "%d", _length - 1); _values->setProp(ParamName, Val, true); return S_OK; } } // end of namespace WinterMute