aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/scriptables
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2012-09-04 22:17:23 +0200
committerWillem Jan Palenstijn2012-09-04 22:17:23 +0200
commitb4090ead4d4334e08725323ff72fd355c93b63d5 (patch)
tree4eb58e5698b1cfd1a89d2b038f929071264ffeb9 /engines/wintermute/base/scriptables
parentdf80820184c90a87511f0cabdca4addb9fa13a66 (diff)
downloadscummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.tar.gz
scummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.tar.bz2
scummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.zip
WINTERMUTE: Convert CRLF to LF
Diffstat (limited to 'engines/wintermute/base/scriptables')
-rw-r--r--engines/wintermute/base/scriptables/dcscript.h282
-rw-r--r--engines/wintermute/base/scriptables/script.cpp2934
-rw-r--r--engines/wintermute/base/scriptables/script.h348
-rw-r--r--engines/wintermute/base/scriptables/script_engine.cpp1220
-rw-r--r--engines/wintermute/base/scriptables/script_engine.h270
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.cpp504
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.h112
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.cpp586
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.h108
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.cpp1658
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.h132
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.cpp590
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.h106
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp1058
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.h120
-rw-r--r--engines/wintermute/base/scriptables/script_ext_object.cpp134
-rw-r--r--engines/wintermute/base/scriptables/script_ext_object.h92
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.cpp872
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.h116
-rw-r--r--engines/wintermute/base/scriptables/script_stack.cpp464
-rw-r--r--engines/wintermute/base/scriptables/script_stack.h132
-rw-r--r--engines/wintermute/base/scriptables/script_value.cpp1990
-rw-r--r--engines/wintermute/base/scriptables/script_value.h226
23 files changed, 7027 insertions, 7027 deletions
diff --git a/engines/wintermute/base/scriptables/dcscript.h b/engines/wintermute/base/scriptables/dcscript.h
index 6810fdf665..4aae897dc2 100644
--- a/engines/wintermute/base/scriptables/dcscript.h
+++ b/engines/wintermute/base/scriptables/dcscript.h
@@ -1,141 +1,141 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_DCSCRIPT_H
-#define WINTERMUTE_DCSCRIPT_H
-
-namespace Wintermute {
-
-#define SCRIPT_MAGIC 0xDEC0ADDE
-#define SCRIPT_VERSION 0x0102
-
-// value types
-typedef enum {
- VAL_NULL,
- VAL_STRING,
- VAL_INT,
- VAL_BOOL,
- VAL_FLOAT,
- VAL_OBJECT,
- VAL_NATIVE,
- VAL_VARIABLE_REF
-} TValType;
-
-
-// script states
-typedef enum {
- SCRIPT_RUNNING,
- SCRIPT_WAITING,
- SCRIPT_SLEEPING,
- SCRIPT_FINISHED,
- SCRIPT_PERSISTENT,
- SCRIPT_ERROR,
- SCRIPT_PAUSED,
- SCRIPT_WAITING_SCRIPT,
- SCRIPT_THREAD_FINISHED
-} TScriptState;
-
-// opcodes
-typedef enum {
- II_DEF_VAR = 0,
- II_DEF_GLOB_VAR,
- II_RET,
- II_RET_EVENT,
- II_CALL,
- II_CALL_BY_EXP,
- II_EXTERNAL_CALL,
- II_SCOPE,
- II_CORRECT_STACK,
- II_CREATE_OBJECT,
- II_POP_EMPTY,
- II_PUSH_VAR,
- II_PUSH_VAR_REF,
- II_POP_VAR,
- II_PUSH_VAR_THIS, // push current this on stack
- II_PUSH_INT,
- II_PUSH_BOOL,
- II_PUSH_FLOAT,
- II_PUSH_STRING,
- II_PUSH_NULL,
- II_PUSH_THIS_FROM_STACK,
- II_PUSH_THIS,
- II_POP_THIS,
- II_PUSH_BY_EXP,
- II_POP_BY_EXP,
- II_JMP,
- II_JMP_FALSE,
- II_ADD,
- II_SUB,
- II_MUL,
- II_DIV,
- II_MODULO,
- II_NOT,
- II_AND,
- II_OR,
- II_CMP_EQ,
- II_CMP_NE,
- II_CMP_L,
- II_CMP_G,
- II_CMP_LE,
- II_CMP_GE,
- II_CMP_STRICT_EQ,
- II_CMP_STRICT_NE,
- II_DBG_LINE,
- II_POP_REG1,
- II_PUSH_REG1,
- II_DEF_CONST_VAR
-} TInstruction;
-
-// external data types
-typedef enum {
- TYPE_VOID = 0,
- TYPE_BOOL,
- TYPE_LONG,
- TYPE_BYTE,
- TYPE_STRING,
- TYPE_FLOAT,
- TYPE_DOUBLE,
- TYPE_MEMBUFFER
-} TExternalType;
-
-
-// call types
-typedef enum {
- CALL_STDCALL = 0,
- CALL_CDECL,
- CALL_THISCALL
-} TCallType;
-
-// element types
-typedef enum {
- ELEMENT_STRING = 0
-} TElementType;
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_DCSCRIPT_H
+#define WINTERMUTE_DCSCRIPT_H
+
+namespace Wintermute {
+
+#define SCRIPT_MAGIC 0xDEC0ADDE
+#define SCRIPT_VERSION 0x0102
+
+// value types
+typedef enum {
+ VAL_NULL,
+ VAL_STRING,
+ VAL_INT,
+ VAL_BOOL,
+ VAL_FLOAT,
+ VAL_OBJECT,
+ VAL_NATIVE,
+ VAL_VARIABLE_REF
+} TValType;
+
+
+// script states
+typedef enum {
+ SCRIPT_RUNNING,
+ SCRIPT_WAITING,
+ SCRIPT_SLEEPING,
+ SCRIPT_FINISHED,
+ SCRIPT_PERSISTENT,
+ SCRIPT_ERROR,
+ SCRIPT_PAUSED,
+ SCRIPT_WAITING_SCRIPT,
+ SCRIPT_THREAD_FINISHED
+} TScriptState;
+
+// opcodes
+typedef enum {
+ II_DEF_VAR = 0,
+ II_DEF_GLOB_VAR,
+ II_RET,
+ II_RET_EVENT,
+ II_CALL,
+ II_CALL_BY_EXP,
+ II_EXTERNAL_CALL,
+ II_SCOPE,
+ II_CORRECT_STACK,
+ II_CREATE_OBJECT,
+ II_POP_EMPTY,
+ II_PUSH_VAR,
+ II_PUSH_VAR_REF,
+ II_POP_VAR,
+ II_PUSH_VAR_THIS, // push current this on stack
+ II_PUSH_INT,
+ II_PUSH_BOOL,
+ II_PUSH_FLOAT,
+ II_PUSH_STRING,
+ II_PUSH_NULL,
+ II_PUSH_THIS_FROM_STACK,
+ II_PUSH_THIS,
+ II_POP_THIS,
+ II_PUSH_BY_EXP,
+ II_POP_BY_EXP,
+ II_JMP,
+ II_JMP_FALSE,
+ II_ADD,
+ II_SUB,
+ II_MUL,
+ II_DIV,
+ II_MODULO,
+ II_NOT,
+ II_AND,
+ II_OR,
+ II_CMP_EQ,
+ II_CMP_NE,
+ II_CMP_L,
+ II_CMP_G,
+ II_CMP_LE,
+ II_CMP_GE,
+ II_CMP_STRICT_EQ,
+ II_CMP_STRICT_NE,
+ II_DBG_LINE,
+ II_POP_REG1,
+ II_PUSH_REG1,
+ II_DEF_CONST_VAR
+} TInstruction;
+
+// external data types
+typedef enum {
+ TYPE_VOID = 0,
+ TYPE_BOOL,
+ TYPE_LONG,
+ TYPE_BYTE,
+ TYPE_STRING,
+ TYPE_FLOAT,
+ TYPE_DOUBLE,
+ TYPE_MEMBUFFER
+} TExternalType;
+
+
+// call types
+typedef enum {
+ CALL_STDCALL = 0,
+ CALL_CDECL,
+ CALL_THISCALL
+} TCallType;
+
+// element types
+typedef enum {
+ ELEMENT_STRING = 0
+} TElementType;
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp
index 269ea1ea03..9469bd46a7 100644
--- a/engines/wintermute/base/scriptables/script.cpp
+++ b/engines/wintermute/base/scriptables/script.cpp
@@ -1,1467 +1,1467 @@
-/* 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/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/scriptables/script_engine.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "common/memstream.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(ScScript, false)
-
-//////////////////////////////////////////////////////////////////////////
-ScScript::ScScript(BaseGame *inGame, ScEngine *engine) : BaseClass(inGame) {
- _buffer = NULL;
- _bufferSize = _iP = 0;
- _scriptStream = NULL;
- _filename = NULL;
- _currentLine = 0;
-
- _symbols = NULL;
- _numSymbols = 0;
-
- _engine = engine;
-
- _globals = NULL;
-
- _scopeStack = NULL;
- _callStack = NULL;
- _thisStack = NULL;
- _stack = NULL;
-
- _operand = NULL;
- _reg1 = NULL;
-
- _functions = NULL;
- _numFunctions = 0;
-
- _methods = NULL;
- _numMethods = 0;
-
- _events = NULL;
- _numEvents = 0;
-
- _externals = NULL;
- _numExternals = 0;
-
- _state = SCRIPT_FINISHED;
- _origState = SCRIPT_FINISHED;
-
- _waitObject = NULL;
- _waitTime = 0;
- _waitFrozen = false;
- _waitScript = NULL;
-
- _timeSlice = 0;
-
- _thread = false;
- _methodThread = false;
- _threadEvent = NULL;
-
- _freezable = true;
- _owner = NULL;
-
- _unbreakable = false;
- _parentScript = NULL;
-
- _tracingMode = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScScript::~ScScript() {
- cleanup();
-}
-
-void ScScript::readHeader() {
- uint32 oldPos = _scriptStream->pos();
- _scriptStream->seek(0);
- _header.magic = _scriptStream->readUint32LE();
- _header.version = _scriptStream->readUint32LE();
- _header.codeStart = _scriptStream->readUint32LE();
- _header.funcTable = _scriptStream->readUint32LE();
- _header.symbolTable = _scriptStream->readUint32LE();
- _header.eventTable = _scriptStream->readUint32LE();
- _header.externalsTable = _scriptStream->readUint32LE();
- _header.methodTable = _scriptStream->readUint32LE();
- _scriptStream->seek(oldPos);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::initScript() {
- if (!_scriptStream) {
- _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
- }
- readHeader();
-
- if (_header.magic != SCRIPT_MAGIC) {
- _gameRef->LOG(0, "File '%s' is not a valid compiled script", _filename);
- cleanup();
- return STATUS_FAILED;
- }
-
- if (_header.version > SCRIPT_VERSION) {
- _gameRef->LOG(0, "Script '%s' has a wrong version %d.%d (expected %d.%d)", _filename, _header.version / 256, _header.version % 256, SCRIPT_VERSION / 256, SCRIPT_VERSION % 256);
- cleanup();
- return STATUS_FAILED;
- }
-
- initTables();
-
- // init stacks
- _scopeStack = new ScStack(_gameRef);
- _callStack = new ScStack(_gameRef);
- _thisStack = new ScStack(_gameRef);
- _stack = new ScStack(_gameRef);
-
- _operand = new ScValue(_gameRef);
- _reg1 = new ScValue(_gameRef);
-
-
- // skip to the beginning
- _iP = _header.codeStart;
- _scriptStream->seek(_iP);
- _currentLine = 0;
-
- // ready to rumble...
- _state = SCRIPT_RUNNING;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::initTables() {
- uint32 origIP = _iP;
-
- readHeader();
- // load symbol table
- _iP = _header.symbolTable;
-
- _numSymbols = getDWORD();
- _symbols = new char*[_numSymbols];
- for (uint32 i = 0; i < _numSymbols; i++) {
- uint32 index = getDWORD();
- _symbols[index] = getString();
- }
-
- // load functions table
- _iP = _header.funcTable;
-
- _numFunctions = getDWORD();
- _functions = new TFunctionPos[_numFunctions];
- for (uint32 i = 0; i < _numFunctions; i++) {
- _functions[i].pos = getDWORD();
- _functions[i].name = getString();
- }
-
-
- // load events table
- _iP = _header.eventTable;
-
- _numEvents = getDWORD();
- _events = new TEventPos[_numEvents];
- for (uint32 i = 0; i < _numEvents; i++) {
- _events[i].pos = getDWORD();
- _events[i].name = getString();
- }
-
-
- // load externals
- if (_header.version >= 0x0101) {
- _iP = _header.externalsTable;
-
- _numExternals = getDWORD();
- _externals = new TExternalFunction[_numExternals];
- for (uint32 i = 0; i < _numExternals; i++) {
- _externals[i].dll_name = getString();
- _externals[i].name = getString();
- _externals[i].call_type = (TCallType)getDWORD();
- _externals[i].returns = (TExternalType)getDWORD();
- _externals[i].nu_params = getDWORD();
- if (_externals[i].nu_params > 0) {
- _externals[i].params = new TExternalType[_externals[i].nu_params];
- for (int j = 0; j < _externals[i].nu_params; j++) {
- _externals[i].params[j] = (TExternalType)getDWORD();
- }
- }
- }
- }
-
- // load method table
- _iP = _header.methodTable;
-
- _numMethods = getDWORD();
- _methods = new TMethodPos[_numMethods];
- for (uint32 i = 0; i < _numMethods; i++) {
- _methods[i].pos = getDWORD();
- _methods[i].name = getString();
- }
-
-
- _iP = origIP;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::create(const char *filename, byte *buffer, uint32 size, BaseScriptHolder *owner) {
- cleanup();
-
- _thread = false;
- _methodThread = false;
-
- delete[] _threadEvent;
- _threadEvent = NULL;
-
- _filename = new char[strlen(filename) + 1];
- if (_filename) {
- strcpy(_filename, filename);
- }
-
- _buffer = new byte [size];
- if (!_buffer) {
- return STATUS_FAILED;
- }
-
- memcpy(_buffer, buffer, size);
-
- _bufferSize = size;
-
- bool res = initScript();
- if (DID_FAIL(res)) {
- return res;
- }
-
- // establish global variables table
- _globals = new ScValue(_gameRef);
-
- _owner = owner;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::createThread(ScScript *original, uint32 initIP, const Common::String &eventName) {
- cleanup();
-
- _thread = true;
- _methodThread = false;
- _threadEvent = new char[eventName.size() + 1];
- if (_threadEvent) {
- strcpy(_threadEvent, eventName.c_str());
- }
-
- // copy filename
- _filename = new char[strlen(original->_filename) + 1];
- if (_filename) {
- strcpy(_filename, original->_filename);
- }
-
- // copy buffer
- _buffer = new byte [original->_bufferSize];
- if (!_buffer) {
- return STATUS_FAILED;
- }
-
- memcpy(_buffer, original->_buffer, original->_bufferSize);
- _bufferSize = original->_bufferSize;
-
- // initialize
- bool res = initScript();
- if (DID_FAIL(res)) {
- return res;
- }
-
- // copy globals
- _globals = original->_globals;
-
- // skip to the beginning of the event
- _iP = initIP;
- _scriptStream->seek(_iP);
-
- _timeSlice = original->_timeSlice;
- _freezable = original->_freezable;
- _owner = original->_owner;
-
- _engine = original->_engine;
- _parentScript = original;
-
- return STATUS_OK;
-}
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::createMethodThread(ScScript *original, const Common::String &methodName) {
- uint32 ip = original->getMethodPos(methodName);
- if (ip == 0) {
- return STATUS_FAILED;
- }
-
- cleanup();
-
- _thread = true;
- _methodThread = true;
- _threadEvent = new char[methodName.size() + 1];
- if (_threadEvent) {
- strcpy(_threadEvent, methodName.c_str());
- }
-
- // copy filename
- _filename = new char[strlen(original->_filename) + 1];
- if (_filename) {
- strcpy(_filename, original->_filename);
- }
-
- // copy buffer
- _buffer = new byte [original->_bufferSize];
- if (!_buffer) {
- return STATUS_FAILED;
- }
-
- memcpy(_buffer, original->_buffer, original->_bufferSize);
- _bufferSize = original->_bufferSize;
-
- // initialize
- bool res = initScript();
- if (DID_FAIL(res)) {
- return res;
- }
-
- // copy globals
- _globals = original->_globals;
-
- // skip to the beginning of the event
- _iP = ip;
-
- _timeSlice = original->_timeSlice;
- _freezable = original->_freezable;
- _owner = original->_owner;
-
- _engine = original->_engine;
- _parentScript = original;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScScript::cleanup() {
- if (_buffer) {
- delete[] _buffer;
- }
- _buffer = NULL;
-
- if (_filename) {
- delete[] _filename;
- }
- _filename = NULL;
-
- if (_symbols) {
- delete[] _symbols;
- }
- _symbols = NULL;
- _numSymbols = 0;
-
- if (_globals && !_thread) {
- delete _globals;
- }
- _globals = NULL;
-
- delete _scopeStack;
- _scopeStack = NULL;
-
- delete _callStack;
- _callStack = NULL;
-
- delete _thisStack;
- _thisStack = NULL;
-
- delete _stack;
- _stack = NULL;
-
- if (_functions) {
- delete[] _functions;
- }
- _functions = NULL;
- _numFunctions = 0;
-
- if (_methods) {
- delete[] _methods;
- }
- _methods = NULL;
- _numMethods = 0;
-
- if (_events) {
- delete[] _events;
- }
- _events = NULL;
- _numEvents = 0;
-
-
- if (_externals) {
- for (uint32 i = 0; i < _numExternals; i++) {
- if (_externals[i].nu_params > 0) {
- delete[] _externals[i].params;
- }
- }
- delete[] _externals;
- }
- _externals = NULL;
- _numExternals = 0;
-
- delete _operand;
- delete _reg1;
- _operand = NULL;
- _reg1 = NULL;
-
- delete[] _threadEvent;
- _threadEvent = NULL;
-
- _state = SCRIPT_FINISHED;
-
- _waitObject = NULL;
- _waitTime = 0;
- _waitFrozen = false;
- _waitScript = NULL;
-
- _parentScript = NULL; // ref only
-
- delete _scriptStream;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-uint32 ScScript::getDWORD() {
- _scriptStream->seek((int32)_iP);
- uint32 ret = _scriptStream->readUint32LE();
- _iP += sizeof(uint32);
-// assert(oldRet == ret);
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-double ScScript::getFloat() {
- _scriptStream->seek((int32)_iP);
- byte buffer[8];
- _scriptStream->read(buffer, 8);
-
-#ifdef SCUMM_BIG_ENDIAN
- // TODO: For lack of a READ_LE_UINT64
- SWAP(buffer[0], buffer[7]);
- SWAP(buffer[1], buffer[6]);
- SWAP(buffer[2], buffer[5]);
- SWAP(buffer[3], buffer[4]);
-#endif
-
- double ret = *(double *)(buffer);
- _iP += 8; // Hardcode the double-size used originally.
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-char *ScScript::getString() {
- char *ret = (char *)(_buffer + _iP);
- while (*(char *)(_buffer + _iP) != '\0') {
- _iP++;
- }
- _iP++; // string terminator
- _scriptStream->seek(_iP);
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::executeInstruction() {
- bool ret = STATUS_OK;
-
- uint32 dw;
- const char *str = NULL;
-
- //ScValue* op = new ScValue(_gameRef);
- _operand->cleanup();
-
- ScValue *op1;
- ScValue *op2;
-
- uint32 inst = getDWORD();
- switch (inst) {
-
- case II_DEF_VAR:
- _operand->setNULL();
- dw = getDWORD();
- if (_scopeStack->_sP < 0) {
- _globals->setProp(_symbols[dw], _operand);
- } else {
- _scopeStack->getTop()->setProp(_symbols[dw], _operand);
- }
-
- break;
-
- case II_DEF_GLOB_VAR:
- case II_DEF_CONST_VAR: {
- dw = getDWORD();
- /* char *temp = _symbols[dw]; // TODO delete */
- // only create global var if it doesn't exist
- if (!_engine->_globals->propExists(_symbols[dw])) {
- _operand->setNULL();
- _engine->_globals->setProp(_symbols[dw], _operand, false, inst == II_DEF_CONST_VAR);
- }
- break;
- }
-
- case II_RET:
- if (_scopeStack->_sP >= 0 && _callStack->_sP >= 0) {
- _scopeStack->pop();
- _iP = (uint32)_callStack->pop()->getInt();
- } else {
- if (_thread) {
- _state = SCRIPT_THREAD_FINISHED;
- } else {
- if (_numEvents == 0 && _numMethods == 0) {
- _state = SCRIPT_FINISHED;
- } else {
- _state = SCRIPT_PERSISTENT;
- }
- }
- }
-
- break;
-
- case II_RET_EVENT:
- _state = SCRIPT_FINISHED;
- break;
-
-
- case II_CALL:
- dw = getDWORD();
-
- _operand->setInt(_iP);
- _callStack->push(_operand);
-
- _iP = dw;
-
- break;
-
- case II_CALL_BY_EXP: {
- // push var
- // push string
- str = _stack->pop()->getString();
- char *methodName = new char[strlen(str) + 1];
- strcpy(methodName, str);
-
- ScValue *var = _stack->pop();
- if (var->_type == VAL_VARIABLE_REF) {
- var = var->_valRef;
- }
-
- bool res = STATUS_FAILED;
- bool triedNative = false;
-
- // we are already calling this method, try native
- if (_thread && _methodThread && strcmp(methodName, _threadEvent) == 0 && var->_type == VAL_NATIVE && _owner == var->getNative()) {
- triedNative = true;
- res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
- }
-
- if (DID_FAIL(res)) {
- if (var->isNative() && var->getNative()->canHandleMethod(methodName)) {
- if (!_unbreakable) {
- _waitScript = var->getNative()->invokeMethodThread(methodName);
- if (!_waitScript) {
- _stack->correctParams(0);
- runtimeError("Error invoking method '%s'.", methodName);
- _stack->pushNULL();
- } else {
- _state = SCRIPT_WAITING_SCRIPT;
- _waitScript->copyParameters(_stack);
- }
- } else {
- // can call methods in unbreakable mode
- _stack->correctParams(0);
- runtimeError("Cannot call method '%s'. Ignored.", methodName);
- _stack->pushNULL();
- }
- delete[] methodName;
- break;
- }
- /*
- ScValue* val = var->getProp(MethodName);
- if (val){
- dw = GetFuncPos(val->getString());
- if (dw==0){
- TExternalFunction* f = GetExternal(val->getString());
- if (f){
- ExternalCall(_stack, _thisStack, f);
- }
- else{
- // not an internal nor external, try for native function
- _gameRef->ExternalCall(this, _stack, _thisStack, val->getString());
- }
- }
- else{
- _operand->setInt(_iP);
- _callStack->Push(_operand);
- _iP = dw;
- }
- }
- */
- else {
- res = STATUS_FAILED;
- if (var->_type == VAL_NATIVE && !triedNative) {
- res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
- }
-
- if (DID_FAIL(res)) {
- _stack->correctParams(0);
- runtimeError("Call to undefined method '%s'. Ignored.", methodName);
- _stack->pushNULL();
- }
- }
- }
- delete[] methodName;
- }
- break;
-
- case II_EXTERNAL_CALL: {
- uint32 symbolIndex = getDWORD();
-
- TExternalFunction *f = getExternal(_symbols[symbolIndex]);
- if (f) {
- externalCall(_stack, _thisStack, f);
- } else {
- _gameRef->externalCall(this, _stack, _thisStack, _symbols[symbolIndex]);
- }
-
- break;
- }
- case II_SCOPE:
- _operand->setNULL();
- _scopeStack->push(_operand);
- break;
-
- case II_CORRECT_STACK:
- dw = getDWORD(); // params expected
- _stack->correctParams(dw);
- break;
-
- case II_CREATE_OBJECT:
- _operand->setObject();
- _stack->push(_operand);
- break;
-
- case II_POP_EMPTY:
- _stack->pop();
- break;
-
- case II_PUSH_VAR: {
- ScValue *var = getVar(_symbols[getDWORD()]);
- if (false && /*var->_type==VAL_OBJECT ||*/ var->_type == VAL_NATIVE) {
- _operand->setReference(var);
- _stack->push(_operand);
- } else {
- _stack->push(var);
- }
- break;
- }
-
- case II_PUSH_VAR_REF: {
- ScValue *var = getVar(_symbols[getDWORD()]);
- _operand->setReference(var);
- _stack->push(_operand);
- break;
- }
-
- case II_POP_VAR: {
- char *varName = _symbols[getDWORD()];
- ScValue *var = getVar(varName);
- if (var) {
- ScValue *val = _stack->pop();
- if (!val) {
- runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
- var->setNULL();
- } else {
- if (val->getType() == VAL_VARIABLE_REF) {
- val = val->_valRef;
- }
- if (val->_type == VAL_NATIVE) {
- var->setValue(val);
- } else {
- var->copy(val);
- }
- }
- }
-
- break;
- }
-
- case II_PUSH_VAR_THIS:
- _stack->push(_thisStack->getTop());
- break;
-
- case II_PUSH_INT:
- _stack->pushInt((int)getDWORD());
- break;
-
- case II_PUSH_FLOAT:
- _stack->pushFloat(getFloat());
- break;
-
-
- case II_PUSH_BOOL:
- _stack->pushBool(getDWORD() != 0);
-
- break;
-
- case II_PUSH_STRING:
- _stack->pushString(getString());
- break;
-
- case II_PUSH_NULL:
- _stack->pushNULL();
- break;
-
- case II_PUSH_THIS_FROM_STACK:
- _operand->setReference(_stack->getTop());
- _thisStack->push(_operand);
- break;
-
- case II_PUSH_THIS:
- _operand->setReference(getVar(_symbols[getDWORD()]));
- _thisStack->push(_operand);
- break;
-
- case II_POP_THIS:
- _thisStack->pop();
- break;
-
- case II_PUSH_BY_EXP: {
- str = _stack->pop()->getString();
- ScValue *val = _stack->pop()->getProp(str);
- if (val) {
- _stack->push(val);
- } else {
- _stack->pushNULL();
- }
-
- break;
- }
-
- case II_POP_BY_EXP: {
- str = _stack->pop()->getString();
- ScValue *var = _stack->pop();
- ScValue *val = _stack->pop();
-
- if (val == NULL) {
- runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
- var->setNULL();
- } else {
- var->setProp(str, val);
- }
-
- break;
- }
-
- case II_PUSH_REG1:
- _stack->push(_reg1);
- break;
-
- case II_POP_REG1:
- _reg1->copy(_stack->pop());
- break;
-
- case II_JMP:
- _iP = getDWORD();
- break;
-
- case II_JMP_FALSE: {
- dw = getDWORD();
- //if (!_stack->pop()->getBool()) _iP = dw;
- ScValue *val = _stack->pop();
- if (!val) {
- runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
- } else {
- if (!val->getBool()) {
- _iP = dw;
- }
- }
- break;
- }
-
- case II_ADD:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- if (op1->isNULL() || op2->isNULL()) {
- _operand->setNULL();
- } else if (op1->getType() == VAL_STRING || op2->getType() == VAL_STRING) {
- char *tempStr = new char [strlen(op1->getString()) + strlen(op2->getString()) + 1];
- strcpy(tempStr, op1->getString());
- strcat(tempStr, op2->getString());
- _operand->setString(tempStr);
- delete[] tempStr;
- } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
- _operand->setInt(op1->getInt() + op2->getInt());
- } else {
- _operand->setFloat(op1->getFloat() + op2->getFloat());
- }
-
- _stack->push(_operand);
-
- break;
-
- case II_SUB:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- if (op1->isNULL() || op2->isNULL()) {
- _operand->setNULL();
- } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
- _operand->setInt(op1->getInt() - op2->getInt());
- } else {
- _operand->setFloat(op1->getFloat() - op2->getFloat());
- }
-
- _stack->push(_operand);
-
- break;
-
- case II_MUL:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- if (op1->isNULL() || op2->isNULL()) {
- _operand->setNULL();
- } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
- _operand->setInt(op1->getInt() * op2->getInt());
- } else {
- _operand->setFloat(op1->getFloat() * op2->getFloat());
- }
-
- _stack->push(_operand);
-
- break;
-
- case II_DIV:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- if (op2->getFloat() == 0.0f) {
- runtimeError("Division by zero.");
- }
-
- if (op1->isNULL() || op2->isNULL() || op2->getFloat() == 0.0f) {
- _operand->setNULL();
- } else {
- _operand->setFloat(op1->getFloat() / op2->getFloat());
- }
-
- _stack->push(_operand);
-
- break;
-
- case II_MODULO:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- if (op2->getInt() == 0) {
- runtimeError("Division by zero.");
- }
-
- if (op1->isNULL() || op2->isNULL() || op2->getInt() == 0) {
- _operand->setNULL();
- } else {
- _operand->setInt(op1->getInt() % op2->getInt());
- }
-
- _stack->push(_operand);
-
- break;
-
- case II_NOT:
- op1 = _stack->pop();
- //if (op1->isNULL()) _operand->setNULL();
- if (op1->isNULL()) {
- _operand->setBool(true);
- } else {
- _operand->setBool(!op1->getBool());
- }
- _stack->push(_operand);
-
- break;
-
- case II_AND:
- op2 = _stack->pop();
- op1 = _stack->pop();
- if (op1 == NULL || op2 == NULL) {
- runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
- _operand->setBool(false);
- } else {
- _operand->setBool(op1->getBool() && op2->getBool());
- }
- _stack->push(_operand);
- break;
-
- case II_OR:
- op2 = _stack->pop();
- op1 = _stack->pop();
- if (op1 == NULL || op2 == NULL) {
- runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
- _operand->setBool(false);
- } else {
- _operand->setBool(op1->getBool() || op2->getBool());
- }
- _stack->push(_operand);
- break;
-
- case II_CMP_EQ:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(false);
- else if (op1->isNative() && op2->isNative()){
- _operand->setBool(op1->getNative() == op2->getNative());
- }
- else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING){
- _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())==0);
- }
- else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() == op2->getFloat());
- }
- else{
- _operand->setBool(op1->getInt() == op2->getInt());
- }
- */
-
- _operand->setBool(ScValue::compare(op1, op2) == 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_NE:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(true);
- else if (op1->isNative() && op2->isNative()){
- _operand->setBool(op1->getNative() != op2->getNative());
- }
- else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING){
- _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())!=0);
- }
- else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() != op2->getFloat());
- }
- else{
- _operand->setBool(op1->getInt() != op2->getInt());
- }
- */
-
- _operand->setBool(ScValue::compare(op1, op2) != 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_L:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() < op2->getFloat());
- }
- else _operand->setBool(op1->getInt() < op2->getInt());
- */
-
- _operand->setBool(ScValue::compare(op1, op2) < 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_G:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() > op2->getFloat());
- }
- else _operand->setBool(op1->getInt() > op2->getInt());
- */
-
- _operand->setBool(ScValue::compare(op1, op2) > 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_LE:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() <= op2->getFloat());
- }
- else _operand->setBool(op1->getInt() <= op2->getInt());
- */
-
- _operand->setBool(ScValue::compare(op1, op2) <= 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_GE:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- /*
- if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
- _operand->setBool(op1->getFloat() >= op2->getFloat());
- }
- else _operand->setBool(op1->getInt() >= op2->getInt());
- */
-
- _operand->setBool(ScValue::compare(op1, op2) >= 0);
- _stack->push(_operand);
- break;
-
- case II_CMP_STRICT_EQ:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- //_operand->setBool(op1->getType()==op2->getType() && op1->getFloat()==op2->getFloat());
- _operand->setBool(ScValue::compareStrict(op1, op2) == 0);
- _stack->push(_operand);
-
- break;
-
- case II_CMP_STRICT_NE:
- op2 = _stack->pop();
- op1 = _stack->pop();
-
- //_operand->setBool(op1->getType()!=op2->getType() || op1->getFloat()!=op2->getFloat());
- _operand->setBool(ScValue::compareStrict(op1, op2) != 0);
- _stack->push(_operand);
- break;
-
- case II_DBG_LINE: {
- int newLine = getDWORD();
- if (newLine != _currentLine) {
- _currentLine = newLine;
- }
- break;
-
- }
- default:
- _gameRef->LOG(0, "Fatal: Invalid instruction %d ('%s', line %d, IP:0x%x)\n", inst, _filename, _currentLine, _iP - sizeof(uint32));
- _state = SCRIPT_FINISHED;
- ret = STATUS_FAILED;
- } // switch(instruction)
-
- //delete op;
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-uint32 ScScript::getFuncPos(const Common::String &name) {
- for (uint32 i = 0; i < _numFunctions; i++) {
- if (name == _functions[i].name) {
- return _functions[i].pos;
- }
- }
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-uint32 ScScript::getMethodPos(const Common::String &name) {
- for (uint32 i = 0; i < _numMethods; i++) {
- if (name == _methods[i].name) {
- return _methods[i].pos;
- }
- }
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScScript::getVar(char *name) {
- ScValue *ret = NULL;
-
- // scope locals
- if (_scopeStack->_sP >= 0) {
- if (_scopeStack->getTop()->propExists(name)) {
- ret = _scopeStack->getTop()->getProp(name);
- }
- }
-
- // script globals
- if (ret == NULL) {
- if (_globals->propExists(name)) {
- ret = _globals->getProp(name);
- }
- }
-
- // engine globals
- if (ret == NULL) {
- if (_engine->_globals->propExists(name)) {
- ret = _engine->_globals->getProp(name);
- }
- }
-
- if (ret == NULL) {
- //RuntimeError("Variable '%s' is inaccessible in the current block. Consider changing the script.", name);
- _gameRef->LOG(0, "Warning: variable '%s' is inaccessible in the current block. Consider changing the script (script:%s, line:%d)", name, _filename, _currentLine);
- ScValue *val = new ScValue(_gameRef);
- ScValue *scope = _scopeStack->getTop();
- if (scope) {
- scope->setProp(name, val);
- ret = _scopeStack->getTop()->getProp(name);
- } else {
- _globals->setProp(name, val);
- ret = _globals->getProp(name);
- }
- delete val;
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::waitFor(BaseObject *object) {
- if (_unbreakable) {
- runtimeError("Script cannot be interrupted.");
- return STATUS_OK;
- }
-
- _state = SCRIPT_WAITING;
- _waitObject = object;
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::waitForExclusive(BaseObject *object) {
- _engine->resetObject(object);
- return waitFor(object);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::sleep(uint32 duration) {
- if (_unbreakable) {
- runtimeError("Script cannot be interrupted.");
- return STATUS_OK;
- }
-
- _state = SCRIPT_SLEEPING;
- if (_gameRef->_state == GAME_FROZEN) {
- _waitTime = g_system->getMillis() + duration;
- _waitFrozen = true;
- } else {
- _waitTime = _gameRef->_timer + duration;
- _waitFrozen = false;
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::finish(bool includingThreads) {
- if (_state != SCRIPT_FINISHED && includingThreads) {
- _state = SCRIPT_FINISHED;
- finishThreads();
- } else {
- _state = SCRIPT_FINISHED;
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::run() {
- _state = SCRIPT_RUNNING;
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-void ScScript::runtimeError(const char *fmt, ...) {
- char buff[256];
- va_list va;
-
- va_start(va, fmt);
- vsprintf(buff, fmt, va);
- va_end(va);
-
- _gameRef->LOG(0, "Runtime error. Script '%s', line %d", _filename, _currentLine);
- _gameRef->LOG(0, " %s", buff);
-
- if (!_gameRef->_suppressScriptErrors) {
- _gameRef->quickMessage("Script runtime error. View log for details.");
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::persist(BasePersistenceManager *persistMgr) {
-
- persistMgr->transfer(TMEMBER(_gameRef));
-
- // buffer
- if (persistMgr->getIsSaving()) {
- if (_state != SCRIPT_PERSISTENT && _state != SCRIPT_FINISHED && _state != SCRIPT_THREAD_FINISHED) {
- persistMgr->transfer(TMEMBER(_bufferSize));
- persistMgr->putBytes(_buffer, _bufferSize);
- } else {
- // don't save idle/finished scripts
- int bufferSize = 0;
- persistMgr->transfer(TMEMBER(bufferSize));
- }
- } else {
- persistMgr->transfer(TMEMBER(_bufferSize));
- if (_bufferSize > 0) {
- _buffer = new byte[_bufferSize];
- persistMgr->getBytes(_buffer, _bufferSize);
- _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
- initTables();
- } else {
- _buffer = NULL;
- _scriptStream = NULL;
- }
- }
-
- persistMgr->transfer(TMEMBER(_callStack));
- persistMgr->transfer(TMEMBER(_currentLine));
- persistMgr->transfer(TMEMBER(_engine));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_freezable));
- persistMgr->transfer(TMEMBER(_globals));
- persistMgr->transfer(TMEMBER(_iP));
- persistMgr->transfer(TMEMBER(_scopeStack));
- persistMgr->transfer(TMEMBER(_stack));
- persistMgr->transfer(TMEMBER_INT(_state));
- persistMgr->transfer(TMEMBER(_operand));
- persistMgr->transfer(TMEMBER_INT(_origState));
- persistMgr->transfer(TMEMBER(_owner));
- persistMgr->transfer(TMEMBER(_reg1));
- persistMgr->transfer(TMEMBER(_thread));
- persistMgr->transfer(TMEMBER(_threadEvent));
- persistMgr->transfer(TMEMBER(_thisStack));
- persistMgr->transfer(TMEMBER(_timeSlice));
- persistMgr->transfer(TMEMBER(_waitObject));
- persistMgr->transfer(TMEMBER(_waitScript));
- persistMgr->transfer(TMEMBER(_waitTime));
- persistMgr->transfer(TMEMBER(_waitFrozen));
-
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_unbreakable));
- persistMgr->transfer(TMEMBER(_parentScript));
-
- if (!persistMgr->getIsSaving()) {
- _tracingMode = false;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScScript *ScScript::invokeEventHandler(const Common::String &eventName, bool unbreakable) {
- //if (_state!=SCRIPT_PERSISTENT) return NULL;
-
- uint32 pos = getEventPos(eventName);
- if (!pos) {
- return NULL;
- }
-
- ScScript *thread = new ScScript(_gameRef, _engine);
- if (thread) {
- bool ret = thread->createThread(this, pos, eventName);
- if (DID_SUCCEED(ret)) {
- thread->_unbreakable = unbreakable;
- _engine->_scripts.add(thread);
- return thread;
- } else {
- delete thread;
- return NULL;
- }
- } else {
- return NULL;
- }
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-uint32 ScScript::getEventPos(const Common::String &name) {
- for (int i = _numEvents - 1; i >= 0; i--) {
- if (scumm_stricmp(name.c_str(), _events[i].name) == 0) {
- return _events[i].pos;
- }
- }
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::canHandleEvent(const Common::String &eventName) {
- return getEventPos(eventName) != 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::canHandleMethod(const Common::String &methodName) {
- return getMethodPos(methodName) != 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::pause() {
- if (_state == SCRIPT_PAUSED) {
- _gameRef->LOG(0, "Attempting to pause a paused script ('%s', line %d)", _filename, _currentLine);
- return STATUS_FAILED;
- }
-
- if (!_freezable || _state == SCRIPT_PERSISTENT) {
- return STATUS_OK;
- }
-
- _origState = _state;
- _state = SCRIPT_PAUSED;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::resume() {
- if (_state != SCRIPT_PAUSED) {
- return STATUS_OK;
- }
-
- _state = _origState;
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScScript::TExternalFunction *ScScript::getExternal(char *name) {
- for (uint32 i = 0; i < _numExternals; i++) {
- if (strcmp(name, _externals[i].name) == 0) {
- return &_externals[i];
- }
- }
- return NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::externalCall(ScStack *stack, ScStack *thisStack, ScScript::TExternalFunction *function) {
-
- _gameRef->LOG(0, "External functions are not supported on this platform.");
- stack->correctParams(0);
- stack->pushNULL();
- return STATUS_FAILED;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::copyParameters(ScStack *stack) {
- int i;
- int numParams = stack->pop()->getInt();
- for (i = numParams - 1; i >= 0; i--) {
- _stack->push(stack->getAt(i));
- }
- _stack->pushInt(numParams);
-
- for (i = 0; i < numParams; i++) {
- stack->pop();
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScScript::finishThreads() {
- for (uint32 i = 0; i < _engine->_scripts.size(); i++) {
- ScScript *scr = _engine->_scripts[i];
- if (scr->_thread && scr->_state != SCRIPT_FINISHED && scr->_owner == _owner && scumm_stricmp(scr->_filename, _filename) == 0) {
- scr->finish(true);
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// IWmeDebugScript interface implementation
-int ScScript::dbgGetLine() {
- return _currentLine;
-}
-
-//////////////////////////////////////////////////////////////////////////
-const char *ScScript::dbgGetFilename() {
- return _filename;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void ScScript::afterLoad() {
- if (_buffer == NULL) {
- byte *buffer = _engine->getCompiledScript(_filename, &_bufferSize);
- if (!buffer) {
- _gameRef->LOG(0, "Error reinitializing script '%s' after load. Script will be terminated.", _filename);
- _state = SCRIPT_ERROR;
- return;
- }
-
- _buffer = new byte [_bufferSize];
- memcpy(_buffer, buffer, _bufferSize);
-
- delete _scriptStream;
- _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
-
- initTables();
- }
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/scriptables/script_engine.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "common/memstream.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(ScScript, false)
+
+//////////////////////////////////////////////////////////////////////////
+ScScript::ScScript(BaseGame *inGame, ScEngine *engine) : BaseClass(inGame) {
+ _buffer = NULL;
+ _bufferSize = _iP = 0;
+ _scriptStream = NULL;
+ _filename = NULL;
+ _currentLine = 0;
+
+ _symbols = NULL;
+ _numSymbols = 0;
+
+ _engine = engine;
+
+ _globals = NULL;
+
+ _scopeStack = NULL;
+ _callStack = NULL;
+ _thisStack = NULL;
+ _stack = NULL;
+
+ _operand = NULL;
+ _reg1 = NULL;
+
+ _functions = NULL;
+ _numFunctions = 0;
+
+ _methods = NULL;
+ _numMethods = 0;
+
+ _events = NULL;
+ _numEvents = 0;
+
+ _externals = NULL;
+ _numExternals = 0;
+
+ _state = SCRIPT_FINISHED;
+ _origState = SCRIPT_FINISHED;
+
+ _waitObject = NULL;
+ _waitTime = 0;
+ _waitFrozen = false;
+ _waitScript = NULL;
+
+ _timeSlice = 0;
+
+ _thread = false;
+ _methodThread = false;
+ _threadEvent = NULL;
+
+ _freezable = true;
+ _owner = NULL;
+
+ _unbreakable = false;
+ _parentScript = NULL;
+
+ _tracingMode = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScScript::~ScScript() {
+ cleanup();
+}
+
+void ScScript::readHeader() {
+ uint32 oldPos = _scriptStream->pos();
+ _scriptStream->seek(0);
+ _header.magic = _scriptStream->readUint32LE();
+ _header.version = _scriptStream->readUint32LE();
+ _header.codeStart = _scriptStream->readUint32LE();
+ _header.funcTable = _scriptStream->readUint32LE();
+ _header.symbolTable = _scriptStream->readUint32LE();
+ _header.eventTable = _scriptStream->readUint32LE();
+ _header.externalsTable = _scriptStream->readUint32LE();
+ _header.methodTable = _scriptStream->readUint32LE();
+ _scriptStream->seek(oldPos);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::initScript() {
+ if (!_scriptStream) {
+ _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
+ }
+ readHeader();
+
+ if (_header.magic != SCRIPT_MAGIC) {
+ _gameRef->LOG(0, "File '%s' is not a valid compiled script", _filename);
+ cleanup();
+ return STATUS_FAILED;
+ }
+
+ if (_header.version > SCRIPT_VERSION) {
+ _gameRef->LOG(0, "Script '%s' has a wrong version %d.%d (expected %d.%d)", _filename, _header.version / 256, _header.version % 256, SCRIPT_VERSION / 256, SCRIPT_VERSION % 256);
+ cleanup();
+ return STATUS_FAILED;
+ }
+
+ initTables();
+
+ // init stacks
+ _scopeStack = new ScStack(_gameRef);
+ _callStack = new ScStack(_gameRef);
+ _thisStack = new ScStack(_gameRef);
+ _stack = new ScStack(_gameRef);
+
+ _operand = new ScValue(_gameRef);
+ _reg1 = new ScValue(_gameRef);
+
+
+ // skip to the beginning
+ _iP = _header.codeStart;
+ _scriptStream->seek(_iP);
+ _currentLine = 0;
+
+ // ready to rumble...
+ _state = SCRIPT_RUNNING;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::initTables() {
+ uint32 origIP = _iP;
+
+ readHeader();
+ // load symbol table
+ _iP = _header.symbolTable;
+
+ _numSymbols = getDWORD();
+ _symbols = new char*[_numSymbols];
+ for (uint32 i = 0; i < _numSymbols; i++) {
+ uint32 index = getDWORD();
+ _symbols[index] = getString();
+ }
+
+ // load functions table
+ _iP = _header.funcTable;
+
+ _numFunctions = getDWORD();
+ _functions = new TFunctionPos[_numFunctions];
+ for (uint32 i = 0; i < _numFunctions; i++) {
+ _functions[i].pos = getDWORD();
+ _functions[i].name = getString();
+ }
+
+
+ // load events table
+ _iP = _header.eventTable;
+
+ _numEvents = getDWORD();
+ _events = new TEventPos[_numEvents];
+ for (uint32 i = 0; i < _numEvents; i++) {
+ _events[i].pos = getDWORD();
+ _events[i].name = getString();
+ }
+
+
+ // load externals
+ if (_header.version >= 0x0101) {
+ _iP = _header.externalsTable;
+
+ _numExternals = getDWORD();
+ _externals = new TExternalFunction[_numExternals];
+ for (uint32 i = 0; i < _numExternals; i++) {
+ _externals[i].dll_name = getString();
+ _externals[i].name = getString();
+ _externals[i].call_type = (TCallType)getDWORD();
+ _externals[i].returns = (TExternalType)getDWORD();
+ _externals[i].nu_params = getDWORD();
+ if (_externals[i].nu_params > 0) {
+ _externals[i].params = new TExternalType[_externals[i].nu_params];
+ for (int j = 0; j < _externals[i].nu_params; j++) {
+ _externals[i].params[j] = (TExternalType)getDWORD();
+ }
+ }
+ }
+ }
+
+ // load method table
+ _iP = _header.methodTable;
+
+ _numMethods = getDWORD();
+ _methods = new TMethodPos[_numMethods];
+ for (uint32 i = 0; i < _numMethods; i++) {
+ _methods[i].pos = getDWORD();
+ _methods[i].name = getString();
+ }
+
+
+ _iP = origIP;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::create(const char *filename, byte *buffer, uint32 size, BaseScriptHolder *owner) {
+ cleanup();
+
+ _thread = false;
+ _methodThread = false;
+
+ delete[] _threadEvent;
+ _threadEvent = NULL;
+
+ _filename = new char[strlen(filename) + 1];
+ if (_filename) {
+ strcpy(_filename, filename);
+ }
+
+ _buffer = new byte [size];
+ if (!_buffer) {
+ return STATUS_FAILED;
+ }
+
+ memcpy(_buffer, buffer, size);
+
+ _bufferSize = size;
+
+ bool res = initScript();
+ if (DID_FAIL(res)) {
+ return res;
+ }
+
+ // establish global variables table
+ _globals = new ScValue(_gameRef);
+
+ _owner = owner;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::createThread(ScScript *original, uint32 initIP, const Common::String &eventName) {
+ cleanup();
+
+ _thread = true;
+ _methodThread = false;
+ _threadEvent = new char[eventName.size() + 1];
+ if (_threadEvent) {
+ strcpy(_threadEvent, eventName.c_str());
+ }
+
+ // copy filename
+ _filename = new char[strlen(original->_filename) + 1];
+ if (_filename) {
+ strcpy(_filename, original->_filename);
+ }
+
+ // copy buffer
+ _buffer = new byte [original->_bufferSize];
+ if (!_buffer) {
+ return STATUS_FAILED;
+ }
+
+ memcpy(_buffer, original->_buffer, original->_bufferSize);
+ _bufferSize = original->_bufferSize;
+
+ // initialize
+ bool res = initScript();
+ if (DID_FAIL(res)) {
+ return res;
+ }
+
+ // copy globals
+ _globals = original->_globals;
+
+ // skip to the beginning of the event
+ _iP = initIP;
+ _scriptStream->seek(_iP);
+
+ _timeSlice = original->_timeSlice;
+ _freezable = original->_freezable;
+ _owner = original->_owner;
+
+ _engine = original->_engine;
+ _parentScript = original;
+
+ return STATUS_OK;
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::createMethodThread(ScScript *original, const Common::String &methodName) {
+ uint32 ip = original->getMethodPos(methodName);
+ if (ip == 0) {
+ return STATUS_FAILED;
+ }
+
+ cleanup();
+
+ _thread = true;
+ _methodThread = true;
+ _threadEvent = new char[methodName.size() + 1];
+ if (_threadEvent) {
+ strcpy(_threadEvent, methodName.c_str());
+ }
+
+ // copy filename
+ _filename = new char[strlen(original->_filename) + 1];
+ if (_filename) {
+ strcpy(_filename, original->_filename);
+ }
+
+ // copy buffer
+ _buffer = new byte [original->_bufferSize];
+ if (!_buffer) {
+ return STATUS_FAILED;
+ }
+
+ memcpy(_buffer, original->_buffer, original->_bufferSize);
+ _bufferSize = original->_bufferSize;
+
+ // initialize
+ bool res = initScript();
+ if (DID_FAIL(res)) {
+ return res;
+ }
+
+ // copy globals
+ _globals = original->_globals;
+
+ // skip to the beginning of the event
+ _iP = ip;
+
+ _timeSlice = original->_timeSlice;
+ _freezable = original->_freezable;
+ _owner = original->_owner;
+
+ _engine = original->_engine;
+ _parentScript = original;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScScript::cleanup() {
+ if (_buffer) {
+ delete[] _buffer;
+ }
+ _buffer = NULL;
+
+ if (_filename) {
+ delete[] _filename;
+ }
+ _filename = NULL;
+
+ if (_symbols) {
+ delete[] _symbols;
+ }
+ _symbols = NULL;
+ _numSymbols = 0;
+
+ if (_globals && !_thread) {
+ delete _globals;
+ }
+ _globals = NULL;
+
+ delete _scopeStack;
+ _scopeStack = NULL;
+
+ delete _callStack;
+ _callStack = NULL;
+
+ delete _thisStack;
+ _thisStack = NULL;
+
+ delete _stack;
+ _stack = NULL;
+
+ if (_functions) {
+ delete[] _functions;
+ }
+ _functions = NULL;
+ _numFunctions = 0;
+
+ if (_methods) {
+ delete[] _methods;
+ }
+ _methods = NULL;
+ _numMethods = 0;
+
+ if (_events) {
+ delete[] _events;
+ }
+ _events = NULL;
+ _numEvents = 0;
+
+
+ if (_externals) {
+ for (uint32 i = 0; i < _numExternals; i++) {
+ if (_externals[i].nu_params > 0) {
+ delete[] _externals[i].params;
+ }
+ }
+ delete[] _externals;
+ }
+ _externals = NULL;
+ _numExternals = 0;
+
+ delete _operand;
+ delete _reg1;
+ _operand = NULL;
+ _reg1 = NULL;
+
+ delete[] _threadEvent;
+ _threadEvent = NULL;
+
+ _state = SCRIPT_FINISHED;
+
+ _waitObject = NULL;
+ _waitTime = 0;
+ _waitFrozen = false;
+ _waitScript = NULL;
+
+ _parentScript = NULL; // ref only
+
+ delete _scriptStream;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 ScScript::getDWORD() {
+ _scriptStream->seek((int32)_iP);
+ uint32 ret = _scriptStream->readUint32LE();
+ _iP += sizeof(uint32);
+// assert(oldRet == ret);
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+double ScScript::getFloat() {
+ _scriptStream->seek((int32)_iP);
+ byte buffer[8];
+ _scriptStream->read(buffer, 8);
+
+#ifdef SCUMM_BIG_ENDIAN
+ // TODO: For lack of a READ_LE_UINT64
+ SWAP(buffer[0], buffer[7]);
+ SWAP(buffer[1], buffer[6]);
+ SWAP(buffer[2], buffer[5]);
+ SWAP(buffer[3], buffer[4]);
+#endif
+
+ double ret = *(double *)(buffer);
+ _iP += 8; // Hardcode the double-size used originally.
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *ScScript::getString() {
+ char *ret = (char *)(_buffer + _iP);
+ while (*(char *)(_buffer + _iP) != '\0') {
+ _iP++;
+ }
+ _iP++; // string terminator
+ _scriptStream->seek(_iP);
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::executeInstruction() {
+ bool ret = STATUS_OK;
+
+ uint32 dw;
+ const char *str = NULL;
+
+ //ScValue* op = new ScValue(_gameRef);
+ _operand->cleanup();
+
+ ScValue *op1;
+ ScValue *op2;
+
+ uint32 inst = getDWORD();
+ switch (inst) {
+
+ case II_DEF_VAR:
+ _operand->setNULL();
+ dw = getDWORD();
+ if (_scopeStack->_sP < 0) {
+ _globals->setProp(_symbols[dw], _operand);
+ } else {
+ _scopeStack->getTop()->setProp(_symbols[dw], _operand);
+ }
+
+ break;
+
+ case II_DEF_GLOB_VAR:
+ case II_DEF_CONST_VAR: {
+ dw = getDWORD();
+ /* char *temp = _symbols[dw]; // TODO delete */
+ // only create global var if it doesn't exist
+ if (!_engine->_globals->propExists(_symbols[dw])) {
+ _operand->setNULL();
+ _engine->_globals->setProp(_symbols[dw], _operand, false, inst == II_DEF_CONST_VAR);
+ }
+ break;
+ }
+
+ case II_RET:
+ if (_scopeStack->_sP >= 0 && _callStack->_sP >= 0) {
+ _scopeStack->pop();
+ _iP = (uint32)_callStack->pop()->getInt();
+ } else {
+ if (_thread) {
+ _state = SCRIPT_THREAD_FINISHED;
+ } else {
+ if (_numEvents == 0 && _numMethods == 0) {
+ _state = SCRIPT_FINISHED;
+ } else {
+ _state = SCRIPT_PERSISTENT;
+ }
+ }
+ }
+
+ break;
+
+ case II_RET_EVENT:
+ _state = SCRIPT_FINISHED;
+ break;
+
+
+ case II_CALL:
+ dw = getDWORD();
+
+ _operand->setInt(_iP);
+ _callStack->push(_operand);
+
+ _iP = dw;
+
+ break;
+
+ case II_CALL_BY_EXP: {
+ // push var
+ // push string
+ str = _stack->pop()->getString();
+ char *methodName = new char[strlen(str) + 1];
+ strcpy(methodName, str);
+
+ ScValue *var = _stack->pop();
+ if (var->_type == VAL_VARIABLE_REF) {
+ var = var->_valRef;
+ }
+
+ bool res = STATUS_FAILED;
+ bool triedNative = false;
+
+ // we are already calling this method, try native
+ if (_thread && _methodThread && strcmp(methodName, _threadEvent) == 0 && var->_type == VAL_NATIVE && _owner == var->getNative()) {
+ triedNative = true;
+ res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
+ }
+
+ if (DID_FAIL(res)) {
+ if (var->isNative() && var->getNative()->canHandleMethod(methodName)) {
+ if (!_unbreakable) {
+ _waitScript = var->getNative()->invokeMethodThread(methodName);
+ if (!_waitScript) {
+ _stack->correctParams(0);
+ runtimeError("Error invoking method '%s'.", methodName);
+ _stack->pushNULL();
+ } else {
+ _state = SCRIPT_WAITING_SCRIPT;
+ _waitScript->copyParameters(_stack);
+ }
+ } else {
+ // can call methods in unbreakable mode
+ _stack->correctParams(0);
+ runtimeError("Cannot call method '%s'. Ignored.", methodName);
+ _stack->pushNULL();
+ }
+ delete[] methodName;
+ break;
+ }
+ /*
+ ScValue* val = var->getProp(MethodName);
+ if (val){
+ dw = GetFuncPos(val->getString());
+ if (dw==0){
+ TExternalFunction* f = GetExternal(val->getString());
+ if (f){
+ ExternalCall(_stack, _thisStack, f);
+ }
+ else{
+ // not an internal nor external, try for native function
+ _gameRef->ExternalCall(this, _stack, _thisStack, val->getString());
+ }
+ }
+ else{
+ _operand->setInt(_iP);
+ _callStack->Push(_operand);
+ _iP = dw;
+ }
+ }
+ */
+ else {
+ res = STATUS_FAILED;
+ if (var->_type == VAL_NATIVE && !triedNative) {
+ res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
+ }
+
+ if (DID_FAIL(res)) {
+ _stack->correctParams(0);
+ runtimeError("Call to undefined method '%s'. Ignored.", methodName);
+ _stack->pushNULL();
+ }
+ }
+ }
+ delete[] methodName;
+ }
+ break;
+
+ case II_EXTERNAL_CALL: {
+ uint32 symbolIndex = getDWORD();
+
+ TExternalFunction *f = getExternal(_symbols[symbolIndex]);
+ if (f) {
+ externalCall(_stack, _thisStack, f);
+ } else {
+ _gameRef->externalCall(this, _stack, _thisStack, _symbols[symbolIndex]);
+ }
+
+ break;
+ }
+ case II_SCOPE:
+ _operand->setNULL();
+ _scopeStack->push(_operand);
+ break;
+
+ case II_CORRECT_STACK:
+ dw = getDWORD(); // params expected
+ _stack->correctParams(dw);
+ break;
+
+ case II_CREATE_OBJECT:
+ _operand->setObject();
+ _stack->push(_operand);
+ break;
+
+ case II_POP_EMPTY:
+ _stack->pop();
+ break;
+
+ case II_PUSH_VAR: {
+ ScValue *var = getVar(_symbols[getDWORD()]);
+ if (false && /*var->_type==VAL_OBJECT ||*/ var->_type == VAL_NATIVE) {
+ _operand->setReference(var);
+ _stack->push(_operand);
+ } else {
+ _stack->push(var);
+ }
+ break;
+ }
+
+ case II_PUSH_VAR_REF: {
+ ScValue *var = getVar(_symbols[getDWORD()]);
+ _operand->setReference(var);
+ _stack->push(_operand);
+ break;
+ }
+
+ case II_POP_VAR: {
+ char *varName = _symbols[getDWORD()];
+ ScValue *var = getVar(varName);
+ if (var) {
+ ScValue *val = _stack->pop();
+ if (!val) {
+ runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
+ var->setNULL();
+ } else {
+ if (val->getType() == VAL_VARIABLE_REF) {
+ val = val->_valRef;
+ }
+ if (val->_type == VAL_NATIVE) {
+ var->setValue(val);
+ } else {
+ var->copy(val);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case II_PUSH_VAR_THIS:
+ _stack->push(_thisStack->getTop());
+ break;
+
+ case II_PUSH_INT:
+ _stack->pushInt((int)getDWORD());
+ break;
+
+ case II_PUSH_FLOAT:
+ _stack->pushFloat(getFloat());
+ break;
+
+
+ case II_PUSH_BOOL:
+ _stack->pushBool(getDWORD() != 0);
+
+ break;
+
+ case II_PUSH_STRING:
+ _stack->pushString(getString());
+ break;
+
+ case II_PUSH_NULL:
+ _stack->pushNULL();
+ break;
+
+ case II_PUSH_THIS_FROM_STACK:
+ _operand->setReference(_stack->getTop());
+ _thisStack->push(_operand);
+ break;
+
+ case II_PUSH_THIS:
+ _operand->setReference(getVar(_symbols[getDWORD()]));
+ _thisStack->push(_operand);
+ break;
+
+ case II_POP_THIS:
+ _thisStack->pop();
+ break;
+
+ case II_PUSH_BY_EXP: {
+ str = _stack->pop()->getString();
+ ScValue *val = _stack->pop()->getProp(str);
+ if (val) {
+ _stack->push(val);
+ } else {
+ _stack->pushNULL();
+ }
+
+ break;
+ }
+
+ case II_POP_BY_EXP: {
+ str = _stack->pop()->getString();
+ ScValue *var = _stack->pop();
+ ScValue *val = _stack->pop();
+
+ if (val == NULL) {
+ runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
+ var->setNULL();
+ } else {
+ var->setProp(str, val);
+ }
+
+ break;
+ }
+
+ case II_PUSH_REG1:
+ _stack->push(_reg1);
+ break;
+
+ case II_POP_REG1:
+ _reg1->copy(_stack->pop());
+ break;
+
+ case II_JMP:
+ _iP = getDWORD();
+ break;
+
+ case II_JMP_FALSE: {
+ dw = getDWORD();
+ //if (!_stack->pop()->getBool()) _iP = dw;
+ ScValue *val = _stack->pop();
+ if (!val) {
+ runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
+ } else {
+ if (!val->getBool()) {
+ _iP = dw;
+ }
+ }
+ break;
+ }
+
+ case II_ADD:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ if (op1->isNULL() || op2->isNULL()) {
+ _operand->setNULL();
+ } else if (op1->getType() == VAL_STRING || op2->getType() == VAL_STRING) {
+ char *tempStr = new char [strlen(op1->getString()) + strlen(op2->getString()) + 1];
+ strcpy(tempStr, op1->getString());
+ strcat(tempStr, op2->getString());
+ _operand->setString(tempStr);
+ delete[] tempStr;
+ } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
+ _operand->setInt(op1->getInt() + op2->getInt());
+ } else {
+ _operand->setFloat(op1->getFloat() + op2->getFloat());
+ }
+
+ _stack->push(_operand);
+
+ break;
+
+ case II_SUB:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ if (op1->isNULL() || op2->isNULL()) {
+ _operand->setNULL();
+ } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
+ _operand->setInt(op1->getInt() - op2->getInt());
+ } else {
+ _operand->setFloat(op1->getFloat() - op2->getFloat());
+ }
+
+ _stack->push(_operand);
+
+ break;
+
+ case II_MUL:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ if (op1->isNULL() || op2->isNULL()) {
+ _operand->setNULL();
+ } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
+ _operand->setInt(op1->getInt() * op2->getInt());
+ } else {
+ _operand->setFloat(op1->getFloat() * op2->getFloat());
+ }
+
+ _stack->push(_operand);
+
+ break;
+
+ case II_DIV:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ if (op2->getFloat() == 0.0f) {
+ runtimeError("Division by zero.");
+ }
+
+ if (op1->isNULL() || op2->isNULL() || op2->getFloat() == 0.0f) {
+ _operand->setNULL();
+ } else {
+ _operand->setFloat(op1->getFloat() / op2->getFloat());
+ }
+
+ _stack->push(_operand);
+
+ break;
+
+ case II_MODULO:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ if (op2->getInt() == 0) {
+ runtimeError("Division by zero.");
+ }
+
+ if (op1->isNULL() || op2->isNULL() || op2->getInt() == 0) {
+ _operand->setNULL();
+ } else {
+ _operand->setInt(op1->getInt() % op2->getInt());
+ }
+
+ _stack->push(_operand);
+
+ break;
+
+ case II_NOT:
+ op1 = _stack->pop();
+ //if (op1->isNULL()) _operand->setNULL();
+ if (op1->isNULL()) {
+ _operand->setBool(true);
+ } else {
+ _operand->setBool(!op1->getBool());
+ }
+ _stack->push(_operand);
+
+ break;
+
+ case II_AND:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+ if (op1 == NULL || op2 == NULL) {
+ runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
+ _operand->setBool(false);
+ } else {
+ _operand->setBool(op1->getBool() && op2->getBool());
+ }
+ _stack->push(_operand);
+ break;
+
+ case II_OR:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+ if (op1 == NULL || op2 == NULL) {
+ runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
+ _operand->setBool(false);
+ } else {
+ _operand->setBool(op1->getBool() || op2->getBool());
+ }
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_EQ:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(false);
+ else if (op1->isNative() && op2->isNative()){
+ _operand->setBool(op1->getNative() == op2->getNative());
+ }
+ else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING){
+ _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())==0);
+ }
+ else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() == op2->getFloat());
+ }
+ else{
+ _operand->setBool(op1->getInt() == op2->getInt());
+ }
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) == 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_NE:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(true);
+ else if (op1->isNative() && op2->isNative()){
+ _operand->setBool(op1->getNative() != op2->getNative());
+ }
+ else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING){
+ _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())!=0);
+ }
+ else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() != op2->getFloat());
+ }
+ else{
+ _operand->setBool(op1->getInt() != op2->getInt());
+ }
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) != 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_L:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() < op2->getFloat());
+ }
+ else _operand->setBool(op1->getInt() < op2->getInt());
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) < 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_G:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() > op2->getFloat());
+ }
+ else _operand->setBool(op1->getInt() > op2->getInt());
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) > 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_LE:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() <= op2->getFloat());
+ }
+ else _operand->setBool(op1->getInt() <= op2->getInt());
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) <= 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_GE:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ /*
+ if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT){
+ _operand->setBool(op1->getFloat() >= op2->getFloat());
+ }
+ else _operand->setBool(op1->getInt() >= op2->getInt());
+ */
+
+ _operand->setBool(ScValue::compare(op1, op2) >= 0);
+ _stack->push(_operand);
+ break;
+
+ case II_CMP_STRICT_EQ:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ //_operand->setBool(op1->getType()==op2->getType() && op1->getFloat()==op2->getFloat());
+ _operand->setBool(ScValue::compareStrict(op1, op2) == 0);
+ _stack->push(_operand);
+
+ break;
+
+ case II_CMP_STRICT_NE:
+ op2 = _stack->pop();
+ op1 = _stack->pop();
+
+ //_operand->setBool(op1->getType()!=op2->getType() || op1->getFloat()!=op2->getFloat());
+ _operand->setBool(ScValue::compareStrict(op1, op2) != 0);
+ _stack->push(_operand);
+ break;
+
+ case II_DBG_LINE: {
+ int newLine = getDWORD();
+ if (newLine != _currentLine) {
+ _currentLine = newLine;
+ }
+ break;
+
+ }
+ default:
+ _gameRef->LOG(0, "Fatal: Invalid instruction %d ('%s', line %d, IP:0x%x)\n", inst, _filename, _currentLine, _iP - sizeof(uint32));
+ _state = SCRIPT_FINISHED;
+ ret = STATUS_FAILED;
+ } // switch(instruction)
+
+ //delete op;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 ScScript::getFuncPos(const Common::String &name) {
+ for (uint32 i = 0; i < _numFunctions; i++) {
+ if (name == _functions[i].name) {
+ return _functions[i].pos;
+ }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 ScScript::getMethodPos(const Common::String &name) {
+ for (uint32 i = 0; i < _numMethods; i++) {
+ if (name == _methods[i].name) {
+ return _methods[i].pos;
+ }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScScript::getVar(char *name) {
+ ScValue *ret = NULL;
+
+ // scope locals
+ if (_scopeStack->_sP >= 0) {
+ if (_scopeStack->getTop()->propExists(name)) {
+ ret = _scopeStack->getTop()->getProp(name);
+ }
+ }
+
+ // script globals
+ if (ret == NULL) {
+ if (_globals->propExists(name)) {
+ ret = _globals->getProp(name);
+ }
+ }
+
+ // engine globals
+ if (ret == NULL) {
+ if (_engine->_globals->propExists(name)) {
+ ret = _engine->_globals->getProp(name);
+ }
+ }
+
+ if (ret == NULL) {
+ //RuntimeError("Variable '%s' is inaccessible in the current block. Consider changing the script.", name);
+ _gameRef->LOG(0, "Warning: variable '%s' is inaccessible in the current block. Consider changing the script (script:%s, line:%d)", name, _filename, _currentLine);
+ ScValue *val = new ScValue(_gameRef);
+ ScValue *scope = _scopeStack->getTop();
+ if (scope) {
+ scope->setProp(name, val);
+ ret = _scopeStack->getTop()->getProp(name);
+ } else {
+ _globals->setProp(name, val);
+ ret = _globals->getProp(name);
+ }
+ delete val;
+ }
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::waitFor(BaseObject *object) {
+ if (_unbreakable) {
+ runtimeError("Script cannot be interrupted.");
+ return STATUS_OK;
+ }
+
+ _state = SCRIPT_WAITING;
+ _waitObject = object;
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::waitForExclusive(BaseObject *object) {
+ _engine->resetObject(object);
+ return waitFor(object);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::sleep(uint32 duration) {
+ if (_unbreakable) {
+ runtimeError("Script cannot be interrupted.");
+ return STATUS_OK;
+ }
+
+ _state = SCRIPT_SLEEPING;
+ if (_gameRef->_state == GAME_FROZEN) {
+ _waitTime = g_system->getMillis() + duration;
+ _waitFrozen = true;
+ } else {
+ _waitTime = _gameRef->_timer + duration;
+ _waitFrozen = false;
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::finish(bool includingThreads) {
+ if (_state != SCRIPT_FINISHED && includingThreads) {
+ _state = SCRIPT_FINISHED;
+ finishThreads();
+ } else {
+ _state = SCRIPT_FINISHED;
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::run() {
+ _state = SCRIPT_RUNNING;
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void ScScript::runtimeError(const char *fmt, ...) {
+ char buff[256];
+ va_list va;
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ _gameRef->LOG(0, "Runtime error. Script '%s', line %d", _filename, _currentLine);
+ _gameRef->LOG(0, " %s", buff);
+
+ if (!_gameRef->_suppressScriptErrors) {
+ _gameRef->quickMessage("Script runtime error. View log for details.");
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::persist(BasePersistenceManager *persistMgr) {
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ // buffer
+ if (persistMgr->getIsSaving()) {
+ if (_state != SCRIPT_PERSISTENT && _state != SCRIPT_FINISHED && _state != SCRIPT_THREAD_FINISHED) {
+ persistMgr->transfer(TMEMBER(_bufferSize));
+ persistMgr->putBytes(_buffer, _bufferSize);
+ } else {
+ // don't save idle/finished scripts
+ int bufferSize = 0;
+ persistMgr->transfer(TMEMBER(bufferSize));
+ }
+ } else {
+ persistMgr->transfer(TMEMBER(_bufferSize));
+ if (_bufferSize > 0) {
+ _buffer = new byte[_bufferSize];
+ persistMgr->getBytes(_buffer, _bufferSize);
+ _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
+ initTables();
+ } else {
+ _buffer = NULL;
+ _scriptStream = NULL;
+ }
+ }
+
+ persistMgr->transfer(TMEMBER(_callStack));
+ persistMgr->transfer(TMEMBER(_currentLine));
+ persistMgr->transfer(TMEMBER(_engine));
+ persistMgr->transfer(TMEMBER(_filename));
+ persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transfer(TMEMBER(_globals));
+ persistMgr->transfer(TMEMBER(_iP));
+ persistMgr->transfer(TMEMBER(_scopeStack));
+ persistMgr->transfer(TMEMBER(_stack));
+ persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transfer(TMEMBER(_operand));
+ persistMgr->transfer(TMEMBER_INT(_origState));
+ persistMgr->transfer(TMEMBER(_owner));
+ persistMgr->transfer(TMEMBER(_reg1));
+ persistMgr->transfer(TMEMBER(_thread));
+ persistMgr->transfer(TMEMBER(_threadEvent));
+ persistMgr->transfer(TMEMBER(_thisStack));
+ persistMgr->transfer(TMEMBER(_timeSlice));
+ persistMgr->transfer(TMEMBER(_waitObject));
+ persistMgr->transfer(TMEMBER(_waitScript));
+ persistMgr->transfer(TMEMBER(_waitTime));
+ persistMgr->transfer(TMEMBER(_waitFrozen));
+
+ persistMgr->transfer(TMEMBER(_methodThread));
+ persistMgr->transfer(TMEMBER(_methodThread));
+ persistMgr->transfer(TMEMBER(_unbreakable));
+ persistMgr->transfer(TMEMBER(_parentScript));
+
+ if (!persistMgr->getIsSaving()) {
+ _tracingMode = false;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScScript *ScScript::invokeEventHandler(const Common::String &eventName, bool unbreakable) {
+ //if (_state!=SCRIPT_PERSISTENT) return NULL;
+
+ uint32 pos = getEventPos(eventName);
+ if (!pos) {
+ return NULL;
+ }
+
+ ScScript *thread = new ScScript(_gameRef, _engine);
+ if (thread) {
+ bool ret = thread->createThread(this, pos, eventName);
+ if (DID_SUCCEED(ret)) {
+ thread->_unbreakable = unbreakable;
+ _engine->_scripts.add(thread);
+ return thread;
+ } else {
+ delete thread;
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 ScScript::getEventPos(const Common::String &name) {
+ for (int i = _numEvents - 1; i >= 0; i--) {
+ if (scumm_stricmp(name.c_str(), _events[i].name) == 0) {
+ return _events[i].pos;
+ }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::canHandleEvent(const Common::String &eventName) {
+ return getEventPos(eventName) != 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::canHandleMethod(const Common::String &methodName) {
+ return getMethodPos(methodName) != 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::pause() {
+ if (_state == SCRIPT_PAUSED) {
+ _gameRef->LOG(0, "Attempting to pause a paused script ('%s', line %d)", _filename, _currentLine);
+ return STATUS_FAILED;
+ }
+
+ if (!_freezable || _state == SCRIPT_PERSISTENT) {
+ return STATUS_OK;
+ }
+
+ _origState = _state;
+ _state = SCRIPT_PAUSED;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::resume() {
+ if (_state != SCRIPT_PAUSED) {
+ return STATUS_OK;
+ }
+
+ _state = _origState;
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScScript::TExternalFunction *ScScript::getExternal(char *name) {
+ for (uint32 i = 0; i < _numExternals; i++) {
+ if (strcmp(name, _externals[i].name) == 0) {
+ return &_externals[i];
+ }
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::externalCall(ScStack *stack, ScStack *thisStack, ScScript::TExternalFunction *function) {
+
+ _gameRef->LOG(0, "External functions are not supported on this platform.");
+ stack->correctParams(0);
+ stack->pushNULL();
+ return STATUS_FAILED;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::copyParameters(ScStack *stack) {
+ int i;
+ int numParams = stack->pop()->getInt();
+ for (i = numParams - 1; i >= 0; i--) {
+ _stack->push(stack->getAt(i));
+ }
+ _stack->pushInt(numParams);
+
+ for (i = 0; i < numParams; i++) {
+ stack->pop();
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScScript::finishThreads() {
+ for (uint32 i = 0; i < _engine->_scripts.size(); i++) {
+ ScScript *scr = _engine->_scripts[i];
+ if (scr->_thread && scr->_state != SCRIPT_FINISHED && scr->_owner == _owner && scumm_stricmp(scr->_filename, _filename) == 0) {
+ scr->finish(true);
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// IWmeDebugScript interface implementation
+int ScScript::dbgGetLine() {
+ return _currentLine;
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char *ScScript::dbgGetFilename() {
+ return _filename;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void ScScript::afterLoad() {
+ if (_buffer == NULL) {
+ byte *buffer = _engine->getCompiledScript(_filename, &_bufferSize);
+ if (!buffer) {
+ _gameRef->LOG(0, "Error reinitializing script '%s' after load. Script will be terminated.", _filename);
+ _state = SCRIPT_ERROR;
+ return;
+ }
+
+ _buffer = new byte [_bufferSize];
+ memcpy(_buffer, buffer, _bufferSize);
+
+ delete _scriptStream;
+ _scriptStream = new Common::MemoryReadStream(_buffer, _bufferSize);
+
+ initTables();
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h
index 4daeacd026..0616bce58a 100644
--- a/engines/wintermute/base/scriptables/script.h
+++ b/engines/wintermute/base/scriptables/script.h
@@ -1,174 +1,174 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SCSCRIPT_H
-#define WINTERMUTE_SCSCRIPT_H
-
-
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView
-#include "engines/wintermute/coll_templ.h"
-
-namespace Wintermute {
-class BaseScriptHolder;
-class BaseObject;
-class ScEngine;
-class ScStack;
-class ScScript : public BaseClass {
-public:
- BaseArray<int> _breakpoints;
- bool _tracingMode;
-
- ScScript *_parentScript;
- bool _unbreakable;
- bool finishThreads();
- bool copyParameters(ScStack *stack);
-
- void afterLoad();
-private:
- ScValue *_operand;
- ScValue *_reg1;
-public:
- bool _freezable;
- bool resume();
- bool pause();
- bool canHandleEvent(const Common::String &eventName);
- bool canHandleMethod(const Common::String &methodName);
- bool createThread(ScScript *original, uint32 initIP, const Common::String &eventName);
- bool createMethodThread(ScScript *original, const Common::String &methodName);
- ScScript *invokeEventHandler(const Common::String &eventName, bool unbreakable = false);
- uint32 _timeSlice;
- DECLARE_PERSISTENT(ScScript, BaseClass)
- void runtimeError(const char *fmt, ...);
- bool run();
- bool finish(bool includingThreads = false);
- bool sleep(uint32 duration);
- bool waitForExclusive(BaseObject *object);
- bool waitFor(BaseObject *object);
- uint32 _waitTime;
- bool _waitFrozen;
- BaseObject *_waitObject;
- ScScript *_waitScript;
- TScriptState _state;
- TScriptState _origState;
- ScValue *getVar(char *name);
- uint32 getFuncPos(const Common::String &name);
- uint32 getEventPos(const Common::String &name);
- uint32 getMethodPos(const Common::String &name);
- typedef struct {
- uint32 magic;
- uint32 version;
- uint32 codeStart;
- uint32 funcTable;
- uint32 symbolTable;
- uint32 eventTable;
- uint32 externalsTable;
- uint32 methodTable;
- } TScriptHeader;
-
- TScriptHeader _header;
-
- typedef struct {
- char *name;
- uint32 pos;
- } TFunctionPos;
-
- typedef struct {
- char *name;
- uint32 pos;
- } TMethodPos;
-
- typedef struct {
- char *name;
- uint32 pos;
- } TEventPos;
-
- typedef struct {
- char *name;
- char *dll_name;
- TCallType call_type;
- TExternalType returns;
- int nu_params;
- TExternalType *params;
- } TExternalFunction;
-
-
- ScStack *_callStack;
- ScStack *_thisStack;
- ScStack *_scopeStack;
- ScStack *_stack;
- ScValue *_globals;
- ScEngine *_engine;
- int _currentLine;
- bool executeInstruction();
- char *getString();
- uint32 getDWORD();
- double getFloat();
- void cleanup();
- bool create(const char *filename, byte *buffer, uint32 size, BaseScriptHolder *owner);
- uint32 _iP;
-private:
- void readHeader();
- uint32 _bufferSize;
- byte *_buffer;
-public:
- Common::SeekableReadStream *_scriptStream;
- ScScript(BaseGame *inGame, ScEngine *engine);
- virtual ~ScScript();
- char *_filename;
- bool _thread;
- bool _methodThread;
- char *_threadEvent;
- BaseScriptHolder *_owner;
- ScScript::TExternalFunction *getExternal(char *name);
- bool externalCall(ScStack *stack, ScStack *thisStack, ScScript::TExternalFunction *function);
-private:
- char **_symbols;
- uint32 _numSymbols;
- TFunctionPos *_functions;
- TMethodPos *_methods;
- TEventPos *_events;
- uint32 _numExternals;
- TExternalFunction *_externals;
- uint32 _numFunctions;
- uint32 _numMethods;
- uint32 _numEvents;
-
- bool initScript();
- bool initTables();
-
-
-// IWmeDebugScript interface implementation
-public:
- virtual int dbgGetLine();
- virtual const char *dbgGetFilename();
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SCSCRIPT_H
+#define WINTERMUTE_SCSCRIPT_H
+
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView
+#include "engines/wintermute/coll_templ.h"
+
+namespace Wintermute {
+class BaseScriptHolder;
+class BaseObject;
+class ScEngine;
+class ScStack;
+class ScScript : public BaseClass {
+public:
+ BaseArray<int> _breakpoints;
+ bool _tracingMode;
+
+ ScScript *_parentScript;
+ bool _unbreakable;
+ bool finishThreads();
+ bool copyParameters(ScStack *stack);
+
+ void afterLoad();
+private:
+ ScValue *_operand;
+ ScValue *_reg1;
+public:
+ bool _freezable;
+ bool resume();
+ bool pause();
+ bool canHandleEvent(const Common::String &eventName);
+ bool canHandleMethod(const Common::String &methodName);
+ bool createThread(ScScript *original, uint32 initIP, const Common::String &eventName);
+ bool createMethodThread(ScScript *original, const Common::String &methodName);
+ ScScript *invokeEventHandler(const Common::String &eventName, bool unbreakable = false);
+ uint32 _timeSlice;
+ DECLARE_PERSISTENT(ScScript, BaseClass)
+ void runtimeError(const char *fmt, ...);
+ bool run();
+ bool finish(bool includingThreads = false);
+ bool sleep(uint32 duration);
+ bool waitForExclusive(BaseObject *object);
+ bool waitFor(BaseObject *object);
+ uint32 _waitTime;
+ bool _waitFrozen;
+ BaseObject *_waitObject;
+ ScScript *_waitScript;
+ TScriptState _state;
+ TScriptState _origState;
+ ScValue *getVar(char *name);
+ uint32 getFuncPos(const Common::String &name);
+ uint32 getEventPos(const Common::String &name);
+ uint32 getMethodPos(const Common::String &name);
+ typedef struct {
+ uint32 magic;
+ uint32 version;
+ uint32 codeStart;
+ uint32 funcTable;
+ uint32 symbolTable;
+ uint32 eventTable;
+ uint32 externalsTable;
+ uint32 methodTable;
+ } TScriptHeader;
+
+ TScriptHeader _header;
+
+ typedef struct {
+ char *name;
+ uint32 pos;
+ } TFunctionPos;
+
+ typedef struct {
+ char *name;
+ uint32 pos;
+ } TMethodPos;
+
+ typedef struct {
+ char *name;
+ uint32 pos;
+ } TEventPos;
+
+ typedef struct {
+ char *name;
+ char *dll_name;
+ TCallType call_type;
+ TExternalType returns;
+ int nu_params;
+ TExternalType *params;
+ } TExternalFunction;
+
+
+ ScStack *_callStack;
+ ScStack *_thisStack;
+ ScStack *_scopeStack;
+ ScStack *_stack;
+ ScValue *_globals;
+ ScEngine *_engine;
+ int _currentLine;
+ bool executeInstruction();
+ char *getString();
+ uint32 getDWORD();
+ double getFloat();
+ void cleanup();
+ bool create(const char *filename, byte *buffer, uint32 size, BaseScriptHolder *owner);
+ uint32 _iP;
+private:
+ void readHeader();
+ uint32 _bufferSize;
+ byte *_buffer;
+public:
+ Common::SeekableReadStream *_scriptStream;
+ ScScript(BaseGame *inGame, ScEngine *engine);
+ virtual ~ScScript();
+ char *_filename;
+ bool _thread;
+ bool _methodThread;
+ char *_threadEvent;
+ BaseScriptHolder *_owner;
+ ScScript::TExternalFunction *getExternal(char *name);
+ bool externalCall(ScStack *stack, ScStack *thisStack, ScScript::TExternalFunction *function);
+private:
+ char **_symbols;
+ uint32 _numSymbols;
+ TFunctionPos *_functions;
+ TMethodPos *_methods;
+ TEventPos *_events;
+ uint32 _numExternals;
+ TExternalFunction *_externals;
+ uint32 _numFunctions;
+ uint32 _numMethods;
+ uint32 _numEvents;
+
+ bool initScript();
+ bool initTables();
+
+
+// IWmeDebugScript interface implementation
+public:
+ virtual int dbgGetLine();
+ virtual const char *dbgGetFilename();
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_engine.cpp b/engines/wintermute/base/scriptables/script_engine.cpp
index 02f6080958..20e2ccadd1 100644
--- a/engines/wintermute/base/scriptables/script_engine.cpp
+++ b/engines/wintermute/base/scriptables/script_engine.cpp
@@ -1,610 +1,610 @@
-/* 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/base/scriptables/script_engine.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_ext_math.h"
-#include "engines/wintermute/base/base_engine.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/utils/utils.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(ScEngine, true)
-
-#define COMPILER_DLL "dcscomp.dll"
-//////////////////////////////////////////////////////////////////////////
-ScEngine::ScEngine(BaseGame *inGame) : BaseClass(inGame) {
- _gameRef->LOG(0, "Initializing scripting engine...");
-
- if (_compilerAvailable) {
- _gameRef->LOG(0, " Script compiler bound successfuly");
- } else {
- _gameRef->LOG(0, " Script compiler is NOT available");
- }
-
- _globals = new ScValue(_gameRef);
-
-
- // register 'Game' as global variable
- if (!_globals->propExists("Game")) {
- ScValue val(_gameRef);
- val.setNative(_gameRef, true);
- _globals->setProp("Game", &val);
- }
-
- // register 'Math' as global variable
- if (!_globals->propExists("Math")) {
- ScValue val(_gameRef);
- val.setNative(_gameRef->_mathClass, true);
- _globals->setProp("Math", &val);
- }
-
- // prepare script cache
- for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
- _cachedScripts[i] = NULL;
- }
-
- _currentScript = NULL;
-
- _isProfiling = false;
- _profilingStartTime = 0;
-
- //EnableProfiling();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScEngine::~ScEngine() {
- _gameRef->LOG(0, "Shutting down scripting engine");
-
- disableProfiling();
-
- cleanup();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::cleanup() {
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (!_scripts[i]->_thread && _scripts[i]->_owner) {
- _scripts[i]->_owner->removeScript(_scripts[i]);
- }
- delete _scripts[i];
- _scripts.remove_at(i);
- i--;
- }
-
- _scripts.clear();
-
- delete _globals;
- _globals = NULL;
-
- emptyScriptCache();
-
- _currentScript = NULL; // ref only
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-byte *ScEngine::loadFile(void *data, char *filename, uint32 *size) {
- return BaseFileManager::getEngineInstance()->readWholeFile(filename, size);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::closeFile(void *data, byte *buffer) {
- delete[] buffer;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::parseElement(void *data, int line, int type, void *elementData) {
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScScript *ScEngine::runScript(const char *filename, BaseScriptHolder *owner) {
- byte *compBuffer;
- uint32 compSize;
-
- // get script from cache
- compBuffer = getCompiledScript(filename, &compSize);
- if (!compBuffer) {
- return NULL;
- }
-
- // add new script
- ScScript *script = new ScScript(_gameRef, this);
- bool ret = script->create(filename, compBuffer, compSize, owner);
- if (DID_FAIL(ret)) {
- _gameRef->LOG(ret, "Error running script '%s'...", filename);
- delete script;
- return NULL;
- } else {
- // publish the "self" pseudo-variable
- ScValue val(_gameRef);
- if (owner) {
- val.setNative(owner, true);
- } else {
- val.setNULL();
- }
-
- script->_globals->setProp("self", &val);
- script->_globals->setProp("this", &val);
-
- _scripts.add(script);
-
- return script;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-byte *ScEngine::getCompiledScript(const char *filename, uint32 *outSize, bool ignoreCache) {
- // is script in cache?
- if (!ignoreCache) {
- for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
- if (_cachedScripts[i] && scumm_stricmp(_cachedScripts[i]->_filename.c_str(), filename) == 0) {
- _cachedScripts[i]->_timestamp = g_system->getMillis();
- *outSize = _cachedScripts[i]->_size;
- return _cachedScripts[i]->_buffer;
- }
- }
- }
-
- // nope, load it
- byte *compBuffer;
- uint32 compSize;
-
- uint32 size;
-
- byte *buffer = BaseEngine::instance().getFileManager()->readWholeFile(filename, &size);
- if (!buffer) {
- _gameRef->LOG(0, "ScEngine::GetCompiledScript - error opening script '%s'", filename);
- return NULL;
- }
-
- // needs to be compiled?
- if (FROM_LE_32(*(uint32 *)buffer) == SCRIPT_MAGIC) {
- compBuffer = buffer;
- compSize = size;
- } else {
- if (!_compilerAvailable) {
- _gameRef->LOG(0, "ScEngine::GetCompiledScript - script '%s' needs to be compiled but compiler is not available", filename);
- delete[] buffer;
- return NULL;
- }
- // This code will never be called, since _compilerAvailable is const false.
- // It's only here in the event someone would want to reinclude the compiler.
- error("Script needs compilation, ScummVM does not contain a WME compiler");
- }
-
- byte *ret = NULL;
-
- // add script to cache
- CScCachedScript *cachedScript = new CScCachedScript(filename, compBuffer, compSize);
- if (cachedScript) {
- int index = 0;
- uint32 minTime = g_system->getMillis();
- for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
- if (_cachedScripts[i] == NULL) {
- index = i;
- break;
- } else if (_cachedScripts[i]->_timestamp <= minTime) {
- minTime = _cachedScripts[i]->_timestamp;
- index = i;
- }
- }
-
- if (_cachedScripts[index] != NULL) {
- delete _cachedScripts[index];
- }
- _cachedScripts[index] = cachedScript;
-
- ret = cachedScript->_buffer;
- *outSize = cachedScript->_size;
- }
-
-
- // cleanup
- delete[] buffer;
-
- return ret;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::tick() {
- if (_scripts.size() == 0) {
- return STATUS_OK;
- }
-
-
- // resolve waiting scripts
- for (uint32 i = 0; i < _scripts.size(); i++) {
-
- switch (_scripts[i]->_state) {
- case SCRIPT_WAITING: {
- /*
- bool obj_found=false;
- for(int j=0; j<_gameRef->_regObjects.size(); j++)
- {
- if (_gameRef->_regObjects[j] == _scripts[i]->_waitObject)
- {
- if (_gameRef->_regObjects[j]->IsReady()) _scripts[i]->Run();
- obj_found = true;
- break;
- }
- }
- if (!obj_found) _scripts[i]->finish(); // _waitObject no longer exists
- */
- if (_gameRef->validObject(_scripts[i]->_waitObject)) {
- if (_scripts[i]->_waitObject->isReady()) {
- _scripts[i]->run();
- }
- } else {
- _scripts[i]->finish();
- }
- break;
- }
-
- case SCRIPT_SLEEPING: {
- if (_scripts[i]->_waitFrozen) {
- if (_scripts[i]->_waitTime <= g_system->getMillis()) {
- _scripts[i]->run();
- }
- } else {
- if (_scripts[i]->_waitTime <= _gameRef->_timer) {
- _scripts[i]->run();
- }
- }
- break;
- }
-
- case SCRIPT_WAITING_SCRIPT: {
- if (!isValidScript(_scripts[i]->_waitScript) || _scripts[i]->_waitScript->_state == SCRIPT_ERROR) {
- // fake return value
- _scripts[i]->_stack->pushNULL();
- _scripts[i]->_waitScript = NULL;
- _scripts[i]->run();
- } else {
- if (_scripts[i]->_waitScript->_state == SCRIPT_THREAD_FINISHED) {
- // copy return value
- _scripts[i]->_stack->push(_scripts[i]->_waitScript->_stack->pop());
- _scripts[i]->run();
- _scripts[i]->_waitScript->finish();
- _scripts[i]->_waitScript = NULL;
- }
- }
- break;
- }
- default:
- break;
- } // switch
- } // for each script
-
-
- // execute scripts
- for (uint32 i = 0; i < _scripts.size(); i++) {
-
- // skip paused scripts
- if (_scripts[i]->_state == SCRIPT_PAUSED) {
- continue;
- }
-
- // time sliced script
- if (_scripts[i]->_timeSlice > 0) {
- uint32 startTime = g_system->getMillis();
- while (_scripts[i]->_state == SCRIPT_RUNNING && g_system->getMillis() - startTime < _scripts[i]->_timeSlice) {
- _currentScript = _scripts[i];
- _scripts[i]->executeInstruction();
- }
- if (_isProfiling && _scripts[i]->_filename) {
- addScriptTime(_scripts[i]->_filename, g_system->getMillis() - startTime);
- }
- }
-
- // normal script
- else {
- uint32 startTime = 0;
- bool isProfiling = _isProfiling;
- if (isProfiling) {
- startTime = g_system->getMillis();
- }
-
- while (_scripts[i]->_state == SCRIPT_RUNNING) {
- _currentScript = _scripts[i];
- _scripts[i]->executeInstruction();
- }
- if (isProfiling && _scripts[i]->_filename) {
- addScriptTime(_scripts[i]->_filename, g_system->getMillis() - startTime);
- }
- }
- _currentScript = NULL;
- }
-
- removeFinishedScripts();
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::tickUnbreakable() {
- // execute unbreakable scripts
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (!_scripts[i]->_unbreakable) {
- continue;
- }
-
- while (_scripts[i]->_state == SCRIPT_RUNNING) {
- _currentScript = _scripts[i];
- _scripts[i]->executeInstruction();
- }
- _scripts[i]->finish();
- _currentScript = NULL;
- }
- removeFinishedScripts();
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::removeFinishedScripts() {
- // remove finished scripts
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i]->_state == SCRIPT_FINISHED || _scripts[i]->_state == SCRIPT_ERROR) {
- if (!_scripts[i]->_thread && _scripts[i]->_owner) {
- _scripts[i]->_owner->removeScript(_scripts[i]);
- }
-
- delete _scripts[i];
- _scripts.remove_at(i);
- i--;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int ScEngine::getNumScripts(int *running, int *waiting, int *persistent) {
- int numRunning = 0, numWaiting = 0, numPersistent = 0, numTotal = 0;
-
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i]->_state == SCRIPT_FINISHED) {
- continue;
- }
- switch (_scripts[i]->_state) {
- case SCRIPT_RUNNING:
- case SCRIPT_SLEEPING:
- case SCRIPT_PAUSED:
- numRunning++;
- break;
- case SCRIPT_WAITING:
- numWaiting++;
- break;
- case SCRIPT_PERSISTENT:
- numPersistent++;
- break;
- default:
- warning("ScEngine::GetNumScripts - unhandled enum");
- break;
- }
- numTotal++;
- }
- if (running) {
- *running = numRunning;
- }
- if (waiting) {
- *waiting = numWaiting;
- }
- if (persistent) {
- *persistent = numPersistent;
- }
-
- return numTotal;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::emptyScriptCache() {
- for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
- if (_cachedScripts[i]) {
- delete _cachedScripts[i];
- _cachedScripts[i] = NULL;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::resetObject(BaseObject *Object) {
- // terminate all scripts waiting for this object
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i]->_state == SCRIPT_WAITING && _scripts[i]->_waitObject == Object) {
- if (!_gameRef->_compatKillMethodThreads) {
- resetScript(_scripts[i]);
- }
-
- bool isThread = _scripts[i]->_methodThread || _scripts[i]->_thread;
- _scripts[i]->finish(!isThread); // 1.9b1 - top-level script kills its threads as well
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::resetScript(ScScript *script) {
- // terminate all scripts waiting for this script
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i]->_state == SCRIPT_WAITING_SCRIPT && _scripts[i]->_waitScript == script) {
- _scripts[i]->finish();
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::persist(BasePersistenceManager *persistMgr) {
- if (!persistMgr->getIsSaving()) {
- cleanup();
- }
-
- persistMgr->transfer(TMEMBER(_gameRef));
- persistMgr->transfer(TMEMBER(_currentScript));
- persistMgr->transfer(TMEMBER(_globals));
- _scripts.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::editorCleanup() {
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i]->_owner == NULL && (_scripts[i]->_state == SCRIPT_FINISHED || _scripts[i]->_state == SCRIPT_ERROR)) {
- delete _scripts[i];
- _scripts.remove_at(i);
- i--;
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::pauseAll() {
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i] != _currentScript) {
- _scripts[i]->pause();
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::resumeAll() {
- for (uint32 i = 0; i < _scripts.size(); i++) {
- _scripts[i]->resume();
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::isValidScript(ScScript *script) {
- for (uint32 i = 0; i < _scripts.size(); i++) {
- if (_scripts[i] == script) {
- return true;
- }
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScEngine::clearGlobals(bool includingNatives) {
- _globals->CleanProps(includingNatives);
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::addScriptTime(const char *filename, uint32 time) {
- if (!_isProfiling) {
- return;
- }
-
- AnsiString fileName = filename;
- fileName.toLowercase();
- _scriptTimes[fileName] += time;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::enableProfiling() {
- if (_isProfiling) {
- return;
- }
-
- // destroy old data, if any
- _scriptTimes.clear();
-
- _profilingStartTime = g_system->getMillis();
- _isProfiling = true;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::disableProfiling() {
- if (!_isProfiling) {
- return;
- }
-
- dumpStats();
- _isProfiling = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScEngine::dumpStats() {
- error("DumpStats not ported to ScummVM yet");
- /* uint32 totalTime = g_system->getMillis() - _profilingStartTime;
-
- typedef std::vector <std::pair<uint32, std::string> > TimeVector;
- TimeVector times;
-
- ScriptTimes::iterator it;
- for (it = _scriptTimes.begin(); it != _scriptTimes.end(); ++it) {
- times.push_back(std::pair<uint32, std::string> (it->_value, it->_key));
- }
- std::sort(times.begin(), times.end());
-
-
- TimeVector::reverse_iterator tit;
-
- _gameRef->LOG(0, "***** Script profiling information: *****");
- _gameRef->LOG(0, " %-40s %fs", "Total execution time", (float)totalTime / 1000);
-
- for (tit = times.rbegin(); tit != times.rend(); ++tit) {
- _gameRef->LOG(0, " %-40s %fs (%f%%)", tit->second.c_str(), (float)tit->first / 1000, (float)tit->first / (float)totalTime * 100);
- }*/
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_engine.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_ext_math.h"
+#include "engines/wintermute/base/base_engine.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/utils/utils.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(ScEngine, true)
+
+#define COMPILER_DLL "dcscomp.dll"
+//////////////////////////////////////////////////////////////////////////
+ScEngine::ScEngine(BaseGame *inGame) : BaseClass(inGame) {
+ _gameRef->LOG(0, "Initializing scripting engine...");
+
+ if (_compilerAvailable) {
+ _gameRef->LOG(0, " Script compiler bound successfuly");
+ } else {
+ _gameRef->LOG(0, " Script compiler is NOT available");
+ }
+
+ _globals = new ScValue(_gameRef);
+
+
+ // register 'Game' as global variable
+ if (!_globals->propExists("Game")) {
+ ScValue val(_gameRef);
+ val.setNative(_gameRef, true);
+ _globals->setProp("Game", &val);
+ }
+
+ // register 'Math' as global variable
+ if (!_globals->propExists("Math")) {
+ ScValue val(_gameRef);
+ val.setNative(_gameRef->_mathClass, true);
+ _globals->setProp("Math", &val);
+ }
+
+ // prepare script cache
+ for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
+ _cachedScripts[i] = NULL;
+ }
+
+ _currentScript = NULL;
+
+ _isProfiling = false;
+ _profilingStartTime = 0;
+
+ //EnableProfiling();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScEngine::~ScEngine() {
+ _gameRef->LOG(0, "Shutting down scripting engine");
+
+ disableProfiling();
+
+ cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::cleanup() {
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (!_scripts[i]->_thread && _scripts[i]->_owner) {
+ _scripts[i]->_owner->removeScript(_scripts[i]);
+ }
+ delete _scripts[i];
+ _scripts.remove_at(i);
+ i--;
+ }
+
+ _scripts.clear();
+
+ delete _globals;
+ _globals = NULL;
+
+ emptyScriptCache();
+
+ _currentScript = NULL; // ref only
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+byte *ScEngine::loadFile(void *data, char *filename, uint32 *size) {
+ return BaseFileManager::getEngineInstance()->readWholeFile(filename, size);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::closeFile(void *data, byte *buffer) {
+ delete[] buffer;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::parseElement(void *data, int line, int type, void *elementData) {
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScScript *ScEngine::runScript(const char *filename, BaseScriptHolder *owner) {
+ byte *compBuffer;
+ uint32 compSize;
+
+ // get script from cache
+ compBuffer = getCompiledScript(filename, &compSize);
+ if (!compBuffer) {
+ return NULL;
+ }
+
+ // add new script
+ ScScript *script = new ScScript(_gameRef, this);
+ bool ret = script->create(filename, compBuffer, compSize, owner);
+ if (DID_FAIL(ret)) {
+ _gameRef->LOG(ret, "Error running script '%s'...", filename);
+ delete script;
+ return NULL;
+ } else {
+ // publish the "self" pseudo-variable
+ ScValue val(_gameRef);
+ if (owner) {
+ val.setNative(owner, true);
+ } else {
+ val.setNULL();
+ }
+
+ script->_globals->setProp("self", &val);
+ script->_globals->setProp("this", &val);
+
+ _scripts.add(script);
+
+ return script;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+byte *ScEngine::getCompiledScript(const char *filename, uint32 *outSize, bool ignoreCache) {
+ // is script in cache?
+ if (!ignoreCache) {
+ for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
+ if (_cachedScripts[i] && scumm_stricmp(_cachedScripts[i]->_filename.c_str(), filename) == 0) {
+ _cachedScripts[i]->_timestamp = g_system->getMillis();
+ *outSize = _cachedScripts[i]->_size;
+ return _cachedScripts[i]->_buffer;
+ }
+ }
+ }
+
+ // nope, load it
+ byte *compBuffer;
+ uint32 compSize;
+
+ uint32 size;
+
+ byte *buffer = BaseEngine::instance().getFileManager()->readWholeFile(filename, &size);
+ if (!buffer) {
+ _gameRef->LOG(0, "ScEngine::GetCompiledScript - error opening script '%s'", filename);
+ return NULL;
+ }
+
+ // needs to be compiled?
+ if (FROM_LE_32(*(uint32 *)buffer) == SCRIPT_MAGIC) {
+ compBuffer = buffer;
+ compSize = size;
+ } else {
+ if (!_compilerAvailable) {
+ _gameRef->LOG(0, "ScEngine::GetCompiledScript - script '%s' needs to be compiled but compiler is not available", filename);
+ delete[] buffer;
+ return NULL;
+ }
+ // This code will never be called, since _compilerAvailable is const false.
+ // It's only here in the event someone would want to reinclude the compiler.
+ error("Script needs compilation, ScummVM does not contain a WME compiler");
+ }
+
+ byte *ret = NULL;
+
+ // add script to cache
+ CScCachedScript *cachedScript = new CScCachedScript(filename, compBuffer, compSize);
+ if (cachedScript) {
+ int index = 0;
+ uint32 minTime = g_system->getMillis();
+ for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
+ if (_cachedScripts[i] == NULL) {
+ index = i;
+ break;
+ } else if (_cachedScripts[i]->_timestamp <= minTime) {
+ minTime = _cachedScripts[i]->_timestamp;
+ index = i;
+ }
+ }
+
+ if (_cachedScripts[index] != NULL) {
+ delete _cachedScripts[index];
+ }
+ _cachedScripts[index] = cachedScript;
+
+ ret = cachedScript->_buffer;
+ *outSize = cachedScript->_size;
+ }
+
+
+ // cleanup
+ delete[] buffer;
+
+ return ret;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::tick() {
+ if (_scripts.size() == 0) {
+ return STATUS_OK;
+ }
+
+
+ // resolve waiting scripts
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+
+ switch (_scripts[i]->_state) {
+ case SCRIPT_WAITING: {
+ /*
+ bool obj_found=false;
+ for(int j=0; j<_gameRef->_regObjects.size(); j++)
+ {
+ if (_gameRef->_regObjects[j] == _scripts[i]->_waitObject)
+ {
+ if (_gameRef->_regObjects[j]->IsReady()) _scripts[i]->Run();
+ obj_found = true;
+ break;
+ }
+ }
+ if (!obj_found) _scripts[i]->finish(); // _waitObject no longer exists
+ */
+ if (_gameRef->validObject(_scripts[i]->_waitObject)) {
+ if (_scripts[i]->_waitObject->isReady()) {
+ _scripts[i]->run();
+ }
+ } else {
+ _scripts[i]->finish();
+ }
+ break;
+ }
+
+ case SCRIPT_SLEEPING: {
+ if (_scripts[i]->_waitFrozen) {
+ if (_scripts[i]->_waitTime <= g_system->getMillis()) {
+ _scripts[i]->run();
+ }
+ } else {
+ if (_scripts[i]->_waitTime <= _gameRef->_timer) {
+ _scripts[i]->run();
+ }
+ }
+ break;
+ }
+
+ case SCRIPT_WAITING_SCRIPT: {
+ if (!isValidScript(_scripts[i]->_waitScript) || _scripts[i]->_waitScript->_state == SCRIPT_ERROR) {
+ // fake return value
+ _scripts[i]->_stack->pushNULL();
+ _scripts[i]->_waitScript = NULL;
+ _scripts[i]->run();
+ } else {
+ if (_scripts[i]->_waitScript->_state == SCRIPT_THREAD_FINISHED) {
+ // copy return value
+ _scripts[i]->_stack->push(_scripts[i]->_waitScript->_stack->pop());
+ _scripts[i]->run();
+ _scripts[i]->_waitScript->finish();
+ _scripts[i]->_waitScript = NULL;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ } // switch
+ } // for each script
+
+
+ // execute scripts
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+
+ // skip paused scripts
+ if (_scripts[i]->_state == SCRIPT_PAUSED) {
+ continue;
+ }
+
+ // time sliced script
+ if (_scripts[i]->_timeSlice > 0) {
+ uint32 startTime = g_system->getMillis();
+ while (_scripts[i]->_state == SCRIPT_RUNNING && g_system->getMillis() - startTime < _scripts[i]->_timeSlice) {
+ _currentScript = _scripts[i];
+ _scripts[i]->executeInstruction();
+ }
+ if (_isProfiling && _scripts[i]->_filename) {
+ addScriptTime(_scripts[i]->_filename, g_system->getMillis() - startTime);
+ }
+ }
+
+ // normal script
+ else {
+ uint32 startTime = 0;
+ bool isProfiling = _isProfiling;
+ if (isProfiling) {
+ startTime = g_system->getMillis();
+ }
+
+ while (_scripts[i]->_state == SCRIPT_RUNNING) {
+ _currentScript = _scripts[i];
+ _scripts[i]->executeInstruction();
+ }
+ if (isProfiling && _scripts[i]->_filename) {
+ addScriptTime(_scripts[i]->_filename, g_system->getMillis() - startTime);
+ }
+ }
+ _currentScript = NULL;
+ }
+
+ removeFinishedScripts();
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::tickUnbreakable() {
+ // execute unbreakable scripts
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (!_scripts[i]->_unbreakable) {
+ continue;
+ }
+
+ while (_scripts[i]->_state == SCRIPT_RUNNING) {
+ _currentScript = _scripts[i];
+ _scripts[i]->executeInstruction();
+ }
+ _scripts[i]->finish();
+ _currentScript = NULL;
+ }
+ removeFinishedScripts();
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::removeFinishedScripts() {
+ // remove finished scripts
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i]->_state == SCRIPT_FINISHED || _scripts[i]->_state == SCRIPT_ERROR) {
+ if (!_scripts[i]->_thread && _scripts[i]->_owner) {
+ _scripts[i]->_owner->removeScript(_scripts[i]);
+ }
+
+ delete _scripts[i];
+ _scripts.remove_at(i);
+ i--;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int ScEngine::getNumScripts(int *running, int *waiting, int *persistent) {
+ int numRunning = 0, numWaiting = 0, numPersistent = 0, numTotal = 0;
+
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i]->_state == SCRIPT_FINISHED) {
+ continue;
+ }
+ switch (_scripts[i]->_state) {
+ case SCRIPT_RUNNING:
+ case SCRIPT_SLEEPING:
+ case SCRIPT_PAUSED:
+ numRunning++;
+ break;
+ case SCRIPT_WAITING:
+ numWaiting++;
+ break;
+ case SCRIPT_PERSISTENT:
+ numPersistent++;
+ break;
+ default:
+ warning("ScEngine::GetNumScripts - unhandled enum");
+ break;
+ }
+ numTotal++;
+ }
+ if (running) {
+ *running = numRunning;
+ }
+ if (waiting) {
+ *waiting = numWaiting;
+ }
+ if (persistent) {
+ *persistent = numPersistent;
+ }
+
+ return numTotal;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::emptyScriptCache() {
+ for (int i = 0; i < MAX_CACHED_SCRIPTS; i++) {
+ if (_cachedScripts[i]) {
+ delete _cachedScripts[i];
+ _cachedScripts[i] = NULL;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::resetObject(BaseObject *Object) {
+ // terminate all scripts waiting for this object
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i]->_state == SCRIPT_WAITING && _scripts[i]->_waitObject == Object) {
+ if (!_gameRef->_compatKillMethodThreads) {
+ resetScript(_scripts[i]);
+ }
+
+ bool isThread = _scripts[i]->_methodThread || _scripts[i]->_thread;
+ _scripts[i]->finish(!isThread); // 1.9b1 - top-level script kills its threads as well
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::resetScript(ScScript *script) {
+ // terminate all scripts waiting for this script
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i]->_state == SCRIPT_WAITING_SCRIPT && _scripts[i]->_waitScript == script) {
+ _scripts[i]->finish();
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::persist(BasePersistenceManager *persistMgr) {
+ if (!persistMgr->getIsSaving()) {
+ cleanup();
+ }
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+ persistMgr->transfer(TMEMBER(_currentScript));
+ persistMgr->transfer(TMEMBER(_globals));
+ _scripts.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::editorCleanup() {
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i]->_owner == NULL && (_scripts[i]->_state == SCRIPT_FINISHED || _scripts[i]->_state == SCRIPT_ERROR)) {
+ delete _scripts[i];
+ _scripts.remove_at(i);
+ i--;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::pauseAll() {
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i] != _currentScript) {
+ _scripts[i]->pause();
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::resumeAll() {
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ _scripts[i]->resume();
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::isValidScript(ScScript *script) {
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ if (_scripts[i] == script) {
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScEngine::clearGlobals(bool includingNatives) {
+ _globals->CleanProps(includingNatives);
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::addScriptTime(const char *filename, uint32 time) {
+ if (!_isProfiling) {
+ return;
+ }
+
+ AnsiString fileName = filename;
+ fileName.toLowercase();
+ _scriptTimes[fileName] += time;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::enableProfiling() {
+ if (_isProfiling) {
+ return;
+ }
+
+ // destroy old data, if any
+ _scriptTimes.clear();
+
+ _profilingStartTime = g_system->getMillis();
+ _isProfiling = true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::disableProfiling() {
+ if (!_isProfiling) {
+ return;
+ }
+
+ dumpStats();
+ _isProfiling = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScEngine::dumpStats() {
+ error("DumpStats not ported to ScummVM yet");
+ /* uint32 totalTime = g_system->getMillis() - _profilingStartTime;
+
+ typedef std::vector <std::pair<uint32, std::string> > TimeVector;
+ TimeVector times;
+
+ ScriptTimes::iterator it;
+ for (it = _scriptTimes.begin(); it != _scriptTimes.end(); ++it) {
+ times.push_back(std::pair<uint32, std::string> (it->_value, it->_key));
+ }
+ std::sort(times.begin(), times.end());
+
+
+ TimeVector::reverse_iterator tit;
+
+ _gameRef->LOG(0, "***** Script profiling information: *****");
+ _gameRef->LOG(0, " %-40s %fs", "Total execution time", (float)totalTime / 1000);
+
+ for (tit = times.rbegin(); tit != times.rend(); ++tit) {
+ _gameRef->LOG(0, " %-40s %fs (%f%%)", tit->second.c_str(), (float)tit->first / 1000, (float)tit->first / (float)totalTime * 100);
+ }*/
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_engine.h b/engines/wintermute/base/scriptables/script_engine.h
index f526353368..1a023326eb 100644
--- a/engines/wintermute/base/scriptables/script_engine.h
+++ b/engines/wintermute/base/scriptables/script_engine.h
@@ -1,135 +1,135 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SCENGINE_H
-#define WINTERMUTE_SCENGINE_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/coll_templ.h"
-#include "engines/wintermute/base/base.h"
-
-namespace Wintermute {
-
-#define MAX_CACHED_SCRIPTS 20
-class ScScript;
-class ScValue;
-class BaseObject;
-class BaseScriptHolder;
-class ScEngine : public BaseClass {
-public:
- class CScCachedScript {
- public:
- CScCachedScript(const char *filename, byte *buffer, uint32 size) {
- _timestamp = g_system->getMillis();
- _buffer = new byte[size];
- if (_buffer) {
- memcpy(_buffer, buffer, size);
- }
- _size = size;
- _filename = filename;
- };
-
- ~CScCachedScript() {
- if (_buffer) {
- delete[] _buffer;
- }
- };
-
- uint32 _timestamp;
- byte *_buffer;
- uint32 _size;
- Common::String _filename;
- };
-
- class CScBreakpoint {
- public:
- CScBreakpoint(const char *filename) {
- _filename = filename;
- }
-
- ~CScBreakpoint() {
- _lines.clear();
- }
-
- Common::String _filename;
- BaseArray<int> _lines;
- };
-
-public:
- bool clearGlobals(bool includingNatives = false);
- bool tickUnbreakable();
- bool removeFinishedScripts();
- bool isValidScript(ScScript *script);
-
- ScScript *_currentScript;
- bool resumeAll();
- bool pauseAll();
- void editorCleanup();
- bool resetObject(BaseObject *Object);
- bool resetScript(ScScript *script);
- bool emptyScriptCache();
- byte *getCompiledScript(const char *filename, uint32 *outSize, bool ignoreCache = false);
- DECLARE_PERSISTENT(ScEngine, BaseClass)
- bool cleanup();
- int getNumScripts(int *running = NULL, int *waiting = NULL, int *persistent = NULL);
- bool tick();
- ScValue *_globals;
- ScScript *runScript(const char *filename, BaseScriptHolder *owner = NULL);
- static const bool _compilerAvailable = false;
-
- ScEngine(BaseGame *inGame);
- virtual ~ScEngine();
- static byte *loadFile(void *data, char *filename, uint32 *size);
- static void closeFile(void *data, byte *buffer);
- static void parseElement(void *data, int line, int type, void *elementData);
-
- BaseArray<ScScript *> _scripts;
-
- void enableProfiling();
- void disableProfiling();
- bool getIsProfiling() {
- return _isProfiling;
- }
-
- void addScriptTime(const char *filename, uint32 Time);
- void dumpStats();
-
-private:
-
- CScCachedScript *_cachedScripts[MAX_CACHED_SCRIPTS];
- bool _isProfiling;
- uint32 _profilingStartTime;
-
- typedef Common::HashMap<Common::String, uint32> ScriptTimes;
- ScriptTimes _scriptTimes;
-
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SCENGINE_H
+#define WINTERMUTE_SCENGINE_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/base/base.h"
+
+namespace Wintermute {
+
+#define MAX_CACHED_SCRIPTS 20
+class ScScript;
+class ScValue;
+class BaseObject;
+class BaseScriptHolder;
+class ScEngine : public BaseClass {
+public:
+ class CScCachedScript {
+ public:
+ CScCachedScript(const char *filename, byte *buffer, uint32 size) {
+ _timestamp = g_system->getMillis();
+ _buffer = new byte[size];
+ if (_buffer) {
+ memcpy(_buffer, buffer, size);
+ }
+ _size = size;
+ _filename = filename;
+ };
+
+ ~CScCachedScript() {
+ if (_buffer) {
+ delete[] _buffer;
+ }
+ };
+
+ uint32 _timestamp;
+ byte *_buffer;
+ uint32 _size;
+ Common::String _filename;
+ };
+
+ class CScBreakpoint {
+ public:
+ CScBreakpoint(const char *filename) {
+ _filename = filename;
+ }
+
+ ~CScBreakpoint() {
+ _lines.clear();
+ }
+
+ Common::String _filename;
+ BaseArray<int> _lines;
+ };
+
+public:
+ bool clearGlobals(bool includingNatives = false);
+ bool tickUnbreakable();
+ bool removeFinishedScripts();
+ bool isValidScript(ScScript *script);
+
+ ScScript *_currentScript;
+ bool resumeAll();
+ bool pauseAll();
+ void editorCleanup();
+ bool resetObject(BaseObject *Object);
+ bool resetScript(ScScript *script);
+ bool emptyScriptCache();
+ byte *getCompiledScript(const char *filename, uint32 *outSize, bool ignoreCache = false);
+ DECLARE_PERSISTENT(ScEngine, BaseClass)
+ bool cleanup();
+ int getNumScripts(int *running = NULL, int *waiting = NULL, int *persistent = NULL);
+ bool tick();
+ ScValue *_globals;
+ ScScript *runScript(const char *filename, BaseScriptHolder *owner = NULL);
+ static const bool _compilerAvailable = false;
+
+ ScEngine(BaseGame *inGame);
+ virtual ~ScEngine();
+ static byte *loadFile(void *data, char *filename, uint32 *size);
+ static void closeFile(void *data, byte *buffer);
+ static void parseElement(void *data, int line, int type, void *elementData);
+
+ BaseArray<ScScript *> _scripts;
+
+ void enableProfiling();
+ void disableProfiling();
+ bool getIsProfiling() {
+ return _isProfiling;
+ }
+
+ void addScriptTime(const char *filename, uint32 Time);
+ void dumpStats();
+
+private:
+
+ CScCachedScript *_cachedScripts[MAX_CACHED_SCRIPTS];
+ bool _isProfiling;
+ uint32 _profilingStartTime;
+
+ typedef Common::HashMap<Common::String, uint32> ScriptTimes;
+ ScriptTimes _scriptTimes;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_array.cpp b/engines/wintermute/base/scriptables/script_ext_array.cpp
index c8d4f64ae9..5ed07f0da6 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -1,252 +1,252 @@
-/* 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(SXArray, false)
-
-BaseScriptable *makeSXArray(BaseGame *inGame, ScStack *stack) {
- return new SXArray(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXArray::SXArray(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
- _length = 0;
- _values = new ScValue(_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());
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXArray::SXArray(BaseGame *inGame) : BaseScriptable(inGame) {
- _length = 0;
- _values = new ScValue(_gameRef);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXArray::~SXArray() {
- delete _values;
- _values = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *SXArray::scToString() {
- char dummy[32768];
- strcpy(dummy, "");
- char propName[20];
- for (int i = 0; i < _length; i++) {
- sprintf(propName, "%d", i);
- ScValue *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, ",");
- }
- }
- _strRep = dummy;
- return _strRep.c_str();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXArray::scCallMethod(ScScript *script, ScStack *stack, ScStack *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;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXArray::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 SXArray::scSetProperty(const char *name, ScValue *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 SXArray::persist(BasePersistenceManager *persistMgr) {
- BaseScriptable::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_length));
- persistMgr->transfer(TMEMBER(_values));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXArray::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 SXArray::push(ScValue *val) {
- char paramName[20];
- _length++;
- sprintf(paramName, "%d", _length - 1);
- _values->setProp(paramName, val, true);
- return STATUS_OK;
-}
-
-} // end of namespace Wintermute
+/* 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(SXArray, false)
+
+BaseScriptable *makeSXArray(BaseGame *inGame, ScStack *stack) {
+ return new SXArray(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXArray::SXArray(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
+ _length = 0;
+ _values = new ScValue(_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());
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXArray::SXArray(BaseGame *inGame) : BaseScriptable(inGame) {
+ _length = 0;
+ _values = new ScValue(_gameRef);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXArray::~SXArray() {
+ delete _values;
+ _values = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *SXArray::scToString() {
+ char dummy[32768];
+ strcpy(dummy, "");
+ char propName[20];
+ for (int i = 0; i < _length; i++) {
+ sprintf(propName, "%d", i);
+ ScValue *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, ",");
+ }
+ }
+ _strRep = dummy;
+ return _strRep.c_str();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXArray::scCallMethod(ScScript *script, ScStack *stack, ScStack *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;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXArray::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 SXArray::scSetProperty(const char *name, ScValue *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 SXArray::persist(BasePersistenceManager *persistMgr) {
+ BaseScriptable::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_length));
+ persistMgr->transfer(TMEMBER(_values));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXArray::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 SXArray::push(ScValue *val) {
+ char paramName[20];
+ _length++;
+ sprintf(paramName, "%d", _length - 1);
+ _values->setProp(paramName, val, true);
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_array.h b/engines/wintermute/base/scriptables/script_ext_array.h
index 614f829950..d9805ef94f 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.h
+++ b/engines/wintermute/base/scriptables/script_ext_array.h
@@ -1,56 +1,56 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXARRAY_H
-#define WINTERMUTE_SXARRAY_H
-
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-class SXArray : public BaseScriptable {
-public:
- bool push(ScValue *val);
- bool validNumber(const char *origStr, char *outStr);
- DECLARE_PERSISTENT(SXArray, BaseScriptable)
- SXArray(BaseGame *inGame, ScStack *stack);
- SXArray(BaseGame *inGame);
- virtual ~SXArray();
- ScValue *scGetProperty(const char *name);
- bool scSetProperty(const char *name, ScValue *value);
- bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- const char *scToString();
-private:
- int _length;
- ScValue *_values;
- Common::String _strRep;
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXARRAY_H
+#define WINTERMUTE_SXARRAY_H
+
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+class SXArray : public BaseScriptable {
+public:
+ bool push(ScValue *val);
+ bool validNumber(const char *origStr, char *outStr);
+ DECLARE_PERSISTENT(SXArray, BaseScriptable)
+ SXArray(BaseGame *inGame, ScStack *stack);
+ SXArray(BaseGame *inGame);
+ virtual ~SXArray();
+ ScValue *scGetProperty(const char *name);
+ bool scSetProperty(const char *name, ScValue *value);
+ bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ const char *scToString();
+private:
+ int _length;
+ ScValue *_values;
+ Common::String _strRep;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_date.cpp b/engines/wintermute/base/scriptables/script_ext_date.cpp
index 7726015081..11eead3b9c 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_date.cpp
@@ -1,293 +1,293 @@
-/* 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/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script_ext_date.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(SXDate, false)
-
-BaseScriptable *makeSXDate(BaseGame *inGame, ScStack *stack) {
- return new SXDate(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXDate::SXDate(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
- stack->correctParams(6);
-
- memset(&_tm, 0, sizeof(_tm));
-
- ScValue *valYear = stack->pop();
- _tm.tm_year = valYear->getInt() - 1900;
- _tm.tm_mon = stack->pop()->getInt() - 1;
- _tm.tm_mday = stack->pop()->getInt();
- _tm.tm_hour = stack->pop()->getInt();
- _tm.tm_min = stack->pop()->getInt();
- _tm.tm_sec = stack->pop()->getInt();
-
- if (valYear->isNULL()) {
- g_system->getTimeAndDate(_tm);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXDate::~SXDate() {
-
-}
-
-//////////////////////////////////////////////////////////////////////////
-const char *SXDate::scToString() {
- // TODO: Make this more stringy, and less ISO 8601-like
- _strRep.format("%04d-%02d-%02d - %02d:%02d:%02d", _tm.tm_year, _tm.tm_mon, _tm.tm_mday, _tm.tm_hour, _tm.tm_min, _tm.tm_sec);
- return _strRep.c_str();
- //return asctime(&_tm);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXDate::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // GetYear
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "GetYear") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_year + 1900);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetMonth
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetMonth") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_mon + 1);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetDate
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetDate") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_mday);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetHours
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetHours") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_hour);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetMinutes
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetMinutes") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_min);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetSeconds
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetSeconds") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_sec);
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // GetWeekday
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetWeekday") == 0) {
- stack->correctParams(0);
- stack->pushInt(_tm.tm_wday);
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // SetYear
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetYear") == 0) {
- stack->correctParams(1);
- _tm.tm_year = stack->pop()->getInt() - 1900;
- stack->pushNULL();
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // SetMonth
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetMonth") == 0) {
- stack->correctParams(1);
- _tm.tm_mon = stack->pop()->getInt() - 1;
- stack->pushNULL();
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // SetDate
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetDate") == 0) {
- stack->correctParams(1);
- _tm.tm_mday = stack->pop()->getInt();
- stack->pushNULL();
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // SetHours
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetHours") == 0) {
- stack->correctParams(1);
- _tm.tm_hour = stack->pop()->getInt();
- stack->pushNULL();
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // SetMinutes
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetMinutes") == 0) {
- stack->correctParams(1);
- _tm.tm_min = stack->pop()->getInt();
- stack->pushNULL();
- return STATUS_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // SetSeconds
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetSeconds") == 0) {
- stack->correctParams(1);
- _tm.tm_sec = stack->pop()->getInt();
- stack->pushNULL();
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // SetCurrentTime
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetCurrentTime") == 0) {
- stack->correctParams(0);
- g_system->getTimeAndDate(_tm);
- stack->pushNULL();
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXDate::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("date");
- return _scValue;
- } else {
- return _scValue;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXDate::scSetProperty(const char *name, ScValue *value) {
- /*
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Name")==0){
- setName(value->getString());
- return STATUS_OK;
- }
-
- else*/ return STATUS_FAILED;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXDate::persist(BasePersistenceManager *persistMgr) {
-
- BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_tm.tm_year));
- persistMgr->transfer(TMEMBER(_tm.tm_mon));
- persistMgr->transfer(TMEMBER(_tm.tm_mday));
- persistMgr->transfer(TMEMBER(_tm.tm_hour));
- persistMgr->transfer(TMEMBER(_tm.tm_min));
- persistMgr->transfer(TMEMBER(_tm.tm_sec));
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-int SXDate::scCompare(BaseScriptable *Value) {
- TimeDate time1 = _tm;
- TimeDate time2 = ((SXDate *)Value)->_tm;
-
- if (time1.tm_year < time2.tm_year) {
- return -1;
- } else if (time1.tm_year == time2.tm_year) {
- if (time1.tm_mon < time2.tm_mon) {
- return -1;
- } else if (time1.tm_mon == time2.tm_mon) {
- if (time1.tm_mday < time2.tm_mday) {
- return -1;
- } else if (time1.tm_mday == time2.tm_mday) {
- if (time1.tm_hour < time2.tm_hour) {
- return -1;
- } else if (time1.tm_hour == time2.tm_hour) {
- if (time1.tm_min < time2.tm_min) {
- return -1;
- } else if (time1.tm_min == time2.tm_min) {
- if (time1.tm_sec < time2.tm_sec) {
- return -1;
- } else if (time1.tm_sec == time2.tm_sec) {
- return 0; // Equal
- } else {
- return 1; // Sec
- }
- } else {
- return 1; // Minute
- }
- } else {
- return 1; // Hour
- }
- } else {
- return 1; // Day
- }
- } else {
- return 1; // Month
- }
- } else {
- return 1; // Year
- }
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script_ext_date.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(SXDate, false)
+
+BaseScriptable *makeSXDate(BaseGame *inGame, ScStack *stack) {
+ return new SXDate(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXDate::SXDate(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
+ stack->correctParams(6);
+
+ memset(&_tm, 0, sizeof(_tm));
+
+ ScValue *valYear = stack->pop();
+ _tm.tm_year = valYear->getInt() - 1900;
+ _tm.tm_mon = stack->pop()->getInt() - 1;
+ _tm.tm_mday = stack->pop()->getInt();
+ _tm.tm_hour = stack->pop()->getInt();
+ _tm.tm_min = stack->pop()->getInt();
+ _tm.tm_sec = stack->pop()->getInt();
+
+ if (valYear->isNULL()) {
+ g_system->getTimeAndDate(_tm);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXDate::~SXDate() {
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char *SXDate::scToString() {
+ // TODO: Make this more stringy, and less ISO 8601-like
+ _strRep.format("%04d-%02d-%02d - %02d:%02d:%02d", _tm.tm_year, _tm.tm_mon, _tm.tm_mday, _tm.tm_hour, _tm.tm_min, _tm.tm_sec);
+ return _strRep.c_str();
+ //return asctime(&_tm);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXDate::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // GetYear
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "GetYear") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_year + 1900);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetMonth
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetMonth") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_mon + 1);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetDate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetDate") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_mday);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetHours
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetHours") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_hour);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetMinutes
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetMinutes") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_min);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetSeconds
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetSeconds") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_sec);
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetWeekday
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetWeekday") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_tm.tm_wday);
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetYear
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetYear") == 0) {
+ stack->correctParams(1);
+ _tm.tm_year = stack->pop()->getInt() - 1900;
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SetMonth
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetMonth") == 0) {
+ stack->correctParams(1);
+ _tm.tm_mon = stack->pop()->getInt() - 1;
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SetDate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetDate") == 0) {
+ stack->correctParams(1);
+ _tm.tm_mday = stack->pop()->getInt();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SetHours
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetHours") == 0) {
+ stack->correctParams(1);
+ _tm.tm_hour = stack->pop()->getInt();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SetMinutes
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetMinutes") == 0) {
+ stack->correctParams(1);
+ _tm.tm_min = stack->pop()->getInt();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SetSeconds
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetSeconds") == 0) {
+ stack->correctParams(1);
+ _tm.tm_sec = stack->pop()->getInt();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetCurrentTime
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetCurrentTime") == 0) {
+ stack->correctParams(0);
+ g_system->getTimeAndDate(_tm);
+ stack->pushNULL();
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXDate::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("date");
+ return _scValue;
+ } else {
+ return _scValue;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXDate::scSetProperty(const char *name, ScValue *value) {
+ /*
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Name")==0){
+ setName(value->getString());
+ return STATUS_OK;
+ }
+
+ else*/ return STATUS_FAILED;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXDate::persist(BasePersistenceManager *persistMgr) {
+
+ BaseScriptable::persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_tm.tm_year));
+ persistMgr->transfer(TMEMBER(_tm.tm_mon));
+ persistMgr->transfer(TMEMBER(_tm.tm_mday));
+ persistMgr->transfer(TMEMBER(_tm.tm_hour));
+ persistMgr->transfer(TMEMBER(_tm.tm_min));
+ persistMgr->transfer(TMEMBER(_tm.tm_sec));
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int SXDate::scCompare(BaseScriptable *Value) {
+ TimeDate time1 = _tm;
+ TimeDate time2 = ((SXDate *)Value)->_tm;
+
+ if (time1.tm_year < time2.tm_year) {
+ return -1;
+ } else if (time1.tm_year == time2.tm_year) {
+ if (time1.tm_mon < time2.tm_mon) {
+ return -1;
+ } else if (time1.tm_mon == time2.tm_mon) {
+ if (time1.tm_mday < time2.tm_mday) {
+ return -1;
+ } else if (time1.tm_mday == time2.tm_mday) {
+ if (time1.tm_hour < time2.tm_hour) {
+ return -1;
+ } else if (time1.tm_hour == time2.tm_hour) {
+ if (time1.tm_min < time2.tm_min) {
+ return -1;
+ } else if (time1.tm_min == time2.tm_min) {
+ if (time1.tm_sec < time2.tm_sec) {
+ return -1;
+ } else if (time1.tm_sec == time2.tm_sec) {
+ return 0; // Equal
+ } else {
+ return 1; // Sec
+ }
+ } else {
+ return 1; // Minute
+ }
+ } else {
+ return 1; // Hour
+ }
+ } else {
+ return 1; // Day
+ }
+ } else {
+ return 1; // Month
+ }
+ } else {
+ return 1; // Year
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_date.h b/engines/wintermute/base/scriptables/script_ext_date.h
index 7cdf57e689..f6f04dd7e6 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.h
+++ b/engines/wintermute/base/scriptables/script_ext_date.h
@@ -1,54 +1,54 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXDATE_H
-#define WINTERMUTE_SXDATE_H
-
-#include "common/system.h"
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-class SXDate : public BaseScriptable {
-public:
- int scCompare(BaseScriptable *Value);
- DECLARE_PERSISTENT(SXDate, BaseScriptable)
- SXDate(BaseGame *inGame, ScStack *Stack);
- virtual ~SXDate();
- ScValue *scGetProperty(const char *name);
- bool scSetProperty(const char *name, ScValue *value);
- bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- const char *scToString();
-private:
- TimeDate _tm;
- Common::String _strRep;
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXDATE_H
+#define WINTERMUTE_SXDATE_H
+
+#include "common/system.h"
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+class SXDate : public BaseScriptable {
+public:
+ int scCompare(BaseScriptable *Value);
+ DECLARE_PERSISTENT(SXDate, BaseScriptable)
+ SXDate(BaseGame *inGame, ScStack *Stack);
+ virtual ~SXDate();
+ ScValue *scGetProperty(const char *name);
+ bool scSetProperty(const char *name, ScValue *value);
+ bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ const char *scToString();
+private:
+ TimeDate _tm;
+ Common::String _strRep;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_file.cpp b/engines/wintermute/base/scriptables/script_ext_file.cpp
index 53d551119d..ab574d464b 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_file.cpp
@@ -1,829 +1,829 @@
-/* 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/system/sys_class_registry.h"
-#include "engines/wintermute/system/sys_class.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/file/base_file.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/base/scriptables/script_ext_file.h"
-
-// Note: This code is completely untested, as I have yet to find a game that uses SXFile.
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(SXFile, false)
-
-BaseScriptable *makeSXFile(BaseGame *inGame, ScStack *stack) {
- return new SXFile(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXFile::SXFile(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- _filename = NULL;
- if (!val->isNULL()) {
- BaseUtils::setString(&_filename, val->getString());
- }
-
- _readFile = NULL;
- _writeFile = NULL;
-
- _mode = 0;
- _textMode = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXFile::~SXFile() {
- cleanup();
-}
-
-//////////////////////////////////////////////////////////////////////////
-void SXFile::cleanup() {
- delete[] _filename;
- _filename = NULL;
- close();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void SXFile::close() {
- if (_readFile) {
- BaseFileManager::getEngineInstance()->closeFile(_readFile);
- _readFile = NULL;
- }
- if (_writeFile) {
- _writeFile->finalize();
- delete _writeFile;
- _writeFile = NULL;
- }
- _mode = 0;
- _textMode = false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-const char *SXFile::scToString() {
- if (_filename) {
- return _filename;
- } else {
- return "[file object]";
- }
-}
-
-#define FILE_BUFFER_SIZE 32768
-//////////////////////////////////////////////////////////////////////////
-bool SXFile::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // SetFilename
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetFilename") == 0) {
- stack->correctParams(1);
- const char *filename = stack->pop()->getString();
- cleanup();
- BaseUtils::setString(&_filename, filename);
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // OpenAsText / OpenAsBinary
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "OpenAsText") == 0 || strcmp(name, "OpenAsBinary") == 0) {
- stack->correctParams(1);
- close();
- _mode = stack->pop()->getInt(1);
- if (_mode < 1 || _mode > 3) {
- script->runtimeError("File.%s: invalid access mode. Setting read mode.", name);
- _mode = 1;
- }
- if (_mode == 1) {
- _readFile = BaseFileManager::getEngineInstance()->openFile(_filename);
- if (!_readFile) {
- //script->runtimeError("File.%s: Error opening file '%s' for reading.", Name, _filename);
- close();
- } else {
- _textMode = strcmp(name, "OpenAsText") == 0;
- }
- } else {
- if (strcmp(name, "OpenAsText") == 0) {
- if (_mode == 2) {
- _writeFile = openForWrite(_filename, false);
- } else {
- _writeFile = openForAppend(_filename, false);
- }
- } else {
- if (_mode == 2) {
- _writeFile = openForWrite(_filename, true);
- } else {
- _writeFile = openForAppend(_filename, true);
- }
- }
-
- if (!_writeFile) {
- //script->runtimeError("File.%s: Error opening file '%s' for writing.", Name, _filename);
- close();
- } else {
- _textMode = strcmp(name, "OpenAsText") == 0;
- }
- }
-
- if (_readFile || _writeFile) {
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Close
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Close") == 0) {
- stack->correctParams(0);
- close();
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetPosition
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetPosition") == 0) {
- stack->correctParams(1);
- if (_mode == 0) {
- script->runtimeError("File.%s: File is not open", name);
- stack->pushBool(false);
- } else {
- int pos = stack->pop()->getInt();
- stack->pushBool(setPos(pos));
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Delete
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Delete") == 0) {
- stack->correctParams(0);
- close();
- error("SXFile-Method: \"Delete\" not supported");
- //stack->pushBool(BasePlatform::deleteFile(_filename) != false);
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Copy
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Copy") == 0) {
- stack->correctParams(2);
- /* const char *dest = */ stack->pop()->getString();
- /* bool overwrite = */ stack->pop()->getBool(true);
-
- close();
- error("SXFile-Method: Copy not supported");
- //stack->pushBool(BasePlatform::copyFile(_filename, Dest, !Overwrite) != false);
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadLine
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadLine") == 0) {
- stack->correctParams(0);
- if (!_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open in text mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- uint32 bufSize = FILE_BUFFER_SIZE;
- byte *buf = (byte *)malloc(bufSize);
- uint32 counter = 0;
- byte b;
- bool foundNewLine = false;
- bool ret = STATUS_FAILED;
- do {
- ret = _readFile->read(&b, 1);
- if (ret != 1) {
- break;
- }
-
- if (counter > bufSize) {
- buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
- bufSize += FILE_BUFFER_SIZE;
- }
- if (b == '\n') {
- buf[counter] = '\0';
- foundNewLine = true;
- break;
- } else if (b == 0x0D) {
- continue;
- } else {
- buf[counter] = b;
- counter++;
- }
- } while (DID_SUCCEED(ret));
-
- if (counter > bufSize) {
- buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
- bufSize += FILE_BUFFER_SIZE;
- }
- buf[counter] = '\0';
-
- if (!foundNewLine && counter == 0) {
- stack->pushNULL();
- } else {
- stack->pushString((char *)buf);
- }
-
- free(buf);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadText
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadText") == 0) {
- stack->correctParams(1);
- int textLen = stack->pop()->getInt();
-
- if (!_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open in text mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- uint32 bufSize = FILE_BUFFER_SIZE;
- byte *buf = (byte *)malloc(bufSize);
- uint32 counter = 0;
- byte b;
-
- bool ret = STATUS_FAILED;
- while (counter < (uint32)textLen) {
- ret = _readFile->read(&b, 1);
- if (ret != 1) {
- break;
- }
-
- if (counter > bufSize) {
- buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
- bufSize += FILE_BUFFER_SIZE;
- }
- if (b == 0x0D) {
- continue;
- } else {
- buf[counter] = b;
- counter++;
- }
- }
-
- if (counter > bufSize) {
- buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
- bufSize += FILE_BUFFER_SIZE;
- }
- buf[counter] = '\0';
-
- if (textLen > 0 && counter == 0) {
- stack->pushNULL();
- } else {
- stack->pushString((char *)buf);
- }
-
- free(buf);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteLine / WriteText
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteLine") == 0 || strcmp(name, "WriteText") == 0) {
- stack->correctParams(1);
- const char *line = stack->pop()->getString();
- if (!_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in text mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- Common::String writeLine;
- if (strcmp(name, "WriteLine") == 0) {
- writeLine = Common::String::format("%s\n", line);
- } else {
- writeLine = Common::String::format("%s", line);
- }
- _writeFile->writeString(writeLine);
- _writeFile->writeByte(0);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- // ReadBool
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadBool") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- bool val;
- if (_readFile->read(&val, sizeof(bool)) == sizeof(bool)) {
- stack->pushBool(val);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadByte
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadByte") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- byte val = _readFile->readByte();
- if (!_readFile->err()) {
- stack->pushInt(val);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadShort
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadShort") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- int16 val = _readFile->readSint16LE();
- if (!_readFile->err()) {
- stack->pushInt(65536 + val);
- } else {
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadInt / ReadLong
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadInt") == 0 || strcmp(name, "ReadLong") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- int32 val = _readFile->readSint32LE();
- if (!_readFile->err()) {
- stack->pushInt(val);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadFloat
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadFloat") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- float val;
- (*(uint32 *)&val) = _readFile->readUint32LE();
- if (!_readFile->err()) {
- stack->pushFloat(val);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadDouble
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadDouble") == 0) { // TODO: Solve reading a 8 byte double.
- error("SXFile::ReadDouble - Not endian safe yet");
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- double val;
- if (_readFile->read(&val, sizeof(double)) == sizeof(double)) {
- stack->pushFloat(val);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ReadString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ReadString") == 0) {
- stack->correctParams(0);
- if (_textMode || !_readFile) {
- script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- uint32 size = _readFile->readUint32LE();
- if (!_readFile->err()) {
- byte *str = new byte[size + 1];
- if (str) {
- if (_readFile->read(str, size) == size) {
- str[size] = '\0';
- stack->pushString((char *)str);
- }
- delete[] str;
- } else {
- stack->pushNULL();
- }
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteBool
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteBool") == 0) {
- stack->correctParams(1);
- bool val = stack->pop()->getBool();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- _writeFile->writeByte(val);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteByte
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteByte") == 0) {
- stack->correctParams(1);
- byte val = stack->pop()->getInt();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- _writeFile->writeByte(val);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteShort
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteShort") == 0) {
- stack->correctParams(1);
- int16 val = stack->pop()->getInt();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- _writeFile->writeSint16LE(val);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteInt / WriteLong
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteInt") == 0 || strcmp(name, "WriteLong") == 0) {
- stack->correctParams(1);
- int32 val = stack->pop()->getInt();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- _writeFile->writeSint32LE(val);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteFloat
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteFloat") == 0) {
- stack->correctParams(1);
- float val = stack->pop()->getFloat();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- uint32 *ptr = (uint32 *)&val;
- _writeFile->writeUint32LE(*ptr);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteDouble
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteDouble") == 0) {
- error("SXFile::WriteDouble - Not endian safe yet");
- stack->correctParams(1);
- /* double val = */ stack->pop()->getFloat();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
- //fwrite(&val, sizeof(val), 1, (FILE *)_writeFile);
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WriteString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WriteString") == 0) {
- stack->correctParams(1);
- const char *val = stack->pop()->getString();
-
- if (_textMode || !_writeFile) {
- script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- uint32 size = strlen(val);
- _writeFile->writeUint32LE(size);
- _writeFile->writeString(val);
-
- stack->pushBool(true);
-
- return STATUS_OK;
- } else {
- return BaseScriptable::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXFile::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("file");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Filename (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Filename") == 0) {
- _scValue->setString(_filename);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Position (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Position") == 0) {
- _scValue->setInt(getPos());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Length (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Length") == 0) {
- _scValue->setInt(getLength());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TextMode (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TextMode") == 0) {
- _scValue->setBool(_textMode);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AccessMode (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AccessMode") == 0) {
- _scValue->setInt(_mode);
- return _scValue;
- } else {
- return BaseScriptable::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXFile::scSetProperty(const char *name, ScValue *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;
- }
- else*/ return BaseScriptable::scSetProperty(name, value);
-}
-
-//////////////////////////////////////////////////////////////////////////
-uint32 SXFile::getPos() {
- if (_mode == 1 && _readFile) {
- return _readFile->pos();
- } else if ((_mode == 2 || _mode == 3) && _writeFile) {
- error("SXFile - getPos for WriteFile not supported");
- return 0;
-// return ftell((FILE *)_writeFile);
- } else {
- return 0;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool SXFile::setPos(uint32 pos, int whence) {
- if (_mode == 1 && _readFile) {
- return _readFile->seek(pos, whence);
- } else if ((_mode == 2 || _mode == 3) && _writeFile) {
- error("SXFile - seeking in WriteFile not supported");
- return false;
-// return fseek((FILE *)_writeFile, pos, (int)origin) == 0;
- } else {
- return false;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-uint32 SXFile::getLength() {
- if (_mode == 1 && _readFile) {
- return _readFile->size();
- } else if ((_mode == 2 || _mode == 3) && _writeFile) {
- error("SXFile - reading length for WriteFile not supported");
- return 0;
- /*
- uint32 currentPos = ftell((FILE *)_writeFile);
- fseek((FILE *)_writeFile, 0, SEEK_END);
- int ret = ftell((FILE *)_writeFile);
- fseek((FILE *)_writeFile, CurrentPos, SEEK_SET);
- return Ret;*/
- } else {
- return 0;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool SXFile::persist(BasePersistenceManager *persistMgr) {
-
- BaseScriptable::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_mode));
- persistMgr->transfer(TMEMBER(_textMode));
-
- uint32 pos = 0;
- if (persistMgr->getIsSaving()) {
- pos = getPos();
- persistMgr->transfer(TMEMBER(pos));
- } else {
- persistMgr->transfer(TMEMBER(pos));
-
- // try to re-open file if needed
- _writeFile = NULL;
- _readFile = NULL;
-
- if (_mode != 0) {
- // open for reading
- if (_mode == 1) {
- _readFile = BaseFileManager::getEngineInstance()->openFile(_filename);
- if (!_readFile) {
- close();
- }
- }
- // open for writing / appending
- else {
- if (_textMode) {
- if (_mode == 2) {
- _writeFile = openForWrite(_filename, false);
- } else {
- _writeFile = openForAppend(_filename, false);
- }
- } else {
- if (_mode == 2) {
- _writeFile = openForWrite(_filename, true);
- } else {
- _writeFile = openForAppend(_filename, true);
- }
- }
- if (_writeFile) {
- close();
- }
- }
- setPos(pos);
- }
- }
-
- return STATUS_OK;
-}
-
-// Should replace fopen(..., "wb+") and fopen(..., "w+")
-Common::WriteStream *SXFile::openForWrite(const Common::String &filename, bool binary) {
- error("SXFile::openForWrite - WriteFiles not supported");
-}
-
-// Should replace fopen(..., "ab+") and fopen(..., "a+")
-Common::WriteStream *SXFile::openForAppend(const Common::String &filename, bool binary) {
- error("SXFile::openForAppend - WriteFiles not supported");
-}
-
-} // end of namespace Wintermute
+/* 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/system/sys_class_registry.h"
+#include "engines/wintermute/system/sys_class.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/file/base_file.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/base/scriptables/script_ext_file.h"
+
+// Note: This code is completely untested, as I have yet to find a game that uses SXFile.
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(SXFile, false)
+
+BaseScriptable *makeSXFile(BaseGame *inGame, ScStack *stack) {
+ return new SXFile(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXFile::SXFile(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ _filename = NULL;
+ if (!val->isNULL()) {
+ BaseUtils::setString(&_filename, val->getString());
+ }
+
+ _readFile = NULL;
+ _writeFile = NULL;
+
+ _mode = 0;
+ _textMode = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXFile::~SXFile() {
+ cleanup();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void SXFile::cleanup() {
+ delete[] _filename;
+ _filename = NULL;
+ close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void SXFile::close() {
+ if (_readFile) {
+ BaseFileManager::getEngineInstance()->closeFile(_readFile);
+ _readFile = NULL;
+ }
+ if (_writeFile) {
+ _writeFile->finalize();
+ delete _writeFile;
+ _writeFile = NULL;
+ }
+ _mode = 0;
+ _textMode = false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char *SXFile::scToString() {
+ if (_filename) {
+ return _filename;
+ } else {
+ return "[file object]";
+ }
+}
+
+#define FILE_BUFFER_SIZE 32768
+//////////////////////////////////////////////////////////////////////////
+bool SXFile::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // SetFilename
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetFilename") == 0) {
+ stack->correctParams(1);
+ const char *filename = stack->pop()->getString();
+ cleanup();
+ BaseUtils::setString(&_filename, filename);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OpenAsText / OpenAsBinary
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "OpenAsText") == 0 || strcmp(name, "OpenAsBinary") == 0) {
+ stack->correctParams(1);
+ close();
+ _mode = stack->pop()->getInt(1);
+ if (_mode < 1 || _mode > 3) {
+ script->runtimeError("File.%s: invalid access mode. Setting read mode.", name);
+ _mode = 1;
+ }
+ if (_mode == 1) {
+ _readFile = BaseFileManager::getEngineInstance()->openFile(_filename);
+ if (!_readFile) {
+ //script->runtimeError("File.%s: Error opening file '%s' for reading.", Name, _filename);
+ close();
+ } else {
+ _textMode = strcmp(name, "OpenAsText") == 0;
+ }
+ } else {
+ if (strcmp(name, "OpenAsText") == 0) {
+ if (_mode == 2) {
+ _writeFile = openForWrite(_filename, false);
+ } else {
+ _writeFile = openForAppend(_filename, false);
+ }
+ } else {
+ if (_mode == 2) {
+ _writeFile = openForWrite(_filename, true);
+ } else {
+ _writeFile = openForAppend(_filename, true);
+ }
+ }
+
+ if (!_writeFile) {
+ //script->runtimeError("File.%s: Error opening file '%s' for writing.", Name, _filename);
+ close();
+ } else {
+ _textMode = strcmp(name, "OpenAsText") == 0;
+ }
+ }
+
+ if (_readFile || _writeFile) {
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Close
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Close") == 0) {
+ stack->correctParams(0);
+ close();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetPosition") == 0) {
+ stack->correctParams(1);
+ if (_mode == 0) {
+ script->runtimeError("File.%s: File is not open", name);
+ stack->pushBool(false);
+ } else {
+ int pos = stack->pop()->getInt();
+ stack->pushBool(setPos(pos));
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Delete
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Delete") == 0) {
+ stack->correctParams(0);
+ close();
+ error("SXFile-Method: \"Delete\" not supported");
+ //stack->pushBool(BasePlatform::deleteFile(_filename) != false);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Copy
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Copy") == 0) {
+ stack->correctParams(2);
+ /* const char *dest = */ stack->pop()->getString();
+ /* bool overwrite = */ stack->pop()->getBool(true);
+
+ close();
+ error("SXFile-Method: Copy not supported");
+ //stack->pushBool(BasePlatform::copyFile(_filename, Dest, !Overwrite) != false);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadLine
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadLine") == 0) {
+ stack->correctParams(0);
+ if (!_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open in text mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ uint32 bufSize = FILE_BUFFER_SIZE;
+ byte *buf = (byte *)malloc(bufSize);
+ uint32 counter = 0;
+ byte b;
+ bool foundNewLine = false;
+ bool ret = STATUS_FAILED;
+ do {
+ ret = _readFile->read(&b, 1);
+ if (ret != 1) {
+ break;
+ }
+
+ if (counter > bufSize) {
+ buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
+ bufSize += FILE_BUFFER_SIZE;
+ }
+ if (b == '\n') {
+ buf[counter] = '\0';
+ foundNewLine = true;
+ break;
+ } else if (b == 0x0D) {
+ continue;
+ } else {
+ buf[counter] = b;
+ counter++;
+ }
+ } while (DID_SUCCEED(ret));
+
+ if (counter > bufSize) {
+ buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
+ bufSize += FILE_BUFFER_SIZE;
+ }
+ buf[counter] = '\0';
+
+ if (!foundNewLine && counter == 0) {
+ stack->pushNULL();
+ } else {
+ stack->pushString((char *)buf);
+ }
+
+ free(buf);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadText
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadText") == 0) {
+ stack->correctParams(1);
+ int textLen = stack->pop()->getInt();
+
+ if (!_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open in text mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ uint32 bufSize = FILE_BUFFER_SIZE;
+ byte *buf = (byte *)malloc(bufSize);
+ uint32 counter = 0;
+ byte b;
+
+ bool ret = STATUS_FAILED;
+ while (counter < (uint32)textLen) {
+ ret = _readFile->read(&b, 1);
+ if (ret != 1) {
+ break;
+ }
+
+ if (counter > bufSize) {
+ buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
+ bufSize += FILE_BUFFER_SIZE;
+ }
+ if (b == 0x0D) {
+ continue;
+ } else {
+ buf[counter] = b;
+ counter++;
+ }
+ }
+
+ if (counter > bufSize) {
+ buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
+ bufSize += FILE_BUFFER_SIZE;
+ }
+ buf[counter] = '\0';
+
+ if (textLen > 0 && counter == 0) {
+ stack->pushNULL();
+ } else {
+ stack->pushString((char *)buf);
+ }
+
+ free(buf);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteLine / WriteText
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteLine") == 0 || strcmp(name, "WriteText") == 0) {
+ stack->correctParams(1);
+ const char *line = stack->pop()->getString();
+ if (!_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in text mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ Common::String writeLine;
+ if (strcmp(name, "WriteLine") == 0) {
+ writeLine = Common::String::format("%s\n", line);
+ } else {
+ writeLine = Common::String::format("%s", line);
+ }
+ _writeFile->writeString(writeLine);
+ _writeFile->writeByte(0);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////
+ // ReadBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadBool") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ bool val;
+ if (_readFile->read(&val, sizeof(bool)) == sizeof(bool)) {
+ stack->pushBool(val);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadByte") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ byte val = _readFile->readByte();
+ if (!_readFile->err()) {
+ stack->pushInt(val);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadShort") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ int16 val = _readFile->readSint16LE();
+ if (!_readFile->err()) {
+ stack->pushInt(65536 + val);
+ } else {
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadInt / ReadLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadInt") == 0 || strcmp(name, "ReadLong") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ int32 val = _readFile->readSint32LE();
+ if (!_readFile->err()) {
+ stack->pushInt(val);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadFloat") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ float val;
+ (*(uint32 *)&val) = _readFile->readUint32LE();
+ if (!_readFile->err()) {
+ stack->pushFloat(val);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadDouble") == 0) { // TODO: Solve reading a 8 byte double.
+ error("SXFile::ReadDouble - Not endian safe yet");
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ double val;
+ if (_readFile->read(&val, sizeof(double)) == sizeof(double)) {
+ stack->pushFloat(val);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ReadString") == 0) {
+ stack->correctParams(0);
+ if (_textMode || !_readFile) {
+ script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ uint32 size = _readFile->readUint32LE();
+ if (!_readFile->err()) {
+ byte *str = new byte[size + 1];
+ if (str) {
+ if (_readFile->read(str, size) == size) {
+ str[size] = '\0';
+ stack->pushString((char *)str);
+ }
+ delete[] str;
+ } else {
+ stack->pushNULL();
+ }
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteBool") == 0) {
+ stack->correctParams(1);
+ bool val = stack->pop()->getBool();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ _writeFile->writeByte(val);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteByte") == 0) {
+ stack->correctParams(1);
+ byte val = stack->pop()->getInt();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ _writeFile->writeByte(val);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteShort") == 0) {
+ stack->correctParams(1);
+ int16 val = stack->pop()->getInt();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ _writeFile->writeSint16LE(val);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteInt / WriteLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteInt") == 0 || strcmp(name, "WriteLong") == 0) {
+ stack->correctParams(1);
+ int32 val = stack->pop()->getInt();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ _writeFile->writeSint32LE(val);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteFloat") == 0) {
+ stack->correctParams(1);
+ float val = stack->pop()->getFloat();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ uint32 *ptr = (uint32 *)&val;
+ _writeFile->writeUint32LE(*ptr);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteDouble") == 0) {
+ error("SXFile::WriteDouble - Not endian safe yet");
+ stack->correctParams(1);
+ /* double val = */ stack->pop()->getFloat();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+ //fwrite(&val, sizeof(val), 1, (FILE *)_writeFile);
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WriteString") == 0) {
+ stack->correctParams(1);
+ const char *val = stack->pop()->getString();
+
+ if (_textMode || !_writeFile) {
+ script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ uint32 size = strlen(val);
+ _writeFile->writeUint32LE(size);
+ _writeFile->writeString(val);
+
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ } else {
+ return BaseScriptable::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXFile::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("file");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Filename (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Filename") == 0) {
+ _scValue->setString(_filename);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Position (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Position") == 0) {
+ _scValue->setInt(getPos());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Length (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Length") == 0) {
+ _scValue->setInt(getLength());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TextMode") == 0) {
+ _scValue->setBool(_textMode);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccessMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AccessMode") == 0) {
+ _scValue->setInt(_mode);
+ return _scValue;
+ } else {
+ return BaseScriptable::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXFile::scSetProperty(const char *name, ScValue *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;
+ }
+ else*/ return BaseScriptable::scSetProperty(name, value);
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 SXFile::getPos() {
+ if (_mode == 1 && _readFile) {
+ return _readFile->pos();
+ } else if ((_mode == 2 || _mode == 3) && _writeFile) {
+ error("SXFile - getPos for WriteFile not supported");
+ return 0;
+// return ftell((FILE *)_writeFile);
+ } else {
+ return 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool SXFile::setPos(uint32 pos, int whence) {
+ if (_mode == 1 && _readFile) {
+ return _readFile->seek(pos, whence);
+ } else if ((_mode == 2 || _mode == 3) && _writeFile) {
+ error("SXFile - seeking in WriteFile not supported");
+ return false;
+// return fseek((FILE *)_writeFile, pos, (int)origin) == 0;
+ } else {
+ return false;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 SXFile::getLength() {
+ if (_mode == 1 && _readFile) {
+ return _readFile->size();
+ } else if ((_mode == 2 || _mode == 3) && _writeFile) {
+ error("SXFile - reading length for WriteFile not supported");
+ return 0;
+ /*
+ uint32 currentPos = ftell((FILE *)_writeFile);
+ fseek((FILE *)_writeFile, 0, SEEK_END);
+ int ret = ftell((FILE *)_writeFile);
+ fseek((FILE *)_writeFile, CurrentPos, SEEK_SET);
+ return Ret;*/
+ } else {
+ return 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool SXFile::persist(BasePersistenceManager *persistMgr) {
+
+ BaseScriptable::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_filename));
+ persistMgr->transfer(TMEMBER(_mode));
+ persistMgr->transfer(TMEMBER(_textMode));
+
+ uint32 pos = 0;
+ if (persistMgr->getIsSaving()) {
+ pos = getPos();
+ persistMgr->transfer(TMEMBER(pos));
+ } else {
+ persistMgr->transfer(TMEMBER(pos));
+
+ // try to re-open file if needed
+ _writeFile = NULL;
+ _readFile = NULL;
+
+ if (_mode != 0) {
+ // open for reading
+ if (_mode == 1) {
+ _readFile = BaseFileManager::getEngineInstance()->openFile(_filename);
+ if (!_readFile) {
+ close();
+ }
+ }
+ // open for writing / appending
+ else {
+ if (_textMode) {
+ if (_mode == 2) {
+ _writeFile = openForWrite(_filename, false);
+ } else {
+ _writeFile = openForAppend(_filename, false);
+ }
+ } else {
+ if (_mode == 2) {
+ _writeFile = openForWrite(_filename, true);
+ } else {
+ _writeFile = openForAppend(_filename, true);
+ }
+ }
+ if (_writeFile) {
+ close();
+ }
+ }
+ setPos(pos);
+ }
+ }
+
+ return STATUS_OK;
+}
+
+// Should replace fopen(..., "wb+") and fopen(..., "w+")
+Common::WriteStream *SXFile::openForWrite(const Common::String &filename, bool binary) {
+ error("SXFile::openForWrite - WriteFiles not supported");
+}
+
+// Should replace fopen(..., "ab+") and fopen(..., "a+")
+Common::WriteStream *SXFile::openForAppend(const Common::String &filename, bool binary) {
+ error("SXFile::openForAppend - WriteFiles not supported");
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_file.h b/engines/wintermute/base/scriptables/script_ext_file.h
index 389974a48e..b91a53e695 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.h
+++ b/engines/wintermute/base/scriptables/script_ext_file.h
@@ -1,66 +1,66 @@
-/* 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
- */
-
-#ifndef WINTERMUTES_SXFILE_H
-#define WINTERMUTES_SXFILE_H
-
-
-#include "engines/wintermute/base/base_scriptable.h"
-#include "common/stream.h"
-
-namespace Wintermute {
-
-class BaseFile;
-
-class SXFile : public BaseScriptable {
-public:
- DECLARE_PERSISTENT(SXFile, BaseScriptable)
- ScValue *scGetProperty(const char *name);
- bool scSetProperty(const char *name, ScValue *value);
- bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- const char *scToString();
- SXFile(BaseGame *inGame, ScStack *Stack);
- virtual ~SXFile();
-private:
- Common::SeekableReadStream *_readFile;
- Common::WriteStream *_writeFile;
- int _mode; // 0..none, 1..read, 2..write, 3..append
- bool _textMode;
- void close();
- void cleanup();
- uint32 getPos();
- uint32 getLength();
- bool setPos(uint32 pos, int whence = SEEK_SET);
- char *_filename;
- Common::WriteStream *openForWrite(const Common::String &filename, bool binary);
- Common::WriteStream *openForAppend(const Common::String &filename, bool binary);
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTES_SXFILE_H
+#define WINTERMUTES_SXFILE_H
+
+
+#include "engines/wintermute/base/base_scriptable.h"
+#include "common/stream.h"
+
+namespace Wintermute {
+
+class BaseFile;
+
+class SXFile : public BaseScriptable {
+public:
+ DECLARE_PERSISTENT(SXFile, BaseScriptable)
+ ScValue *scGetProperty(const char *name);
+ bool scSetProperty(const char *name, ScValue *value);
+ bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ const char *scToString();
+ SXFile(BaseGame *inGame, ScStack *Stack);
+ virtual ~SXFile();
+private:
+ Common::SeekableReadStream *_readFile;
+ Common::WriteStream *_writeFile;
+ int _mode; // 0..none, 1..read, 2..write, 3..append
+ bool _textMode;
+ void close();
+ void cleanup();
+ uint32 getPos();
+ uint32 getLength();
+ bool setPos(uint32 pos, int whence = SEEK_SET);
+ char *_filename;
+ Common::WriteStream *openForWrite(const Common::String &filename, bool binary);
+ Common::WriteStream *openForAppend(const Common::String &filename, bool binary);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_math.cpp b/engines/wintermute/base/scriptables/script_ext_math.cpp
index f7d0ba20b9..598b80cff3 100644
--- a/engines/wintermute/base/scriptables/script_ext_math.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_math.cpp
@@ -1,295 +1,295 @@
-/* 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/base/scriptables/script_ext_math.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/persistent.h"
-#include "common/math.h"
-#include <math.h>
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-
-IMPLEMENT_PERSISTENT(SXMath, true)
-
-BaseScriptable *makeSXMath(BaseGame *inGame) {
- return new SXMath(inGame);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXMath::SXMath(BaseGame *inGame) : BaseScriptable(inGame) {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXMath::~SXMath() {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMath::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // Abs
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Abs") == 0) {
- stack->correctParams(1);
- stack->pushFloat(fabs(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Acos
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Acos") == 0) {
- stack->correctParams(1);
- stack->pushFloat(acos(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Asin
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Asin") == 0) {
- stack->correctParams(1);
- stack->pushFloat(asin(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Atan
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Atan") == 0) {
- stack->correctParams(1);
- stack->pushFloat(atan(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Atan2
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Atan2") == 0) {
- stack->correctParams(2);
- double y = stack->pop()->getFloat();
- double x = stack->pop()->getFloat();
- stack->pushFloat(atan2(y, x));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Ceil
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Ceil") == 0) {
- stack->correctParams(1);
- stack->pushFloat(ceil(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Cos
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Cos") == 0) {
- stack->correctParams(1);
- stack->pushFloat(cos(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Cosh
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Cosh") == 0) {
- stack->correctParams(1);
- stack->pushFloat(cosh(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Exp
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Exp") == 0) {
- stack->correctParams(1);
- stack->pushFloat(exp(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Floor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Floor") == 0) {
- stack->correctParams(1);
- stack->pushFloat(floor(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Log
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Log") == 0) {
- stack->correctParams(1);
- stack->pushFloat(log(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Log10
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Log10") == 0) {
- stack->correctParams(1);
- stack->pushFloat(log10(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Pow
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Pow") == 0) {
- stack->correctParams(2);
- double x = stack->pop()->getFloat();
- double y = stack->pop()->getFloat();
-
- stack->pushFloat(pow(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Sin
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Sin") == 0) {
- stack->correctParams(1);
- stack->pushFloat(sin(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Sinh
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Sinh") == 0) {
- stack->correctParams(1);
- stack->pushFloat(sinh(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Tan
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Tan") == 0) {
- stack->correctParams(1);
- stack->pushFloat(tan(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Tanh
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Tanh") == 0) {
- stack->correctParams(1);
- stack->pushFloat(tanh(degreeToRadian(stack->pop()->getFloat())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Sqrt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Sqrt") == 0) {
- stack->correctParams(1);
- stack->pushFloat(sqrt(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DegToRad
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DegToRad") == 0) {
- stack->correctParams(1);
- stack->pushFloat(degreeToRadian(stack->pop()->getFloat()));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // RadToDeg
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "RadToDeg") == 0) {
- stack->correctParams(1);
- stack->pushFloat(radianToDegree(stack->pop()->getFloat()));
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXMath::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("math");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PI
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PI") == 0) {
- _scValue->setFloat(M_PI);
- return _scValue;
- } else {
- return _scValue;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-double SXMath::degreeToRadian(double value) {
- return value * (M_PI / 180.0f);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-double SXMath::radianToDegree(double value) {
- return value * (180.0f / M_PI);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMath::persist(BasePersistenceManager *persistMgr) {
-
- BaseScriptable::persist(persistMgr);
- return STATUS_OK;
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_ext_math.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/persistent.h"
+#include "common/math.h"
+#include <math.h>
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+IMPLEMENT_PERSISTENT(SXMath, true)
+
+BaseScriptable *makeSXMath(BaseGame *inGame) {
+ return new SXMath(inGame);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXMath::SXMath(BaseGame *inGame) : BaseScriptable(inGame) {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXMath::~SXMath() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMath::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // Abs
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Abs") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(fabs(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Acos
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Acos") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(acos(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Asin
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Asin") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(asin(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Atan
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Atan") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(atan(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Atan2
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Atan2") == 0) {
+ stack->correctParams(2);
+ double y = stack->pop()->getFloat();
+ double x = stack->pop()->getFloat();
+ stack->pushFloat(atan2(y, x));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ceil
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Ceil") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(ceil(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Cos
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Cos") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(cos(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Cosh
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Cosh") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(cosh(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Exp
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Exp") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(exp(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Floor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Floor") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(floor(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Log
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Log") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(log(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Log10
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Log10") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(log10(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Pow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Pow") == 0) {
+ stack->correctParams(2);
+ double x = stack->pop()->getFloat();
+ double y = stack->pop()->getFloat();
+
+ stack->pushFloat(pow(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sin
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Sin") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(sin(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sinh
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Sinh") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(sinh(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Tan
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Tan") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(tan(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Tanh
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Tanh") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(tanh(degreeToRadian(stack->pop()->getFloat())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sqrt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Sqrt") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(sqrt(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DegToRad
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DegToRad") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(degreeToRadian(stack->pop()->getFloat()));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RadToDeg
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RadToDeg") == 0) {
+ stack->correctParams(1);
+ stack->pushFloat(radianToDegree(stack->pop()->getFloat()));
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXMath::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("math");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PI
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PI") == 0) {
+ _scValue->setFloat(M_PI);
+ return _scValue;
+ } else {
+ return _scValue;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+double SXMath::degreeToRadian(double value) {
+ return value * (M_PI / 180.0f);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+double SXMath::radianToDegree(double value) {
+ return value * (180.0f / M_PI);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMath::persist(BasePersistenceManager *persistMgr) {
+
+ BaseScriptable::persist(persistMgr);
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_math.h b/engines/wintermute/base/scriptables/script_ext_math.h
index b195c0785d..f86d59fe7b 100644
--- a/engines/wintermute/base/scriptables/script_ext_math.h
+++ b/engines/wintermute/base/scriptables/script_ext_math.h
@@ -1,53 +1,53 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXMATH_H
-#define WINTERMUTE_SXMATH_H
-
-
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-class SXMath : public BaseScriptable {
-public:
- DECLARE_PERSISTENT(SXMath, BaseScriptable)
- SXMath(BaseGame *inGame);
- virtual ~SXMath();
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
-
-private:
- double degreeToRadian(double value);
- double radianToDegree(double value);
-
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXMATH_H
+#define WINTERMUTE_SXMATH_H
+
+
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+class SXMath : public BaseScriptable {
+public:
+ DECLARE_PERSISTENT(SXMath, BaseScriptable)
+ SXMath(BaseGame *inGame);
+ virtual ~SXMath();
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+
+private:
+ double degreeToRadian(double value);
+ double radianToDegree(double value);
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
index eef1931d8b..5ed9bd5313 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
@@ -1,529 +1,529 @@
-/* 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/base/base_scriptable.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script_ext_mem_buffer.h"
-#include "common/file.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(SXMemBuffer, false)
-
-BaseScriptable *makeSXMemBuffer(BaseGame *inGame, ScStack *stack) {
- return new SXMemBuffer(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXMemBuffer::SXMemBuffer(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
- stack->correctParams(1);
- _buffer = NULL;
- _size = 0;
-
- int newSize = stack->pop()->getInt();
- resize(MAX(0, newSize));
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXMemBuffer::SXMemBuffer(BaseGame *inGame, void *buffer) : BaseScriptable(inGame) {
- _size = 0;
- _buffer = buffer;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXMemBuffer::~SXMemBuffer() {
- cleanup();
-}
-
-//////////////////////////////////////////////////////////////////////////
-void *SXMemBuffer::scToMemBuffer() {
- return _buffer;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void SXMemBuffer::cleanup() {
- if (_size) {
- free(_buffer);
- }
- _buffer = NULL;
- _size = 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMemBuffer::resize(int newSize) {
- int oldSize = _size;
-
- if (_size == 0) {
- _buffer = malloc(newSize);
- if (_buffer) {
- _size = newSize;
- }
- } else {
- void *newBuf = realloc(_buffer, newSize);
- if (!newBuf) {
- if (newSize == 0) {
- _buffer = newBuf;
- _size = newSize;
- } else {
- return STATUS_FAILED;
- }
- } else {
- _buffer = newBuf;
- _size = newSize;
- }
- }
-
- if (_buffer && _size > oldSize) {
- memset((byte *)_buffer + oldSize, 0, _size - oldSize);
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMemBuffer::checkBounds(ScScript *script, int start, int length) {
- if (_buffer == NULL) {
- script->runtimeError("Cannot use Set/Get methods on an uninitialized memory buffer");
- return false;
- }
- if (_size == 0) {
- return true;
- }
-
- if (start < 0 || length == 0 || start + length > _size) {
- script->runtimeError("Set/Get method call is out of bounds");
- return false;
- } else {
- return true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-const char *SXMemBuffer::scToString() {
- return "[membuffer object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMemBuffer::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // SetSize
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetSize") == 0) {
- stack->correctParams(1);
- int newSize = stack->pop()->getInt();
- newSize = MAX(0, newSize);
- if (DID_SUCCEED(resize(newSize))) {
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetBool
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetBool") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(bool))) {
- stack->pushNULL();
- } else {
- stack->pushBool(*(bool *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetByte
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetByte") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(byte))) {
- stack->pushNULL();
- } else {
- stack->pushInt(*(byte *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetShort
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetShort") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(short))) {
- stack->pushNULL();
- } else {
- stack->pushInt(65536 + * (short *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetInt / GetLong
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetInt") == 0 || strcmp(name, "GetLong") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(int))) {
- stack->pushNULL();
- } else {
- stack->pushInt(*(int *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetFloat
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetFloat") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(float))) {
- stack->pushNULL();
- } else {
- stack->pushFloat(*(float *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetDouble
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetDouble") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(double))) {
- stack->pushNULL();
- } else {
- stack->pushFloat(*(double *)((byte *)_buffer + start));
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetString") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- int length = stack->pop()->getInt();
-
- // find end of string
- if (length == 0 && start >= 0 && start < _size) {
- for (int i = start; i < _size; i++) {
- if (((char *)_buffer)[i] == '\0') {
- length = i - start;
- break;
- }
- }
- }
-
- if (!checkBounds(script, start, length)) {
- stack->pushNULL();
- } else {
- char *str = new char[length + 1];
- Common::strlcpy(str, (const char *)_buffer + start, length + 1);
- stack->pushString(str);
- delete[] str;
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetPointer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetPointer") == 0) {
- stack->correctParams(1);
- int start = stack->pop()->getInt();
- if (!checkBounds(script, start, sizeof(void *))) {
- stack->pushNULL();
- } else {
- void *pointer = *(void **)((byte *)_buffer + start);
- SXMemBuffer *buf = new SXMemBuffer(_gameRef, pointer);
- stack->pushNative(buf, false);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetBool
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetBool") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- bool val = stack->pop()->getBool();
-
- if (!checkBounds(script, start, sizeof(bool))) {
- stack->pushBool(false);
- } else {
- *(bool *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetByte
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetByte") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- byte val = (byte)stack->pop()->getInt();
-
- if (!checkBounds(script, start, sizeof(byte))) {
- stack->pushBool(false);
- } else {
- *(byte *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetShort
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetShort") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- short val = (short)stack->pop()->getInt();
-
- if (!checkBounds(script, start, sizeof(short))) {
- stack->pushBool(false);
- } else {
- *(short *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetInt / SetLong
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetInt") == 0 || strcmp(name, "SetLong") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- int val = stack->pop()->getInt();
-
- if (!checkBounds(script, start, sizeof(int))) {
- stack->pushBool(false);
- } else {
- *(int *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetFloat
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetFloat") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- float val = (float)stack->pop()->getFloat();
-
- if (!checkBounds(script, start, sizeof(float))) {
- stack->pushBool(false);
- } else {
- *(float *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetDouble
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetDouble") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- double val = stack->pop()->getFloat();
-
- if (!checkBounds(script, start, sizeof(double))) {
- stack->pushBool(false);
- } else {
- *(double *)((byte *)_buffer + start) = val;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetString") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- const char *val = stack->pop()->getString();
-
- if (!checkBounds(script, start, strlen(val) + 1)) {
- stack->pushBool(false);
- } else {
- memcpy((byte *)_buffer + start, val, strlen(val) + 1);
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetPointer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetPointer") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- /* ScValue *val = */ stack->pop();
-
- if (!checkBounds(script, start, sizeof(void *))) {
- stack->pushBool(false);
- } else {
- /*
- int pointer = (int)Val->getMemBuffer();
- memcpy((byte *)_buffer+Start, &Pointer, sizeof(void*));
- stack->pushBool(true);
- */
- // TODO fix
- stack->pushBool(false);
-
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DEBUG_Dump
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DEBUG_Dump") == 0) {
- stack->correctParams(0);
- if (_buffer && _size) {
- warning("SXMemBuffer::ScCallMethod - DEBUG_Dump");
- Common::DumpFile f;
- f.open("buffer.bin");
- f.write(_buffer, _size);
- f.close();
- }
- stack->pushNULL();
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXMemBuffer::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("membuffer");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Size (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Size") == 0) {
- _scValue->setInt(_size);
- return _scValue;
- } else {
- return BaseScriptable::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMemBuffer::scSetProperty(const char *name, ScValue *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;
- }
- else*/ return BaseScriptable::scSetProperty(name, value);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXMemBuffer::persist(BasePersistenceManager *persistMgr) {
-
- BaseScriptable::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_size));
-
- if (persistMgr->getIsSaving()) {
- if (_size > 0) {
- persistMgr->putBytes((byte *)_buffer, _size);
- }
- } else {
- if (_size > 0) {
- _buffer = malloc(_size);
- persistMgr->getBytes((byte *)_buffer, _size);
- } else {
- _buffer = NULL;
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int SXMemBuffer::scCompare(BaseScriptable *val) {
- if (_buffer == val->scToMemBuffer()) {
- return 0;
- } else {
- return 1;
- }
-}
-
-} // end of namespace Wintermute
+/* 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/base/base_scriptable.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script_ext_mem_buffer.h"
+#include "common/file.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(SXMemBuffer, false)
+
+BaseScriptable *makeSXMemBuffer(BaseGame *inGame, ScStack *stack) {
+ return new SXMemBuffer(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXMemBuffer::SXMemBuffer(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
+ stack->correctParams(1);
+ _buffer = NULL;
+ _size = 0;
+
+ int newSize = stack->pop()->getInt();
+ resize(MAX(0, newSize));
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXMemBuffer::SXMemBuffer(BaseGame *inGame, void *buffer) : BaseScriptable(inGame) {
+ _size = 0;
+ _buffer = buffer;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXMemBuffer::~SXMemBuffer() {
+ cleanup();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void *SXMemBuffer::scToMemBuffer() {
+ return _buffer;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void SXMemBuffer::cleanup() {
+ if (_size) {
+ free(_buffer);
+ }
+ _buffer = NULL;
+ _size = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMemBuffer::resize(int newSize) {
+ int oldSize = _size;
+
+ if (_size == 0) {
+ _buffer = malloc(newSize);
+ if (_buffer) {
+ _size = newSize;
+ }
+ } else {
+ void *newBuf = realloc(_buffer, newSize);
+ if (!newBuf) {
+ if (newSize == 0) {
+ _buffer = newBuf;
+ _size = newSize;
+ } else {
+ return STATUS_FAILED;
+ }
+ } else {
+ _buffer = newBuf;
+ _size = newSize;
+ }
+ }
+
+ if (_buffer && _size > oldSize) {
+ memset((byte *)_buffer + oldSize, 0, _size - oldSize);
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMemBuffer::checkBounds(ScScript *script, int start, int length) {
+ if (_buffer == NULL) {
+ script->runtimeError("Cannot use Set/Get methods on an uninitialized memory buffer");
+ return false;
+ }
+ if (_size == 0) {
+ return true;
+ }
+
+ if (start < 0 || length == 0 || start + length > _size) {
+ script->runtimeError("Set/Get method call is out of bounds");
+ return false;
+ } else {
+ return true;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char *SXMemBuffer::scToString() {
+ return "[membuffer object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMemBuffer::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // SetSize
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetSize") == 0) {
+ stack->correctParams(1);
+ int newSize = stack->pop()->getInt();
+ newSize = MAX(0, newSize);
+ if (DID_SUCCEED(resize(newSize))) {
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetBool") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(bool))) {
+ stack->pushNULL();
+ } else {
+ stack->pushBool(*(bool *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetByte") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(byte))) {
+ stack->pushNULL();
+ } else {
+ stack->pushInt(*(byte *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetShort") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(short))) {
+ stack->pushNULL();
+ } else {
+ stack->pushInt(65536 + * (short *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetInt / GetLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetInt") == 0 || strcmp(name, "GetLong") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(int))) {
+ stack->pushNULL();
+ } else {
+ stack->pushInt(*(int *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetFloat") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(float))) {
+ stack->pushNULL();
+ } else {
+ stack->pushFloat(*(float *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetDouble") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(double))) {
+ stack->pushNULL();
+ } else {
+ stack->pushFloat(*(double *)((byte *)_buffer + start));
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetString") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ int length = stack->pop()->getInt();
+
+ // find end of string
+ if (length == 0 && start >= 0 && start < _size) {
+ for (int i = start; i < _size; i++) {
+ if (((char *)_buffer)[i] == '\0') {
+ length = i - start;
+ break;
+ }
+ }
+ }
+
+ if (!checkBounds(script, start, length)) {
+ stack->pushNULL();
+ } else {
+ char *str = new char[length + 1];
+ Common::strlcpy(str, (const char *)_buffer + start, length + 1);
+ stack->pushString(str);
+ delete[] str;
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetPointer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetPointer") == 0) {
+ stack->correctParams(1);
+ int start = stack->pop()->getInt();
+ if (!checkBounds(script, start, sizeof(void *))) {
+ stack->pushNULL();
+ } else {
+ void *pointer = *(void **)((byte *)_buffer + start);
+ SXMemBuffer *buf = new SXMemBuffer(_gameRef, pointer);
+ stack->pushNative(buf, false);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetBool") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ bool val = stack->pop()->getBool();
+
+ if (!checkBounds(script, start, sizeof(bool))) {
+ stack->pushBool(false);
+ } else {
+ *(bool *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetByte") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ byte val = (byte)stack->pop()->getInt();
+
+ if (!checkBounds(script, start, sizeof(byte))) {
+ stack->pushBool(false);
+ } else {
+ *(byte *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetShort") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ short val = (short)stack->pop()->getInt();
+
+ if (!checkBounds(script, start, sizeof(short))) {
+ stack->pushBool(false);
+ } else {
+ *(short *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetInt / SetLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetInt") == 0 || strcmp(name, "SetLong") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ int val = stack->pop()->getInt();
+
+ if (!checkBounds(script, start, sizeof(int))) {
+ stack->pushBool(false);
+ } else {
+ *(int *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetFloat") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ float val = (float)stack->pop()->getFloat();
+
+ if (!checkBounds(script, start, sizeof(float))) {
+ stack->pushBool(false);
+ } else {
+ *(float *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetDouble") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ double val = stack->pop()->getFloat();
+
+ if (!checkBounds(script, start, sizeof(double))) {
+ stack->pushBool(false);
+ } else {
+ *(double *)((byte *)_buffer + start) = val;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetString") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ const char *val = stack->pop()->getString();
+
+ if (!checkBounds(script, start, strlen(val) + 1)) {
+ stack->pushBool(false);
+ } else {
+ memcpy((byte *)_buffer + start, val, strlen(val) + 1);
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetPointer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetPointer") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ /* ScValue *val = */ stack->pop();
+
+ if (!checkBounds(script, start, sizeof(void *))) {
+ stack->pushBool(false);
+ } else {
+ /*
+ int pointer = (int)Val->getMemBuffer();
+ memcpy((byte *)_buffer+Start, &Pointer, sizeof(void*));
+ stack->pushBool(true);
+ */
+ // TODO fix
+ stack->pushBool(false);
+
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DEBUG_Dump
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DEBUG_Dump") == 0) {
+ stack->correctParams(0);
+ if (_buffer && _size) {
+ warning("SXMemBuffer::ScCallMethod - DEBUG_Dump");
+ Common::DumpFile f;
+ f.open("buffer.bin");
+ f.write(_buffer, _size);
+ f.close();
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXMemBuffer::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("membuffer");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Size (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Size") == 0) {
+ _scValue->setInt(_size);
+ return _scValue;
+ } else {
+ return BaseScriptable::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMemBuffer::scSetProperty(const char *name, ScValue *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;
+ }
+ else*/ return BaseScriptable::scSetProperty(name, value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXMemBuffer::persist(BasePersistenceManager *persistMgr) {
+
+ BaseScriptable::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_size));
+
+ if (persistMgr->getIsSaving()) {
+ if (_size > 0) {
+ persistMgr->putBytes((byte *)_buffer, _size);
+ }
+ } else {
+ if (_size > 0) {
+ _buffer = malloc(_size);
+ persistMgr->getBytes((byte *)_buffer, _size);
+ } else {
+ _buffer = NULL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int SXMemBuffer::scCompare(BaseScriptable *val) {
+ if (_buffer == val->scToMemBuffer()) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.h b/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
index 0a16167b58..d2662b3036 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
@@ -1,60 +1,60 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXMEMBUFFER_H
-#define WINTERMUTE_SXMEMBUFFER_H
-
-
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-class SXMemBuffer : public BaseScriptable {
-public:
- virtual int scCompare(BaseScriptable *Val);
- DECLARE_PERSISTENT(SXMemBuffer, BaseScriptable)
- ScValue *scGetProperty(const char *name);
- bool scSetProperty(const char *name, ScValue *value);
- bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- const char *scToString();
- SXMemBuffer(BaseGame *inGame, ScStack *stack);
- SXMemBuffer(BaseGame *inGame, void *buffer);
- virtual ~SXMemBuffer();
- virtual void *scToMemBuffer();
-private:
- int _size;
-
- bool resize(int newSize);
- void *_buffer;
- void cleanup();
- bool checkBounds(ScScript *script, int start, int length);
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXMEMBUFFER_H
+#define WINTERMUTE_SXMEMBUFFER_H
+
+
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+class SXMemBuffer : public BaseScriptable {
+public:
+ virtual int scCompare(BaseScriptable *Val);
+ DECLARE_PERSISTENT(SXMemBuffer, BaseScriptable)
+ ScValue *scGetProperty(const char *name);
+ bool scSetProperty(const char *name, ScValue *value);
+ bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ const char *scToString();
+ SXMemBuffer(BaseGame *inGame, ScStack *stack);
+ SXMemBuffer(BaseGame *inGame, void *buffer);
+ virtual ~SXMemBuffer();
+ virtual void *scToMemBuffer();
+private:
+ int _size;
+
+ bool resize(int newSize);
+ void *_buffer;
+ void cleanup();
+ bool checkBounds(ScScript *script, int start, int length);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_object.cpp b/engines/wintermute/base/scriptables/script_ext_object.cpp
index 40c9b885cd..b87aac81f9 100644
--- a/engines/wintermute/base/scriptables/script_ext_object.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_object.cpp
@@ -1,67 +1,67 @@
-/* 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/base/scriptables/script_ext_object.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-IMPLEMENT_PERSISTENT(SXObject, false)
-
-BaseScriptable *makeSXObject(BaseGame *inGame, ScStack *stack) {
- return new SXObject(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXObject::SXObject(BaseGame *inGame, ScStack *stack) : BaseObject(inGame) {
- int numParams = stack->pop()->getInt(0);
- for (int i = 0; i < numParams; i++) {
- addScript(stack->pop()->getString());
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXObject::~SXObject() {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXObject::persist(BasePersistenceManager *persistMgr) {
- BaseObject::persist(persistMgr);
-
- return STATUS_OK;
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_ext_object.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(SXObject, false)
+
+BaseScriptable *makeSXObject(BaseGame *inGame, ScStack *stack) {
+ return new SXObject(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXObject::SXObject(BaseGame *inGame, ScStack *stack) : BaseObject(inGame) {
+ int numParams = stack->pop()->getInt(0);
+ for (int i = 0; i < numParams; i++) {
+ addScript(stack->pop()->getString());
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXObject::~SXObject() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXObject::persist(BasePersistenceManager *persistMgr) {
+ BaseObject::persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_object.h b/engines/wintermute/base/scriptables/script_ext_object.h
index 32aa00776e..c85d16d44e 100644
--- a/engines/wintermute/base/scriptables/script_ext_object.h
+++ b/engines/wintermute/base/scriptables/script_ext_object.h
@@ -1,46 +1,46 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXOBJECT_H
-#define WINTERMUTE_SXOBJECT_H
-
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class SXObject : public BaseObject {
-public:
- DECLARE_PERSISTENT(SXObject, BaseObject)
- SXObject(BaseGame *inGame, ScStack *Stack);
- virtual ~SXObject();
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXOBJECT_H
+#define WINTERMUTE_SXOBJECT_H
+
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class SXObject : public BaseObject {
+public:
+ DECLARE_PERSISTENT(SXObject, BaseObject)
+ SXObject(BaseGame *inGame, ScStack *Stack);
+ virtual ~SXObject();
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_string.cpp b/engines/wintermute/base/scriptables/script_ext_string.cpp
index 9bcfe28bbf..8d87a92dc1 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -1,436 +1,436 @@
-/* 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/base/base_game.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/base/scriptables/script_ext_string.h"
-#include "engines/wintermute/base/scriptables/script_ext_array.h"
-#include "engines/wintermute/utils/string_util.h"
-#include "common/tokenizer.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(SXString, false)
-
-BaseScriptable *makeSXString(BaseGame *inGame, ScStack *stack) {
- return new SXString(inGame, stack);
-}
-
-//////////////////////////////////////////////////////////////////////////
-SXString::SXString(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
- _string = NULL;
- _capacity = 0;
-
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- if (val->isInt()) {
- _capacity = MAX(0, val->getInt());
- if (_capacity > 0) {
- _string = new char[_capacity];
- memset(_string, 0, _capacity);
- }
- } else {
- setStringVal(val->getString());
- }
-
- if (_capacity == 0) {
- setStringVal("");
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-SXString::~SXString() {
- if (_string) {
- delete[] _string;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void SXString::setStringVal(const char *val) {
- int len = strlen(val);
- if (len >= _capacity) {
- _capacity = len + 1;
- delete[] _string;
- _string = NULL;
- _string = new char[_capacity];
- memset(_string, 0, _capacity);
- }
- strcpy(_string, val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *SXString::scToString() {
- if (_string) {
- return _string;
- } else {
- return "[null string]";
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void SXString::scSetString(const char *val) {
- setStringVal(val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // Substring
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Substring") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
- int end = stack->pop()->getInt();
-
- if (end < start) {
- BaseUtils::swap(&start, &end);
- }
-
- //try {
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
- //WideString subStr = str.substr(start, end - start + 1);
- WideString subStr(str.c_str() + start, end - start + 1);
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
- } else {
- stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
- }
- // } catch (std::exception &) {
- // stack->pushNULL();
- // }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Substr
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Substr") == 0) {
- stack->correctParams(2);
- int start = stack->pop()->getInt();
-
- ScValue *val = stack->pop();
- int len = val->getInt();
-
- if (!val->isNULL() && len <= 0) {
- stack->pushString("");
- return STATUS_OK;
- }
-
- if (val->isNULL()) {
- len = strlen(_string) - start;
- }
-
-// try {
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
-// WideString subStr = str.substr(start, len);
- WideString subStr(str.c_str() + start, len);
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
- } else {
- stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
- }
-// } catch (std::exception &) {
-// stack->pushNULL();
-// }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ToUpperCase
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ToUpperCase") == 0) {
- stack->correctParams(0);
-
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
- str.toUppercase();
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- stack->pushString(StringUtil::wideToUtf8(str).c_str());
- } else {
- stack->pushString(StringUtil::wideToAnsi(str).c_str());
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ToLowerCase
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ToLowerCase") == 0) {
- stack->correctParams(0);
-
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
- str.toLowercase();
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- stack->pushString(StringUtil::wideToUtf8(str).c_str());
- } else {
- stack->pushString(StringUtil::wideToAnsi(str).c_str());
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IndexOf
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IndexOf") == 0) {
- stack->correctParams(2);
-
- const char *strToFind = stack->pop()->getString();
- int index = stack->pop()->getInt();
-
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
- WideString toFind;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- toFind = StringUtil::utf8ToWide(strToFind);
- } else {
- toFind = StringUtil::ansiToWide(strToFind);
- }
-
- int indexOf = StringUtil::indexOf(str, toFind, index);
- stack->pushInt(indexOf);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Split
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Split") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- char separators[MAX_PATH_LENGTH] = ",";
- if (!val->isNULL()) {
- strcpy(separators, val->getString());
- }
-
- SXArray *array = new SXArray(_gameRef);
- if (!array) {
- stack->pushNULL();
- return STATUS_OK;
- }
-
-
- WideString str;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- str = StringUtil::utf8ToWide(_string);
- } else {
- str = StringUtil::ansiToWide(_string);
- }
-
- WideString delims;
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- delims = StringUtil::utf8ToWide(separators);
- } else {
- delims = StringUtil::ansiToWide(separators);
- }
-
- Common::Array<WideString> parts;
-
-
-
- Common::StringTokenizer tokenizer(str, delims);
- while (!tokenizer.empty()) {
- Common::String str2 = tokenizer.nextToken();
- parts.push_back(str2);
- }
- // TODO: Clean this up
- /*do {
- pos = StringUtil::IndexOf(Common::String(str.c_str() + start), delims, start);
- //pos = str.find_first_of(delims, start);
- if (pos == start) {
- start = pos + 1;
- } else if (pos == str.size()) {
- parts.push_back(Common::String(str.c_str() + start));
- break;
- } else {
- parts.push_back(Common::String(str.c_str() + start, pos - start));
- start = pos + 1;
- }
- //start = str.find_first_not_of(delims, start);
- start = StringUtil::LastIndexOf(Common::String(str.c_str() + start), delims, start) + 1;
-
- } while (pos != str.size());*/
-
- for (Common::Array<WideString>::iterator it = parts.begin(); it != parts.end(); ++it) {
- WideString &part = (*it);
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- val = new ScValue(_gameRef, StringUtil::wideToUtf8(part).c_str());
- } else {
- val = new ScValue(_gameRef, StringUtil::wideToAnsi(part).c_str());
- }
-
- array->push(val);
- delete val;
- val = NULL;
- }
-
- stack->pushNative(array, false);
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *SXString::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("string");
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // Length (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Length") == 0) {
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- WideString wstr = StringUtil::utf8ToWide(_string);
- _scValue->setInt(wstr.size());
- } else {
- _scValue->setInt(strlen(_string));
- }
-
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // Capacity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Capacity") == 0) {
- _scValue->setInt(_capacity);
- return _scValue;
- } else {
- return _scValue;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXString::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Capacity
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Capacity") == 0) {
- int32 newCap = (uint32)value->getInt();
- if (newCap < (int32)(strlen(_string) + 1)) {
- _gameRef->LOG(0, "Warning: cannot lower string capacity");
- } else if (newCap != _capacity) {
- char *newStr = new char[newCap];
- if (newStr) {
- memset(newStr, 0, newCap);
- strcpy(newStr, _string);
- delete[] _string;
- _string = newStr;
- _capacity = newCap;
- }
- }
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool SXString::persist(BasePersistenceManager *persistMgr) {
-
- BaseScriptable::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_capacity));
-
- if (persistMgr->getIsSaving()) {
- if (_capacity > 0) {
- persistMgr->putBytes((byte *)_string, _capacity);
- }
- } else {
- if (_capacity > 0) {
- _string = new char[_capacity];
- persistMgr->getBytes((byte *)_string, _capacity);
- } else {
- _string = NULL;
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int SXString::scCompare(BaseScriptable *val) {
- return strcmp(_string, ((SXString *)val)->_string);
-}
-
-} // end of namespace Wintermute
+/* 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/base/base_game.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/base/scriptables/script_ext_string.h"
+#include "engines/wintermute/base/scriptables/script_ext_array.h"
+#include "engines/wintermute/utils/string_util.h"
+#include "common/tokenizer.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(SXString, false)
+
+BaseScriptable *makeSXString(BaseGame *inGame, ScStack *stack) {
+ return new SXString(inGame, stack);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SXString::SXString(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
+ _string = NULL;
+ _capacity = 0;
+
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ if (val->isInt()) {
+ _capacity = MAX(0, val->getInt());
+ if (_capacity > 0) {
+ _string = new char[_capacity];
+ memset(_string, 0, _capacity);
+ }
+ } else {
+ setStringVal(val->getString());
+ }
+
+ if (_capacity == 0) {
+ setStringVal("");
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+SXString::~SXString() {
+ if (_string) {
+ delete[] _string;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void SXString::setStringVal(const char *val) {
+ int len = strlen(val);
+ if (len >= _capacity) {
+ _capacity = len + 1;
+ delete[] _string;
+ _string = NULL;
+ _string = new char[_capacity];
+ memset(_string, 0, _capacity);
+ }
+ strcpy(_string, val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *SXString::scToString() {
+ if (_string) {
+ return _string;
+ } else {
+ return "[null string]";
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void SXString::scSetString(const char *val) {
+ setStringVal(val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // Substring
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Substring") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+ int end = stack->pop()->getInt();
+
+ if (end < start) {
+ BaseUtils::swap(&start, &end);
+ }
+
+ //try {
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+ //WideString subStr = str.substr(start, end - start + 1);
+ WideString subStr(str.c_str() + start, end - start + 1);
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
+ } else {
+ stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
+ }
+ // } catch (std::exception &) {
+ // stack->pushNULL();
+ // }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Substr
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Substr") == 0) {
+ stack->correctParams(2);
+ int start = stack->pop()->getInt();
+
+ ScValue *val = stack->pop();
+ int len = val->getInt();
+
+ if (!val->isNULL() && len <= 0) {
+ stack->pushString("");
+ return STATUS_OK;
+ }
+
+ if (val->isNULL()) {
+ len = strlen(_string) - start;
+ }
+
+// try {
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+// WideString subStr = str.substr(start, len);
+ WideString subStr(str.c_str() + start, len);
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
+ } else {
+ stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
+ }
+// } catch (std::exception &) {
+// stack->pushNULL();
+// }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToUpperCase
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ToUpperCase") == 0) {
+ stack->correctParams(0);
+
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+ str.toUppercase();
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ stack->pushString(StringUtil::wideToUtf8(str).c_str());
+ } else {
+ stack->pushString(StringUtil::wideToAnsi(str).c_str());
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToLowerCase
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ToLowerCase") == 0) {
+ stack->correctParams(0);
+
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+ str.toLowercase();
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ stack->pushString(StringUtil::wideToUtf8(str).c_str());
+ } else {
+ stack->pushString(StringUtil::wideToAnsi(str).c_str());
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IndexOf
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IndexOf") == 0) {
+ stack->correctParams(2);
+
+ const char *strToFind = stack->pop()->getString();
+ int index = stack->pop()->getInt();
+
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+ WideString toFind;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ toFind = StringUtil::utf8ToWide(strToFind);
+ } else {
+ toFind = StringUtil::ansiToWide(strToFind);
+ }
+
+ int indexOf = StringUtil::indexOf(str, toFind, index);
+ stack->pushInt(indexOf);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Split
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Split") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ char separators[MAX_PATH_LENGTH] = ",";
+ if (!val->isNULL()) {
+ strcpy(separators, val->getString());
+ }
+
+ SXArray *array = new SXArray(_gameRef);
+ if (!array) {
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+
+ WideString str;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ str = StringUtil::utf8ToWide(_string);
+ } else {
+ str = StringUtil::ansiToWide(_string);
+ }
+
+ WideString delims;
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ delims = StringUtil::utf8ToWide(separators);
+ } else {
+ delims = StringUtil::ansiToWide(separators);
+ }
+
+ Common::Array<WideString> parts;
+
+
+
+ Common::StringTokenizer tokenizer(str, delims);
+ while (!tokenizer.empty()) {
+ Common::String str2 = tokenizer.nextToken();
+ parts.push_back(str2);
+ }
+ // TODO: Clean this up
+ /*do {
+ pos = StringUtil::IndexOf(Common::String(str.c_str() + start), delims, start);
+ //pos = str.find_first_of(delims, start);
+ if (pos == start) {
+ start = pos + 1;
+ } else if (pos == str.size()) {
+ parts.push_back(Common::String(str.c_str() + start));
+ break;
+ } else {
+ parts.push_back(Common::String(str.c_str() + start, pos - start));
+ start = pos + 1;
+ }
+ //start = str.find_first_not_of(delims, start);
+ start = StringUtil::LastIndexOf(Common::String(str.c_str() + start), delims, start) + 1;
+
+ } while (pos != str.size());*/
+
+ for (Common::Array<WideString>::iterator it = parts.begin(); it != parts.end(); ++it) {
+ WideString &part = (*it);
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ val = new ScValue(_gameRef, StringUtil::wideToUtf8(part).c_str());
+ } else {
+ val = new ScValue(_gameRef, StringUtil::wideToAnsi(part).c_str());
+ }
+
+ array->push(val);
+ delete val;
+ val = NULL;
+ }
+
+ stack->pushNative(array, false);
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *SXString::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("string");
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Length (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Length") == 0) {
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::utf8ToWide(_string);
+ _scValue->setInt(wstr.size());
+ } else {
+ _scValue->setInt(strlen(_string));
+ }
+
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Capacity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Capacity") == 0) {
+ _scValue->setInt(_capacity);
+ return _scValue;
+ } else {
+ return _scValue;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXString::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Capacity
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Capacity") == 0) {
+ int32 newCap = (uint32)value->getInt();
+ if (newCap < (int32)(strlen(_string) + 1)) {
+ _gameRef->LOG(0, "Warning: cannot lower string capacity");
+ } else if (newCap != _capacity) {
+ char *newStr = new char[newCap];
+ if (newStr) {
+ memset(newStr, 0, newCap);
+ strcpy(newStr, _string);
+ delete[] _string;
+ _string = newStr;
+ _capacity = newCap;
+ }
+ }
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool SXString::persist(BasePersistenceManager *persistMgr) {
+
+ BaseScriptable::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_capacity));
+
+ if (persistMgr->getIsSaving()) {
+ if (_capacity > 0) {
+ persistMgr->putBytes((byte *)_string, _capacity);
+ }
+ } else {
+ if (_capacity > 0) {
+ _string = new char[_capacity];
+ persistMgr->getBytes((byte *)_string, _capacity);
+ } else {
+ _string = NULL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int SXString::scCompare(BaseScriptable *val) {
+ return strcmp(_string, ((SXString *)val)->_string);
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_string.h b/engines/wintermute/base/scriptables/script_ext_string.h
index c2de3860ed..255b9c57eb 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.h
+++ b/engines/wintermute/base/scriptables/script_ext_string.h
@@ -1,58 +1,58 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SXSTRING_H
-#define WINTERMUTE_SXSTRING_H
-
-
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-class SXString : public BaseScriptable {
-public:
- virtual int scCompare(BaseScriptable *Val);
- DECLARE_PERSISTENT(SXString, BaseScriptable)
- ScValue *scGetProperty(const char *name);
- bool scSetProperty(const char *name, ScValue *value);
- bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- void scSetString(const char *val);
- const char *scToString();
- void setStringVal(const char *val);
-
- SXString(BaseGame *inGame, ScStack *Stack);
- virtual ~SXString();
-
-private:
- char *_string;
- int _capacity;
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SXSTRING_H
+#define WINTERMUTE_SXSTRING_H
+
+
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+class SXString : public BaseScriptable {
+public:
+ virtual int scCompare(BaseScriptable *Val);
+ DECLARE_PERSISTENT(SXString, BaseScriptable)
+ ScValue *scGetProperty(const char *name);
+ bool scSetProperty(const char *name, ScValue *value);
+ bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ void scSetString(const char *val);
+ const char *scToString();
+ void setStringVal(const char *val);
+
+ SXString(BaseGame *inGame, ScStack *Stack);
+ virtual ~SXString();
+
+private:
+ char *_string;
+ int _capacity;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_stack.cpp b/engines/wintermute/base/scriptables/script_stack.cpp
index d27748abe6..77367045c2 100644
--- a/engines/wintermute/base/scriptables/script_stack.cpp
+++ b/engines/wintermute/base/scriptables/script_stack.cpp
@@ -1,232 +1,232 @@
-/* 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/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/base_game.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(ScStack, false)
-
-//////////////////////////////////////////////////////////////////////////
-ScStack::ScStack(BaseGame *inGame) : BaseClass(inGame) {
- _sP = -1;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScStack::~ScStack() {
-
-#if _DEBUG
- //_gameRef->LOG(0, "STAT: Stack size: %d, SP=%d", _values.size(), _sP);
-#endif
-
- for (uint32 i = 0; i < _values.size(); i++) {
- delete _values[i];
- }
- _values.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScStack::pop() {
- if (_sP < 0) {
- _gameRef->LOG(0, "Fatal: Stack underflow");
- return NULL;
- }
-
- return _values[_sP--];
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::push(ScValue *val) {
- _sP++;
-
- if (_sP < (int32)_values.size()) {
- _values[_sP]->cleanup();
- _values[_sP]->copy(val);
- } else {
- ScValue *copyVal = new ScValue(_gameRef);
- copyVal->copy(val);
- _values.add(copyVal);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScStack::getPushValue() {
- _sP++;
-
- if (_sP >= (int32)_values.size()) {
- ScValue *val = new ScValue(_gameRef);
- _values.add(val);
- }
- _values[_sP]->cleanup();
- return _values[_sP];
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScStack::getTop() {
- if (_sP < 0 || _sP >= (int32)_values.size()) {
- return NULL;
- } else {
- return _values[_sP];
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScStack::getAt(int index) {
- index = _sP - index;
- if (index < 0 || index >= (int32)_values.size()) {
- return NULL;
- } else {
- return _values[index];
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::correctParams(uint32 expectedParams) {
- uint32 nuParams = (uint32)pop()->getInt();
-
- if (expectedParams < nuParams) { // too many params
- while (expectedParams < nuParams) {
- //Pop();
- delete _values[_sP - expectedParams];
- _values.remove_at(_sP - expectedParams);
- nuParams--;
- _sP--;
- }
- } else if (expectedParams > nuParams) { // need more params
- while (expectedParams > nuParams) {
- //Push(null_val);
- ScValue *nullVal = new ScValue(_gameRef);
- nullVal->setNULL();
- _values.insert_at(_sP - nuParams + 1, nullVal);
- nuParams++;
- _sP++;
-
- if ((int32)_values.size() > _sP + 1) {
- delete _values[_values.size() - 1];
- _values.remove_at(_values.size() - 1);
- }
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushNULL() {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setNULL();
- Push(val);
- delete val;
- */
- getPushValue()->setNULL();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushInt(int val) {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setInt(Val);
- Push(val);
- delete val;
- */
- getPushValue()->setInt(val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushFloat(double val) {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setFloat(Val);
- Push(val);
- delete val;
- */
- getPushValue()->setFloat(val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushBool(bool val) {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setBool(Val);
- Push(val);
- delete val;
- */
- getPushValue()->setBool(val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushString(const char *val) {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setString(Val);
- Push(val);
- delete val;
- */
- getPushValue()->setString(val);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScStack::pushNative(BaseScriptable *val, bool persistent) {
- /*
- ScValue* val = new ScValue(_gameRef);
- val->setNative(Val, Persistent);
- Push(val);
- delete val;
- */
-
- getPushValue()->setNative(val, persistent);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScStack::persist(BasePersistenceManager *persistMgr) {
-
- persistMgr->transfer(TMEMBER(_gameRef));
-
- persistMgr->transfer(TMEMBER(_sP));
- _values.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-} // end of namespace Wintermute
+/* 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/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/base_game.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(ScStack, false)
+
+//////////////////////////////////////////////////////////////////////////
+ScStack::ScStack(BaseGame *inGame) : BaseClass(inGame) {
+ _sP = -1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScStack::~ScStack() {
+
+#if _DEBUG
+ //_gameRef->LOG(0, "STAT: Stack size: %d, SP=%d", _values.size(), _sP);
+#endif
+
+ for (uint32 i = 0; i < _values.size(); i++) {
+ delete _values[i];
+ }
+ _values.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScStack::pop() {
+ if (_sP < 0) {
+ _gameRef->LOG(0, "Fatal: Stack underflow");
+ return NULL;
+ }
+
+ return _values[_sP--];
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::push(ScValue *val) {
+ _sP++;
+
+ if (_sP < (int32)_values.size()) {
+ _values[_sP]->cleanup();
+ _values[_sP]->copy(val);
+ } else {
+ ScValue *copyVal = new ScValue(_gameRef);
+ copyVal->copy(val);
+ _values.add(copyVal);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScStack::getPushValue() {
+ _sP++;
+
+ if (_sP >= (int32)_values.size()) {
+ ScValue *val = new ScValue(_gameRef);
+ _values.add(val);
+ }
+ _values[_sP]->cleanup();
+ return _values[_sP];
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScStack::getTop() {
+ if (_sP < 0 || _sP >= (int32)_values.size()) {
+ return NULL;
+ } else {
+ return _values[_sP];
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScStack::getAt(int index) {
+ index = _sP - index;
+ if (index < 0 || index >= (int32)_values.size()) {
+ return NULL;
+ } else {
+ return _values[index];
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::correctParams(uint32 expectedParams) {
+ uint32 nuParams = (uint32)pop()->getInt();
+
+ if (expectedParams < nuParams) { // too many params
+ while (expectedParams < nuParams) {
+ //Pop();
+ delete _values[_sP - expectedParams];
+ _values.remove_at(_sP - expectedParams);
+ nuParams--;
+ _sP--;
+ }
+ } else if (expectedParams > nuParams) { // need more params
+ while (expectedParams > nuParams) {
+ //Push(null_val);
+ ScValue *nullVal = new ScValue(_gameRef);
+ nullVal->setNULL();
+ _values.insert_at(_sP - nuParams + 1, nullVal);
+ nuParams++;
+ _sP++;
+
+ if ((int32)_values.size() > _sP + 1) {
+ delete _values[_values.size() - 1];
+ _values.remove_at(_values.size() - 1);
+ }
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushNULL() {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setNULL();
+ Push(val);
+ delete val;
+ */
+ getPushValue()->setNULL();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushInt(int val) {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setInt(Val);
+ Push(val);
+ delete val;
+ */
+ getPushValue()->setInt(val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushFloat(double val) {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setFloat(Val);
+ Push(val);
+ delete val;
+ */
+ getPushValue()->setFloat(val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushBool(bool val) {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setBool(Val);
+ Push(val);
+ delete val;
+ */
+ getPushValue()->setBool(val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushString(const char *val) {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setString(Val);
+ Push(val);
+ delete val;
+ */
+ getPushValue()->setString(val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScStack::pushNative(BaseScriptable *val, bool persistent) {
+ /*
+ ScValue* val = new ScValue(_gameRef);
+ val->setNative(Val, Persistent);
+ Push(val);
+ delete val;
+ */
+
+ getPushValue()->setNative(val, persistent);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScStack::persist(BasePersistenceManager *persistMgr) {
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ persistMgr->transfer(TMEMBER(_sP));
+ _values.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_stack.h b/engines/wintermute/base/scriptables/script_stack.h
index 0e2adae518..86d246cf34 100644
--- a/engines/wintermute/base/scriptables/script_stack.h
+++ b/engines/wintermute/base/scriptables/script_stack.h
@@ -1,66 +1,66 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SCSTACK_H
-#define WINTERMUTE_SCSTACK_H
-
-
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/coll_templ.h"
-#include "engines/wintermute/persistent.h"
-
-namespace Wintermute {
-
-class ScValue;
-class BaseScriptable;
-
-class ScStack : public BaseClass {
-public:
- ScValue *getAt(int Index);
- ScValue *getPushValue();
- DECLARE_PERSISTENT(ScStack, BaseClass)
- void pushNative(BaseScriptable *val, bool persistent);
- void pushString(const char *val);
- void pushBool(bool val);
- void pushInt(int val);
- void pushFloat(double val);
- void pushNULL();
- void correctParams(uint32 expectedParams);
- ScValue *getTop();
- void push(ScValue *val);
- ScValue *pop();
- ScStack(BaseGame *inGame);
- virtual ~ScStack();
- BaseArray<ScValue *> _values;
- int _sP;
-
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SCSTACK_H
+#define WINTERMUTE_SCSTACK_H
+
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/persistent.h"
+
+namespace Wintermute {
+
+class ScValue;
+class BaseScriptable;
+
+class ScStack : public BaseClass {
+public:
+ ScValue *getAt(int Index);
+ ScValue *getPushValue();
+ DECLARE_PERSISTENT(ScStack, BaseClass)
+ void pushNative(BaseScriptable *val, bool persistent);
+ void pushString(const char *val);
+ void pushBool(bool val);
+ void pushInt(int val);
+ void pushFloat(double val);
+ void pushNULL();
+ void correctParams(uint32 expectedParams);
+ ScValue *getTop();
+ void push(ScValue *val);
+ ScValue *pop();
+ ScStack(BaseGame *inGame);
+ virtual ~ScStack();
+ BaseArray<ScValue *> _values;
+ int _sP;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 03ca69ac7e..0bc7ab5807 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -1,995 +1,995 @@
-/* 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/platform_osystem.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/utils/string_util.h"
-#include "engines/wintermute/base/base_scriptable.h"
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-IMPLEMENT_PERSISTENT(ScValue, false)
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::ScValue(BaseGame *inGame) : BaseClass(inGame) {
- _type = VAL_NULL;
-
- _valBool = false;
- _valInt = 0;
- _valFloat = 0.0f;
- _valNative = NULL;
- _valString = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::ScValue(BaseGame *inGame, bool val) : BaseClass(inGame) {
- _type = VAL_BOOL;
- _valBool = val;
-
- _valInt = 0;
- _valFloat = 0.0f;
- _valNative = NULL;
- _valString = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::ScValue(BaseGame *inGame, int val) : BaseClass(inGame) {
- _type = VAL_INT;
- _valInt = val;
-
- _valFloat = 0.0f;
- _valBool = false;
- _valNative = NULL;
- _valString = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::ScValue(BaseGame *inGame, double val) : BaseClass(inGame) {
- _type = VAL_FLOAT;
- _valFloat = val;
-
- _valInt = 0;
- _valBool = false;
- _valNative = NULL;
- _valString = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::ScValue(BaseGame *inGame, const char *val) : BaseClass(inGame) {
- _type = VAL_STRING;
- _valString = NULL;
- setStringVal(val);
-
- _valBool = false;
- _valInt = 0;
- _valFloat = 0.0f;
- _valNative = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::cleanup(bool ignoreNatives) {
- deleteProps();
-
- if (_valString) {
- delete[] _valString;
- }
-
- if (!ignoreNatives) {
- if (_valNative && !_persistent) {
- _valNative->_refCount--;
- if (_valNative->_refCount <= 0) {
- delete _valNative;
- _valNative = NULL;
- }
- }
- }
-
-
- _type = VAL_NULL;
-
- _valBool = false;
- _valInt = 0;
- _valFloat = 0.0f;
- _valNative = NULL;
- _valString = NULL;
- _valRef = NULL;
- _persistent = false;
- _isConstVar = false;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue::~ScValue() {
- cleanup();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *ScValue::getProp(const char *name) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getProp(name);
- }
-
- if (_type == VAL_STRING && strcmp(name, "Length") == 0) {
- _gameRef->_scValue->_type = VAL_INT;
-
- if (_gameRef->_textEncoding == TEXT_ANSI) {
- _gameRef->_scValue->setInt(strlen(_valString));
- } else {
- WideString wstr = StringUtil::utf8ToWide(_valString);
- _gameRef->_scValue->setInt(wstr.size());
- }
-
- return _gameRef->_scValue;
- }
-
- ScValue *ret = NULL;
-
- if (_type == VAL_NATIVE && _valNative) {
- ret = _valNative->scGetProperty(name);
- }
-
- if (ret == NULL) {
- _valIter = _valObject.find(name);
- if (_valIter != _valObject.end()) {
- ret = _valIter->_value;
- }
- }
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::deleteProp(const char *name) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->deleteProp(name);
- }
-
- _valIter = _valObject.find(name);
- if (_valIter != _valObject.end()) {
- delete _valIter->_value;
- _valIter->_value = NULL;
- }
-
- return STATUS_OK;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProp(const char *name, ScValue *val, bool copyWhole, bool setAsConst) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->setProp(name, val);
- }
-
- bool ret = STATUS_FAILED;
- if (_type == VAL_NATIVE && _valNative) {
- ret = _valNative->scSetProperty(name, val);
- }
-
- if (DID_FAIL(ret)) {
- ScValue *newVal = NULL;
-
- _valIter = _valObject.find(name);
- if (_valIter != _valObject.end()) {
- newVal = _valIter->_value;
- }
- if (!newVal) {
- newVal = new ScValue(_gameRef);
- } else {
- newVal->cleanup();
- }
-
- newVal->copy(val, copyWhole);
- newVal->_isConstVar = setAsConst;
- _valObject[name] = newVal;
-
- if (_type != VAL_NATIVE) {
- _type = VAL_OBJECT;
- }
-
- /*
- _valIter = _valObject.find(Name);
- if (_valIter != _valObject.end()){
- delete _valIter->_value;
- _valIter->_value = NULL;
- }
- ScValue* val = new ScValue(_gameRef);
- val->Copy(Val, CopyWhole);
- val->_isConstVar = SetAsConst;
- _valObject[Name] = val;
-
- if (_type!=VAL_NATIVE) _type = VAL_OBJECT;
- */
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::propExists(const char *name) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->propExists(name);
- }
- _valIter = _valObject.find(name);
-
- return (_valIter != _valObject.end());
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::deleteProps() {
- _valIter = _valObject.begin();
- while (_valIter != _valObject.end()) {
- delete(ScValue *)_valIter->_value;
- _valIter++;
- }
- _valObject.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::CleanProps(bool includingNatives) {
- _valIter = _valObject.begin();
- while (_valIter != _valObject.end()) {
- if (!_valIter->_value->_isConstVar && (!_valIter->_value->isNative() || includingNatives)) {
- _valIter->_value->setNULL();
- }
- _valIter++;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isNULL() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isNULL();
- }
-
- return (_type == VAL_NULL);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isNative() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isNative();
- }
-
- return (_type == VAL_NATIVE);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isString() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isString();
- }
-
- return (_type == VAL_STRING);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isFloat() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isFloat();
- }
-
- return (_type == VAL_FLOAT);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isInt() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isInt();
- }
-
- return (_type == VAL_INT);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isBool() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isBool();
- }
-
- return (_type == VAL_BOOL);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::isObject() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->isObject();
- }
-
- return (_type == VAL_OBJECT);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-TValType ScValue::getTypeTolerant() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getType();
- }
-
- return _type;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setBool(bool val) {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setBool(val);
- return;
- }
-
- if (_type == VAL_NATIVE) {
- _valNative->scSetBool(val);
- return;
- }
-
- _valBool = val;
- _type = VAL_BOOL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setInt(int val) {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setInt(val);
- return;
- }
-
- if (_type == VAL_NATIVE) {
- _valNative->scSetInt(val);
- return;
- }
-
- _valInt = val;
- _type = VAL_INT;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setFloat(double val) {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setFloat(val);
- return;
- }
-
- if (_type == VAL_NATIVE) {
- _valNative->scSetFloat(val);
- return;
- }
-
- _valFloat = val;
- _type = VAL_FLOAT;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setString(const char *val) {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setString(val);
- return;
- }
-
- if (_type == VAL_NATIVE) {
- _valNative->scSetString(val);
- return;
- }
-
- setStringVal(val);
- if (_valString) {
- _type = VAL_STRING;
- } else {
- _type = VAL_NULL;
- }
-}
-
-void ScValue::setString(const Common::String &val) {
- setString(val.c_str());
-}
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setStringVal(const char *val) {
- if (_valString) {
- delete[] _valString;
- _valString = NULL;
- }
-
- if (val == NULL) {
- _valString = NULL;
- return;
- }
-
- _valString = new char [strlen(val) + 1];
- if (_valString) {
- strcpy(_valString, val);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setNULL() {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setNULL();
- return;
- }
-
- if (_valNative && !_persistent) {
- _valNative->_refCount--;
- if (_valNative->_refCount <= 0) {
- delete _valNative;
- }
- }
- _valNative = NULL;
- deleteProps();
-
- _type = VAL_NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setNative(BaseScriptable *val, bool persistent) {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setNative(val, persistent);
- return;
- }
-
- if (val == NULL) {
- setNULL();
- } else {
- if (_valNative && !_persistent) {
- _valNative->_refCount--;
- if (_valNative->_refCount <= 0) {
- if (_valNative != val) {
- delete _valNative;
- }
- _valNative = NULL;
- }
- }
-
- _type = VAL_NATIVE;
- _persistent = persistent;
-
- _valNative = val;
- if (_valNative && !_persistent) {
- _valNative->_refCount++;
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setObject() {
- if (_type == VAL_VARIABLE_REF) {
- _valRef->setObject();
- return;
- }
-
- deleteProps();
- _type = VAL_OBJECT;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setReference(ScValue *val) {
- _valRef = val;
- _type = VAL_VARIABLE_REF;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::getBool(bool defaultVal) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getBool();
- }
-
- switch (_type) {
- case VAL_BOOL:
- return _valBool;
-
- case VAL_NATIVE:
- return _valNative->scToBool();
-
- case VAL_INT:
- return (_valInt != 0);
-
- case VAL_FLOAT:
- return (_valFloat != 0.0f);
-
- case VAL_STRING:
- return (scumm_stricmp(_valString, "1") == 0 || scumm_stricmp(_valString, "yes") == 0 || scumm_stricmp(_valString, "true") == 0);
-
- default:
- return defaultVal;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int ScValue::getInt(int defaultVal) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getInt();
- }
-
- switch (_type) {
- case VAL_BOOL:
- return _valBool ? 1 : 0;
-
- case VAL_NATIVE:
- return _valNative->scToInt();
-
- case VAL_INT:
- return _valInt;
-
- case VAL_FLOAT:
- return (int)_valFloat;
-
- case VAL_STRING:
- return atoi(_valString);
-
- default:
- return defaultVal;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-double ScValue::getFloat(double defaultVal) {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getFloat();
- }
-
- switch (_type) {
- case VAL_BOOL:
- return _valBool ? 1.0f : 0.0f;
-
- case VAL_NATIVE:
- return _valNative->scToFloat();
-
- case VAL_INT:
- return (double)_valInt;
-
- case VAL_FLOAT:
- return _valFloat;
-
- case VAL_STRING:
- return atof(_valString);
-
- default:
- return defaultVal;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-void *ScValue::getMemBuffer() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getMemBuffer();
- }
-
- if (_type == VAL_NATIVE) {
- return _valNative->scToMemBuffer();
- } else {
- return (void *)NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *ScValue::getString() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getString();
- }
-
- switch (_type) {
- case VAL_OBJECT:
- setStringVal("[object]");
- break;
-
- case VAL_NULL:
- setStringVal("[null]");
- break;
-
- case VAL_NATIVE: {
- const char *strVal = _valNative->scToString();
- setStringVal(strVal);
- return strVal;
- break;
- }
-
- case VAL_BOOL:
- setStringVal(_valBool ? "yes" : "no");
- break;
-
- case VAL_INT: {
- char dummy[50];
- sprintf(dummy, "%d", _valInt);
- setStringVal(dummy);
- break;
- }
-
- case VAL_FLOAT: {
- char dummy[50];
- sprintf(dummy, "%f", _valFloat);
- setStringVal(dummy);
- break;
- }
-
- case VAL_STRING:
- break;
-
- default:
- setStringVal("");
- }
-
- return _valString;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseScriptable *ScValue::getNative() {
- if (_type == VAL_VARIABLE_REF) {
- return _valRef->getNative();
- }
-
- if (_type == VAL_NATIVE) {
- return _valNative;
- } else {
- return NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-TValType ScValue::getType() {
- return _type;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::copy(ScValue *orig, bool copyWhole) {
- _gameRef = orig->_gameRef;
-
- if (_valNative && !_persistent) {
- _valNative->_refCount--;
- if (_valNative->_refCount <= 0) {
- if (_valNative != orig->_valNative) {
- delete _valNative;
- }
- _valNative = NULL;
- }
- }
-
- if (orig->_type == VAL_VARIABLE_REF && orig->_valRef && copyWhole) {
- orig = orig->_valRef;
- }
-
- cleanup(true);
-
- _type = orig->_type;
- _valBool = orig->_valBool;
- _valInt = orig->_valInt;
- _valFloat = orig->_valFloat;
- setStringVal(orig->_valString);
-
- _valRef = orig->_valRef;
- _persistent = orig->_persistent;
-
- _valNative = orig->_valNative;
- if (_valNative && !_persistent) {
- _valNative->_refCount++;
- }
-//!!!! ref->native++
-
- // copy properties
- if (orig->_type == VAL_OBJECT && orig->_valObject.size() > 0) {
- orig->_valIter = orig->_valObject.begin();
- while (orig->_valIter != orig->_valObject.end()) {
- _valObject[orig->_valIter->_key] = new ScValue(_gameRef);
- _valObject[orig->_valIter->_key]->copy(orig->_valIter->_value);
- orig->_valIter++;
- }
- } else {
- _valObject.clear();
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void ScValue::setValue(ScValue *val) {
- if (val->_type == VAL_VARIABLE_REF) {
- setValue(val->_valRef);
- return;
- }
-
- // if being assigned a simple type, preserve native state
- if (_type == VAL_NATIVE && (val->_type == VAL_INT || val->_type == VAL_STRING || val->_type == VAL_BOOL)) {
- switch (val->_type) {
- case VAL_INT:
- _valNative->scSetInt(val->getInt());
- break;
- case VAL_FLOAT:
- _valNative->scSetFloat(val->getFloat());
- break;
- case VAL_BOOL:
- _valNative->scSetBool(val->getBool());
- break;
- case VAL_STRING:
- _valNative->scSetString(val->getString());
- break;
- default:
- warning("ScValue::setValue - unhandled enum");
- break;
- }
- }
- // otherwise just copy everything
- else {
- copy(val);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_gameRef));
-
- persistMgr->transfer(TMEMBER(_persistent));
- persistMgr->transfer(TMEMBER(_isConstVar));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_valBool));
- persistMgr->transfer(TMEMBER(_valFloat));
- persistMgr->transfer(TMEMBER(_valInt));
- persistMgr->transfer(TMEMBER(_valNative));
-
- int size;
- const char *str;
- if (persistMgr->getIsSaving()) {
- size = _valObject.size();
- persistMgr->transfer("", &size);
- _valIter = _valObject.begin();
- while (_valIter != _valObject.end()) {
- str = _valIter->_key.c_str();
- persistMgr->transfer("", &str);
- persistMgr->transfer("", &_valIter->_value);
-
- _valIter++;
- }
- } else {
- ScValue *val;
- persistMgr->transfer("", &size);
- for (int i = 0; i < size; i++) {
- persistMgr->transfer("", &str);
- persistMgr->transfer("", &val);
-
- _valObject[str] = val;
- delete[] str;
- }
- }
-
- persistMgr->transfer(TMEMBER(_valRef));
- persistMgr->transfer(TMEMBER(_valString));
-
- /*
- FILE* f = fopen("c:\\val.log", "a+");
- switch(_type)
- {
- case VAL_STRING:
- fprintf(f, "str %s\n", _valString);
- break;
-
- case VAL_INT:
- fprintf(f, "int %d\n", _valInt);
- break;
-
- case VAL_BOOL:
- fprintf(f, "bool %d\n", _valBool);
- break;
-
- case VAL_NULL:
- fprintf(f, "null\n");
- break;
-
- case VAL_NATIVE:
- fprintf(f, "native\n");
- break;
-
- case VAL_VARIABLE_REF:
- fprintf(f, "ref\n");
- break;
-
- case VAL_OBJECT:
- fprintf(f, "obj\n");
- break;
-
- case VAL_FLOAT:
- fprintf(f, "float\n");
- break;
-
- }
- fclose(f);
- */
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- _valIter = _valObject.begin();
- while (_valIter != _valObject.end()) {
- buffer->putTextIndent(indent, "PROPERTY {\n");
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _valIter->_key.c_str());
- buffer->putTextIndent(indent + 2, "VALUE=\"%s\"\n", _valIter->_value->getString());
- buffer->putTextIndent(indent, "}\n\n");
-
- _valIter++;
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// -1 ... left is less, 0 ... equals, 1 ... left is greater
-int ScValue::compare(ScValue *val1, ScValue *val2) {
- // both natives?
- if (val1->isNative() && val2->isNative()) {
- // same class?
- if (strcmp(val1->getNative()->getClassName(), val2->getNative()->getClassName()) == 0) {
- return val1->getNative()->scCompare(val2->getNative());
- } else {
- return strcmp(val1->getString(), val2->getString());
- }
- }
-
- // both objects?
- if (val1->isObject() && val2->isObject()) {
- return -1;
- }
-
-
- // null states
- if (val1->isNULL() && !val2->isNULL()) {
- return -1;
- } else if (!val1->isNULL() && val2->isNULL()) {
- return 1;
- } else if (val1->isNULL() && val2->isNULL()) {
- return 0;
- }
-
- // one of them is string? convert both to string
- if (val1->isString() || val2->isString()) {
- return strcmp(val1->getString(), val2->getString());
- }
-
- // one of them is float?
- if (val1->isFloat() || val2->isFloat()) {
- if (val1->getFloat() < val2->getFloat()) {
- return -1;
- } else if (val1->getFloat() > val2->getFloat()) {
- return 1;
- } else {
- return 0;
- }
- }
-
- // otherwise compare as int's
- if (val1->getInt() < val2->getInt()) {
- return -1;
- } else if (val1->getInt() > val2->getInt()) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int ScValue::compareStrict(ScValue *val1, ScValue *val2) {
- if (val1->getTypeTolerant() != val2->getTypeTolerant()) {
- return -1;
- } else {
- return ScValue::compare(val1, val2);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProperty(const char *propName, int value) {
- ScValue *val = new ScValue(_gameRef, value);
- bool ret = DID_SUCCEED(setProp(propName, val));
- delete val;
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProperty(const char *propName, const char *value) {
- ScValue *val = new ScValue(_gameRef, value);
- bool ret = DID_SUCCEED(setProp(propName, val));
- delete val;
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProperty(const char *propName, double value) {
- ScValue *val = new ScValue(_gameRef, value);
- bool ret = DID_SUCCEED(setProp(propName, val));
- delete val;
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProperty(const char *propName, bool value) {
- ScValue *val = new ScValue(_gameRef, value);
- bool ret = DID_SUCCEED(setProp(propName, val));
- delete val;
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool ScValue::setProperty(const char *propName) {
- ScValue *val = new ScValue(_gameRef);
- bool ret = DID_SUCCEED(setProp(propName, val));
- delete val;
- return ret;
-}
-
-} // end of namespace Wintermute
+/* 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/platform_osystem.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/utils/string_util.h"
+#include "engines/wintermute/base/base_scriptable.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(ScValue, false)
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::ScValue(BaseGame *inGame) : BaseClass(inGame) {
+ _type = VAL_NULL;
+
+ _valBool = false;
+ _valInt = 0;
+ _valFloat = 0.0f;
+ _valNative = NULL;
+ _valString = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::ScValue(BaseGame *inGame, bool val) : BaseClass(inGame) {
+ _type = VAL_BOOL;
+ _valBool = val;
+
+ _valInt = 0;
+ _valFloat = 0.0f;
+ _valNative = NULL;
+ _valString = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::ScValue(BaseGame *inGame, int val) : BaseClass(inGame) {
+ _type = VAL_INT;
+ _valInt = val;
+
+ _valFloat = 0.0f;
+ _valBool = false;
+ _valNative = NULL;
+ _valString = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::ScValue(BaseGame *inGame, double val) : BaseClass(inGame) {
+ _type = VAL_FLOAT;
+ _valFloat = val;
+
+ _valInt = 0;
+ _valBool = false;
+ _valNative = NULL;
+ _valString = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::ScValue(BaseGame *inGame, const char *val) : BaseClass(inGame) {
+ _type = VAL_STRING;
+ _valString = NULL;
+ setStringVal(val);
+
+ _valBool = false;
+ _valInt = 0;
+ _valFloat = 0.0f;
+ _valNative = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::cleanup(bool ignoreNatives) {
+ deleteProps();
+
+ if (_valString) {
+ delete[] _valString;
+ }
+
+ if (!ignoreNatives) {
+ if (_valNative && !_persistent) {
+ _valNative->_refCount--;
+ if (_valNative->_refCount <= 0) {
+ delete _valNative;
+ _valNative = NULL;
+ }
+ }
+ }
+
+
+ _type = VAL_NULL;
+
+ _valBool = false;
+ _valInt = 0;
+ _valFloat = 0.0f;
+ _valNative = NULL;
+ _valString = NULL;
+ _valRef = NULL;
+ _persistent = false;
+ _isConstVar = false;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue::~ScValue() {
+ cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *ScValue::getProp(const char *name) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getProp(name);
+ }
+
+ if (_type == VAL_STRING && strcmp(name, "Length") == 0) {
+ _gameRef->_scValue->_type = VAL_INT;
+
+ if (_gameRef->_textEncoding == TEXT_ANSI) {
+ _gameRef->_scValue->setInt(strlen(_valString));
+ } else {
+ WideString wstr = StringUtil::utf8ToWide(_valString);
+ _gameRef->_scValue->setInt(wstr.size());
+ }
+
+ return _gameRef->_scValue;
+ }
+
+ ScValue *ret = NULL;
+
+ if (_type == VAL_NATIVE && _valNative) {
+ ret = _valNative->scGetProperty(name);
+ }
+
+ if (ret == NULL) {
+ _valIter = _valObject.find(name);
+ if (_valIter != _valObject.end()) {
+ ret = _valIter->_value;
+ }
+ }
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::deleteProp(const char *name) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->deleteProp(name);
+ }
+
+ _valIter = _valObject.find(name);
+ if (_valIter != _valObject.end()) {
+ delete _valIter->_value;
+ _valIter->_value = NULL;
+ }
+
+ return STATUS_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProp(const char *name, ScValue *val, bool copyWhole, bool setAsConst) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->setProp(name, val);
+ }
+
+ bool ret = STATUS_FAILED;
+ if (_type == VAL_NATIVE && _valNative) {
+ ret = _valNative->scSetProperty(name, val);
+ }
+
+ if (DID_FAIL(ret)) {
+ ScValue *newVal = NULL;
+
+ _valIter = _valObject.find(name);
+ if (_valIter != _valObject.end()) {
+ newVal = _valIter->_value;
+ }
+ if (!newVal) {
+ newVal = new ScValue(_gameRef);
+ } else {
+ newVal->cleanup();
+ }
+
+ newVal->copy(val, copyWhole);
+ newVal->_isConstVar = setAsConst;
+ _valObject[name] = newVal;
+
+ if (_type != VAL_NATIVE) {
+ _type = VAL_OBJECT;
+ }
+
+ /*
+ _valIter = _valObject.find(Name);
+ if (_valIter != _valObject.end()){
+ delete _valIter->_value;
+ _valIter->_value = NULL;
+ }
+ ScValue* val = new ScValue(_gameRef);
+ val->Copy(Val, CopyWhole);
+ val->_isConstVar = SetAsConst;
+ _valObject[Name] = val;
+
+ if (_type!=VAL_NATIVE) _type = VAL_OBJECT;
+ */
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::propExists(const char *name) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->propExists(name);
+ }
+ _valIter = _valObject.find(name);
+
+ return (_valIter != _valObject.end());
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::deleteProps() {
+ _valIter = _valObject.begin();
+ while (_valIter != _valObject.end()) {
+ delete(ScValue *)_valIter->_value;
+ _valIter++;
+ }
+ _valObject.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::CleanProps(bool includingNatives) {
+ _valIter = _valObject.begin();
+ while (_valIter != _valObject.end()) {
+ if (!_valIter->_value->_isConstVar && (!_valIter->_value->isNative() || includingNatives)) {
+ _valIter->_value->setNULL();
+ }
+ _valIter++;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isNULL() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isNULL();
+ }
+
+ return (_type == VAL_NULL);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isNative() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isNative();
+ }
+
+ return (_type == VAL_NATIVE);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isString() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isString();
+ }
+
+ return (_type == VAL_STRING);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isFloat() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isFloat();
+ }
+
+ return (_type == VAL_FLOAT);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isInt() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isInt();
+ }
+
+ return (_type == VAL_INT);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isBool() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isBool();
+ }
+
+ return (_type == VAL_BOOL);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::isObject() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->isObject();
+ }
+
+ return (_type == VAL_OBJECT);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+TValType ScValue::getTypeTolerant() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getType();
+ }
+
+ return _type;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setBool(bool val) {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setBool(val);
+ return;
+ }
+
+ if (_type == VAL_NATIVE) {
+ _valNative->scSetBool(val);
+ return;
+ }
+
+ _valBool = val;
+ _type = VAL_BOOL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setInt(int val) {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setInt(val);
+ return;
+ }
+
+ if (_type == VAL_NATIVE) {
+ _valNative->scSetInt(val);
+ return;
+ }
+
+ _valInt = val;
+ _type = VAL_INT;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setFloat(double val) {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setFloat(val);
+ return;
+ }
+
+ if (_type == VAL_NATIVE) {
+ _valNative->scSetFloat(val);
+ return;
+ }
+
+ _valFloat = val;
+ _type = VAL_FLOAT;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setString(const char *val) {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setString(val);
+ return;
+ }
+
+ if (_type == VAL_NATIVE) {
+ _valNative->scSetString(val);
+ return;
+ }
+
+ setStringVal(val);
+ if (_valString) {
+ _type = VAL_STRING;
+ } else {
+ _type = VAL_NULL;
+ }
+}
+
+void ScValue::setString(const Common::String &val) {
+ setString(val.c_str());
+}
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setStringVal(const char *val) {
+ if (_valString) {
+ delete[] _valString;
+ _valString = NULL;
+ }
+
+ if (val == NULL) {
+ _valString = NULL;
+ return;
+ }
+
+ _valString = new char [strlen(val) + 1];
+ if (_valString) {
+ strcpy(_valString, val);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setNULL() {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setNULL();
+ return;
+ }
+
+ if (_valNative && !_persistent) {
+ _valNative->_refCount--;
+ if (_valNative->_refCount <= 0) {
+ delete _valNative;
+ }
+ }
+ _valNative = NULL;
+ deleteProps();
+
+ _type = VAL_NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setNative(BaseScriptable *val, bool persistent) {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setNative(val, persistent);
+ return;
+ }
+
+ if (val == NULL) {
+ setNULL();
+ } else {
+ if (_valNative && !_persistent) {
+ _valNative->_refCount--;
+ if (_valNative->_refCount <= 0) {
+ if (_valNative != val) {
+ delete _valNative;
+ }
+ _valNative = NULL;
+ }
+ }
+
+ _type = VAL_NATIVE;
+ _persistent = persistent;
+
+ _valNative = val;
+ if (_valNative && !_persistent) {
+ _valNative->_refCount++;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setObject() {
+ if (_type == VAL_VARIABLE_REF) {
+ _valRef->setObject();
+ return;
+ }
+
+ deleteProps();
+ _type = VAL_OBJECT;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setReference(ScValue *val) {
+ _valRef = val;
+ _type = VAL_VARIABLE_REF;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::getBool(bool defaultVal) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getBool();
+ }
+
+ switch (_type) {
+ case VAL_BOOL:
+ return _valBool;
+
+ case VAL_NATIVE:
+ return _valNative->scToBool();
+
+ case VAL_INT:
+ return (_valInt != 0);
+
+ case VAL_FLOAT:
+ return (_valFloat != 0.0f);
+
+ case VAL_STRING:
+ return (scumm_stricmp(_valString, "1") == 0 || scumm_stricmp(_valString, "yes") == 0 || scumm_stricmp(_valString, "true") == 0);
+
+ default:
+ return defaultVal;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int ScValue::getInt(int defaultVal) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getInt();
+ }
+
+ switch (_type) {
+ case VAL_BOOL:
+ return _valBool ? 1 : 0;
+
+ case VAL_NATIVE:
+ return _valNative->scToInt();
+
+ case VAL_INT:
+ return _valInt;
+
+ case VAL_FLOAT:
+ return (int)_valFloat;
+
+ case VAL_STRING:
+ return atoi(_valString);
+
+ default:
+ return defaultVal;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+double ScValue::getFloat(double defaultVal) {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getFloat();
+ }
+
+ switch (_type) {
+ case VAL_BOOL:
+ return _valBool ? 1.0f : 0.0f;
+
+ case VAL_NATIVE:
+ return _valNative->scToFloat();
+
+ case VAL_INT:
+ return (double)_valInt;
+
+ case VAL_FLOAT:
+ return _valFloat;
+
+ case VAL_STRING:
+ return atof(_valString);
+
+ default:
+ return defaultVal;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void *ScValue::getMemBuffer() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getMemBuffer();
+ }
+
+ if (_type == VAL_NATIVE) {
+ return _valNative->scToMemBuffer();
+ } else {
+ return (void *)NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *ScValue::getString() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getString();
+ }
+
+ switch (_type) {
+ case VAL_OBJECT:
+ setStringVal("[object]");
+ break;
+
+ case VAL_NULL:
+ setStringVal("[null]");
+ break;
+
+ case VAL_NATIVE: {
+ const char *strVal = _valNative->scToString();
+ setStringVal(strVal);
+ return strVal;
+ break;
+ }
+
+ case VAL_BOOL:
+ setStringVal(_valBool ? "yes" : "no");
+ break;
+
+ case VAL_INT: {
+ char dummy[50];
+ sprintf(dummy, "%d", _valInt);
+ setStringVal(dummy);
+ break;
+ }
+
+ case VAL_FLOAT: {
+ char dummy[50];
+ sprintf(dummy, "%f", _valFloat);
+ setStringVal(dummy);
+ break;
+ }
+
+ case VAL_STRING:
+ break;
+
+ default:
+ setStringVal("");
+ }
+
+ return _valString;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseScriptable *ScValue::getNative() {
+ if (_type == VAL_VARIABLE_REF) {
+ return _valRef->getNative();
+ }
+
+ if (_type == VAL_NATIVE) {
+ return _valNative;
+ } else {
+ return NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+TValType ScValue::getType() {
+ return _type;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::copy(ScValue *orig, bool copyWhole) {
+ _gameRef = orig->_gameRef;
+
+ if (_valNative && !_persistent) {
+ _valNative->_refCount--;
+ if (_valNative->_refCount <= 0) {
+ if (_valNative != orig->_valNative) {
+ delete _valNative;
+ }
+ _valNative = NULL;
+ }
+ }
+
+ if (orig->_type == VAL_VARIABLE_REF && orig->_valRef && copyWhole) {
+ orig = orig->_valRef;
+ }
+
+ cleanup(true);
+
+ _type = orig->_type;
+ _valBool = orig->_valBool;
+ _valInt = orig->_valInt;
+ _valFloat = orig->_valFloat;
+ setStringVal(orig->_valString);
+
+ _valRef = orig->_valRef;
+ _persistent = orig->_persistent;
+
+ _valNative = orig->_valNative;
+ if (_valNative && !_persistent) {
+ _valNative->_refCount++;
+ }
+//!!!! ref->native++
+
+ // copy properties
+ if (orig->_type == VAL_OBJECT && orig->_valObject.size() > 0) {
+ orig->_valIter = orig->_valObject.begin();
+ while (orig->_valIter != orig->_valObject.end()) {
+ _valObject[orig->_valIter->_key] = new ScValue(_gameRef);
+ _valObject[orig->_valIter->_key]->copy(orig->_valIter->_value);
+ orig->_valIter++;
+ }
+ } else {
+ _valObject.clear();
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void ScValue::setValue(ScValue *val) {
+ if (val->_type == VAL_VARIABLE_REF) {
+ setValue(val->_valRef);
+ return;
+ }
+
+ // if being assigned a simple type, preserve native state
+ if (_type == VAL_NATIVE && (val->_type == VAL_INT || val->_type == VAL_STRING || val->_type == VAL_BOOL)) {
+ switch (val->_type) {
+ case VAL_INT:
+ _valNative->scSetInt(val->getInt());
+ break;
+ case VAL_FLOAT:
+ _valNative->scSetFloat(val->getFloat());
+ break;
+ case VAL_BOOL:
+ _valNative->scSetBool(val->getBool());
+ break;
+ case VAL_STRING:
+ _valNative->scSetString(val->getString());
+ break;
+ default:
+ warning("ScValue::setValue - unhandled enum");
+ break;
+ }
+ }
+ // otherwise just copy everything
+ else {
+ copy(val);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ persistMgr->transfer(TMEMBER(_persistent));
+ persistMgr->transfer(TMEMBER(_isConstVar));
+ persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transfer(TMEMBER(_valBool));
+ persistMgr->transfer(TMEMBER(_valFloat));
+ persistMgr->transfer(TMEMBER(_valInt));
+ persistMgr->transfer(TMEMBER(_valNative));
+
+ int size;
+ const char *str;
+ if (persistMgr->getIsSaving()) {
+ size = _valObject.size();
+ persistMgr->transfer("", &size);
+ _valIter = _valObject.begin();
+ while (_valIter != _valObject.end()) {
+ str = _valIter->_key.c_str();
+ persistMgr->transfer("", &str);
+ persistMgr->transfer("", &_valIter->_value);
+
+ _valIter++;
+ }
+ } else {
+ ScValue *val;
+ persistMgr->transfer("", &size);
+ for (int i = 0; i < size; i++) {
+ persistMgr->transfer("", &str);
+ persistMgr->transfer("", &val);
+
+ _valObject[str] = val;
+ delete[] str;
+ }
+ }
+
+ persistMgr->transfer(TMEMBER(_valRef));
+ persistMgr->transfer(TMEMBER(_valString));
+
+ /*
+ FILE* f = fopen("c:\\val.log", "a+");
+ switch(_type)
+ {
+ case VAL_STRING:
+ fprintf(f, "str %s\n", _valString);
+ break;
+
+ case VAL_INT:
+ fprintf(f, "int %d\n", _valInt);
+ break;
+
+ case VAL_BOOL:
+ fprintf(f, "bool %d\n", _valBool);
+ break;
+
+ case VAL_NULL:
+ fprintf(f, "null\n");
+ break;
+
+ case VAL_NATIVE:
+ fprintf(f, "native\n");
+ break;
+
+ case VAL_VARIABLE_REF:
+ fprintf(f, "ref\n");
+ break;
+
+ case VAL_OBJECT:
+ fprintf(f, "obj\n");
+ break;
+
+ case VAL_FLOAT:
+ fprintf(f, "float\n");
+ break;
+
+ }
+ fclose(f);
+ */
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ _valIter = _valObject.begin();
+ while (_valIter != _valObject.end()) {
+ buffer->putTextIndent(indent, "PROPERTY {\n");
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _valIter->_key.c_str());
+ buffer->putTextIndent(indent + 2, "VALUE=\"%s\"\n", _valIter->_value->getString());
+ buffer->putTextIndent(indent, "}\n\n");
+
+ _valIter++;
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// -1 ... left is less, 0 ... equals, 1 ... left is greater
+int ScValue::compare(ScValue *val1, ScValue *val2) {
+ // both natives?
+ if (val1->isNative() && val2->isNative()) {
+ // same class?
+ if (strcmp(val1->getNative()->getClassName(), val2->getNative()->getClassName()) == 0) {
+ return val1->getNative()->scCompare(val2->getNative());
+ } else {
+ return strcmp(val1->getString(), val2->getString());
+ }
+ }
+
+ // both objects?
+ if (val1->isObject() && val2->isObject()) {
+ return -1;
+ }
+
+
+ // null states
+ if (val1->isNULL() && !val2->isNULL()) {
+ return -1;
+ } else if (!val1->isNULL() && val2->isNULL()) {
+ return 1;
+ } else if (val1->isNULL() && val2->isNULL()) {
+ return 0;
+ }
+
+ // one of them is string? convert both to string
+ if (val1->isString() || val2->isString()) {
+ return strcmp(val1->getString(), val2->getString());
+ }
+
+ // one of them is float?
+ if (val1->isFloat() || val2->isFloat()) {
+ if (val1->getFloat() < val2->getFloat()) {
+ return -1;
+ } else if (val1->getFloat() > val2->getFloat()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ // otherwise compare as int's
+ if (val1->getInt() < val2->getInt()) {
+ return -1;
+ } else if (val1->getInt() > val2->getInt()) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int ScValue::compareStrict(ScValue *val1, ScValue *val2) {
+ if (val1->getTypeTolerant() != val2->getTypeTolerant()) {
+ return -1;
+ } else {
+ return ScValue::compare(val1, val2);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProperty(const char *propName, int value) {
+ ScValue *val = new ScValue(_gameRef, value);
+ bool ret = DID_SUCCEED(setProp(propName, val));
+ delete val;
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProperty(const char *propName, const char *value) {
+ ScValue *val = new ScValue(_gameRef, value);
+ bool ret = DID_SUCCEED(setProp(propName, val));
+ delete val;
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProperty(const char *propName, double value) {
+ ScValue *val = new ScValue(_gameRef, value);
+ bool ret = DID_SUCCEED(setProp(propName, val));
+ delete val;
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProperty(const char *propName, bool value) {
+ ScValue *val = new ScValue(_gameRef, value);
+ bool ret = DID_SUCCEED(setProp(propName, val));
+ delete val;
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool ScValue::setProperty(const char *propName) {
+ ScValue *val = new ScValue(_gameRef);
+ bool ret = DID_SUCCEED(setProp(propName, val));
+ delete val;
+ return ret;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_value.h b/engines/wintermute/base/scriptables/script_value.h
index af31014bac..bf7d9cd8a1 100644
--- a/engines/wintermute/base/scriptables/script_value.h
+++ b/engines/wintermute/base/scriptables/script_value.h
@@ -1,113 +1,113 @@
-/* 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
- */
-
-#ifndef WINTERMUTE_SCVALUE_H
-#define WINTERMUTE_SCVALUE_H
-
-
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView
-#include "common/str.h"
-
-namespace Wintermute {
-
-class ScScript;
-class BaseScriptable;
-
-class ScValue : public BaseClass {
-public:
- static int compare(ScValue *val1, ScValue *val2);
- static int compareStrict(ScValue *val1, ScValue *val2);
- TValType getTypeTolerant();
- void cleanup(bool ignoreNatives = false);
- DECLARE_PERSISTENT(ScValue, BaseClass)
-
- bool _isConstVar;
- bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- void setValue(ScValue *val);
- bool _persistent;
- bool propExists(const char *name);
- void copy(ScValue *orig, bool copyWhole = false);
- void setStringVal(const char *val);
- TValType getType();
- bool getBool(bool defaultVal = false);
- int getInt(int defaultVal = 0);
- double getFloat(double defaultVal = 0.0f);
- const char *getString();
- void *getMemBuffer();
- BaseScriptable *getNative();
- bool deleteProp(const char *name);
- void deleteProps();
- void CleanProps(bool includingNatives);
- void setBool(bool val);
- void setInt(int val);
- void setFloat(double val);
- void setString(const char *val);
- void setString(const Common::String &val);
- void setNULL();
- void setNative(BaseScriptable *val, bool persistent = false);
- void setObject();
- void setReference(ScValue *val);
- bool isNULL();
- bool isNative();
- bool isString();
- bool isBool();
- bool isFloat();
- bool isInt();
- bool isObject();
- bool setProp(const char *name, ScValue *val, bool copyWhole = false, bool setAsConst = false);
- ScValue *getProp(const char *name);
- BaseScriptable *_valNative;
- ScValue *_valRef;
-private:
- bool _valBool;
- int _valInt;
- double _valFloat;
- char *_valString;
-public:
- TValType _type;
- ScValue(BaseGame *inGame);
- ScValue(BaseGame *inGame, bool Val);
- ScValue(BaseGame *inGame, int Val);
- ScValue(BaseGame *inGame, double Val);
- ScValue(BaseGame *inGame, const char *Val);
- virtual ~ScValue();
- Common::HashMap<Common::String, ScValue *> _valObject;
- Common::HashMap<Common::String, ScValue *>::iterator _valIter;
-
- bool setProperty(const char *propName, int value);
- bool setProperty(const char *propName, const char *value);
- bool setProperty(const char *propName, double value);
- bool setProperty(const char *propName, bool value);
- bool setProperty(const char *propName);
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* 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
+ */
+
+#ifndef WINTERMUTE_SCVALUE_H
+#define WINTERMUTE_SCVALUE_H
+
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView
+#include "common/str.h"
+
+namespace Wintermute {
+
+class ScScript;
+class BaseScriptable;
+
+class ScValue : public BaseClass {
+public:
+ static int compare(ScValue *val1, ScValue *val2);
+ static int compareStrict(ScValue *val1, ScValue *val2);
+ TValType getTypeTolerant();
+ void cleanup(bool ignoreNatives = false);
+ DECLARE_PERSISTENT(ScValue, BaseClass)
+
+ bool _isConstVar;
+ bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ void setValue(ScValue *val);
+ bool _persistent;
+ bool propExists(const char *name);
+ void copy(ScValue *orig, bool copyWhole = false);
+ void setStringVal(const char *val);
+ TValType getType();
+ bool getBool(bool defaultVal = false);
+ int getInt(int defaultVal = 0);
+ double getFloat(double defaultVal = 0.0f);
+ const char *getString();
+ void *getMemBuffer();
+ BaseScriptable *getNative();
+ bool deleteProp(const char *name);
+ void deleteProps();
+ void CleanProps(bool includingNatives);
+ void setBool(bool val);
+ void setInt(int val);
+ void setFloat(double val);
+ void setString(const char *val);
+ void setString(const Common::String &val);
+ void setNULL();
+ void setNative(BaseScriptable *val, bool persistent = false);
+ void setObject();
+ void setReference(ScValue *val);
+ bool isNULL();
+ bool isNative();
+ bool isString();
+ bool isBool();
+ bool isFloat();
+ bool isInt();
+ bool isObject();
+ bool setProp(const char *name, ScValue *val, bool copyWhole = false, bool setAsConst = false);
+ ScValue *getProp(const char *name);
+ BaseScriptable *_valNative;
+ ScValue *_valRef;
+private:
+ bool _valBool;
+ int _valInt;
+ double _valFloat;
+ char *_valString;
+public:
+ TValType _type;
+ ScValue(BaseGame *inGame);
+ ScValue(BaseGame *inGame, bool Val);
+ ScValue(BaseGame *inGame, int Val);
+ ScValue(BaseGame *inGame, double Val);
+ ScValue(BaseGame *inGame, const char *Val);
+ virtual ~ScValue();
+ Common::HashMap<Common::String, ScValue *> _valObject;
+ Common::HashMap<Common::String, ScValue *>::iterator _valIter;
+
+ bool setProperty(const char *propName, int value);
+ bool setProperty(const char *propName, const char *value);
+ bool setProperty(const char *propName, double value);
+ bool setProperty(const char *propName, bool value);
+ bool setProperty(const char *propName);
+};
+
+} // end of namespace Wintermute
+
+#endif