Initial commit
This commit is contained in:
772
engines/wintermute/base/base_frame.cpp
Normal file
772
engines/wintermute/base/base_frame.cpp
Normal file
@@ -0,0 +1,772 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_parser.h"
|
||||
#include "engines/wintermute/base/base_engine.h"
|
||||
#include "engines/wintermute/base/base_frame.h"
|
||||
#include "engines/wintermute/base/base_game.h"
|
||||
#include "engines/wintermute/base/base_object.h"
|
||||
#include "engines/wintermute/base/base_dynamic_buffer.h"
|
||||
#include "engines/wintermute/base/sound/base_sound_manager.h"
|
||||
#include "engines/wintermute/base/sound/base_sound.h"
|
||||
#include "engines/wintermute/base/base_sub_frame.h"
|
||||
#include "engines/wintermute/platform_osystem.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/dcgf.h"
|
||||
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Wintermute {
|
||||
|
||||
IMPLEMENT_PERSISTENT(BaseFrame, false)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
BaseFrame::BaseFrame(BaseGame *inGame) : BaseScriptable(inGame, true) {
|
||||
_delay = 0;
|
||||
_moveX = _moveY = 0;
|
||||
|
||||
_sound = nullptr;
|
||||
_killSound = false;
|
||||
|
||||
_editorExpanded = false;
|
||||
_keyframe = false;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
BaseFrame::~BaseFrame() {
|
||||
SAFE_DELETE(_sound);
|
||||
|
||||
for (int32 i = 0; i < _subframes.getSize(); i++) {
|
||||
delete _subframes[i];
|
||||
}
|
||||
_subframes.removeAll();
|
||||
|
||||
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
|
||||
SAFE_DELETE_ARRAY(_applyEvent[i]);
|
||||
}
|
||||
_applyEvent.removeAll();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, bool allFrames, float rotate, Graphics::TSpriteBlendMode blendMode) {
|
||||
bool res;
|
||||
|
||||
for (int32 i = 0; i < _subframes.getSize(); i++) {
|
||||
// filter out subframes unsupported by current renderer
|
||||
//
|
||||
// This is not present in original Lite version of WME.
|
||||
// It's in assumption Lite support only 2D games.
|
||||
// Our 3D renderer has full 2D capability, so not filter 2D only subframes.
|
||||
if (!allFrames) {
|
||||
if (/*(_subframes[i]->_2DOnly && _game->_useD3D) || */(_subframes[i]->_3DOnly && !_game->_useD3D))
|
||||
continue;
|
||||
}
|
||||
res = _subframes[i]->draw(x, y, registerOwner, zoomX, zoomY, precise, alpha, rotate, blendMode);
|
||||
if (DID_FAIL(res)) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::oneTimeDisplay(BaseObject *owner, bool muted) {
|
||||
if (_sound && !muted) {
|
||||
if (owner) {
|
||||
owner->updateOneSound(_sound);
|
||||
}
|
||||
_sound->play();
|
||||
/*
|
||||
if (_game->_state == GAME_FROZEN) {
|
||||
_sound->pause(true);
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (owner) {
|
||||
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
|
||||
owner->applyEvent(_applyEvent[i]);
|
||||
}
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TOKEN_DEF_START
|
||||
TOKEN_DEF(DELAY)
|
||||
TOKEN_DEF(IMAGE)
|
||||
TOKEN_DEF(TRANSPARENT)
|
||||
TOKEN_DEF(RECT)
|
||||
TOKEN_DEF(HOTSPOT)
|
||||
TOKEN_DEF(2D_ONLY)
|
||||
TOKEN_DEF(3D_ONLY)
|
||||
TOKEN_DEF(MIRROR_X)
|
||||
TOKEN_DEF(MIRROR_Y)
|
||||
TOKEN_DEF(MOVE)
|
||||
TOKEN_DEF(ALPHA_COLOR)
|
||||
TOKEN_DEF(ALPHA)
|
||||
TOKEN_DEF(SUBFRAME)
|
||||
TOKEN_DEF(SOUND)
|
||||
TOKEN_DEF(KEYFRAME)
|
||||
TOKEN_DEF(DECORATION)
|
||||
TOKEN_DEF(APPLY_EVENT)
|
||||
TOKEN_DEF(EDITOR_SELECTED)
|
||||
TOKEN_DEF(EDITOR_EXPANDED)
|
||||
TOKEN_DEF(EDITOR_PROPERTY)
|
||||
TOKEN_DEF(KILL_SOUND)
|
||||
TOKEN_DEF_END
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
|
||||
TOKEN_TABLE_START(commands)
|
||||
TOKEN_TABLE(DELAY)
|
||||
TOKEN_TABLE(IMAGE)
|
||||
TOKEN_TABLE(TRANSPARENT)
|
||||
TOKEN_TABLE(RECT)
|
||||
TOKEN_TABLE(HOTSPOT)
|
||||
TOKEN_TABLE(2D_ONLY)
|
||||
TOKEN_TABLE(3D_ONLY)
|
||||
TOKEN_TABLE(MIRROR_X)
|
||||
TOKEN_TABLE(MIRROR_Y)
|
||||
TOKEN_TABLE(MOVE)
|
||||
TOKEN_TABLE(ALPHA_COLOR)
|
||||
TOKEN_TABLE(ALPHA)
|
||||
TOKEN_TABLE(SUBFRAME)
|
||||
TOKEN_TABLE(SOUND)
|
||||
TOKEN_TABLE(KEYFRAME)
|
||||
TOKEN_TABLE(DECORATION)
|
||||
TOKEN_TABLE(APPLY_EVENT)
|
||||
TOKEN_TABLE(EDITOR_SELECTED)
|
||||
TOKEN_TABLE(EDITOR_EXPANDED)
|
||||
TOKEN_TABLE(EDITOR_PROPERTY)
|
||||
TOKEN_TABLE(KILL_SOUND)
|
||||
TOKEN_TABLE_END
|
||||
|
||||
char *params;
|
||||
int cmd;
|
||||
BaseParser parser(_game);
|
||||
Common::Rect32 rect;
|
||||
int r = 255, g = 255, b = 255;
|
||||
int ar = 255, ag = 255, ab = 255, alpha = 255;
|
||||
int hotspotX = 0, hotspotY = 0;
|
||||
bool customTrans = false;
|
||||
bool editorSelected = false;
|
||||
bool is2DOnly = false;
|
||||
bool is3DOnly = false;
|
||||
bool decoration = false;
|
||||
bool mirrorX = false;
|
||||
bool mirrorY = false;
|
||||
BasePlatform::setRectEmpty(&rect);
|
||||
char *surface_file = nullptr;
|
||||
|
||||
while ((cmd = parser.getCommand(&buffer, commands, ¶ms)) > 0) {
|
||||
switch (cmd) {
|
||||
case TOKEN_DELAY:
|
||||
parser.scanStr(params, "%d", &_delay);
|
||||
break;
|
||||
|
||||
case TOKEN_IMAGE:
|
||||
surface_file = params;
|
||||
break;
|
||||
|
||||
case TOKEN_TRANSPARENT:
|
||||
parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
|
||||
customTrans = true;
|
||||
break;
|
||||
|
||||
case TOKEN_RECT:
|
||||
parser.scanStr(params, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
|
||||
break;
|
||||
|
||||
case TOKEN_HOTSPOT:
|
||||
parser.scanStr(params, "%d,%d", &hotspotX, &hotspotY);
|
||||
break;
|
||||
|
||||
case TOKEN_MOVE:
|
||||
parser.scanStr(params, "%d,%d", &_moveX, &_moveY);
|
||||
break;
|
||||
|
||||
case TOKEN_2D_ONLY:
|
||||
parser.scanStr(params, "%b", &is2DOnly);
|
||||
break;
|
||||
|
||||
case TOKEN_3D_ONLY:
|
||||
parser.scanStr(params, "%b", &is3DOnly);
|
||||
break;
|
||||
|
||||
case TOKEN_MIRROR_X:
|
||||
parser.scanStr(params, "%b", &mirrorX);
|
||||
break;
|
||||
|
||||
case TOKEN_MIRROR_Y:
|
||||
parser.scanStr(params, "%b", &mirrorY);
|
||||
break;
|
||||
|
||||
case TOKEN_ALPHA_COLOR:
|
||||
parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
|
||||
break;
|
||||
|
||||
case TOKEN_ALPHA:
|
||||
parser.scanStr(params, "%d", &alpha);
|
||||
break;
|
||||
|
||||
case TOKEN_EDITOR_SELECTED:
|
||||
parser.scanStr(params, "%b", &editorSelected);
|
||||
break;
|
||||
|
||||
case TOKEN_EDITOR_EXPANDED:
|
||||
parser.scanStr(params, "%b", &_editorExpanded);
|
||||
break;
|
||||
|
||||
case TOKEN_KILL_SOUND:
|
||||
parser.scanStr(params, "%b", &_killSound);
|
||||
break;
|
||||
|
||||
case TOKEN_SUBFRAME: {
|
||||
BaseSubFrame *subframe = new BaseSubFrame(_game);
|
||||
if (!subframe || DID_FAIL(subframe->loadBuffer(params, lifeTime, keepLoaded))) {
|
||||
delete subframe;
|
||||
cmd = PARSERR_GENERIC;
|
||||
} else {
|
||||
_subframes.add(subframe);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TOKEN_SOUND: {
|
||||
if (_sound) {
|
||||
SAFE_DELETE(_sound);
|
||||
}
|
||||
_sound = new BaseSound(_game);
|
||||
if (!_sound || DID_FAIL(_sound->setSound(params, TSoundType::SOUND_SFX, false))) {
|
||||
if (_game->_soundMgr->_soundAvailable) {
|
||||
_game->LOG(0, "Error loading sound '%s'.", params);
|
||||
}
|
||||
SAFE_DELETE(_sound);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TOKEN_APPLY_EVENT: {
|
||||
size_t eventSize = strlen(params) + 1;
|
||||
char *event = new char[eventSize];
|
||||
Common::strcpy_s(event, eventSize, params);
|
||||
_applyEvent.add(event);
|
||||
}
|
||||
break;
|
||||
|
||||
case TOKEN_KEYFRAME:
|
||||
parser.scanStr(params, "%b", &_keyframe);
|
||||
break;
|
||||
|
||||
case TOKEN_DECORATION:
|
||||
parser.scanStr(params, "%b", &decoration);
|
||||
break;
|
||||
|
||||
case TOKEN_EDITOR_PROPERTY:
|
||||
parseEditorProperty(params, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmd == PARSERR_TOKENNOTFOUND) {
|
||||
_game->LOG(0, "Syntax error in FRAME definition");
|
||||
return STATUS_FAILED;
|
||||
}
|
||||
|
||||
if (cmd == PARSERR_GENERIC) {
|
||||
_game->LOG(0, "Error loading FRAME definition");
|
||||
return STATUS_FAILED;
|
||||
}
|
||||
|
||||
|
||||
BaseSubFrame *sub = new BaseSubFrame(_game);
|
||||
if (surface_file != nullptr) {
|
||||
if (customTrans) {
|
||||
sub->setSurface(surface_file, false, r, g, b, lifeTime, keepLoaded);
|
||||
} else {
|
||||
sub->setSurface(surface_file, true, 0, 0, 0, lifeTime, keepLoaded);
|
||||
}
|
||||
|
||||
if (!sub->_surface) {
|
||||
delete sub;
|
||||
_game->LOG(0, "Error loading SUBFRAME");
|
||||
return STATUS_FAILED;
|
||||
}
|
||||
|
||||
sub->_alpha = BYTETORGBA(ar, ag, ab, alpha);
|
||||
if (customTrans) {
|
||||
sub->_transparent = BYTETORGBA(r, g, b, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (BasePlatform::isRectEmpty(&rect)) {
|
||||
sub->setDefaultRect();
|
||||
} else {
|
||||
sub->_rect = rect;
|
||||
}
|
||||
|
||||
sub->_hotspotX = hotspotX;
|
||||
sub->_hotspotY = hotspotY;
|
||||
sub->_2DOnly = is2DOnly;
|
||||
sub->_3DOnly = is3DOnly;
|
||||
sub->_decoration = decoration;
|
||||
sub->_mirrorX = mirrorX;
|
||||
sub->_mirrorY = mirrorY;
|
||||
|
||||
|
||||
sub->_editorSelected = editorSelected;
|
||||
_subframes.insertAt(0, sub);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::getBoundingRect(Common::Rect32 *rect, int x, int y, float scaleX, float scaleY) {
|
||||
if (!rect) {
|
||||
return false;
|
||||
}
|
||||
BasePlatform::setRectEmpty(rect);
|
||||
|
||||
Common::Rect32 subRect;
|
||||
|
||||
for (int32 i = 0; i < _subframes.getSize(); i++) {
|
||||
_subframes[i]->getBoundingRect(&subRect, x, y, scaleX, scaleY);
|
||||
BasePlatform::unionRect(rect, rect, &subRect);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::saveAsText(BaseDynamicBuffer *buffer, int indent) {
|
||||
buffer->putTextIndent(indent, "FRAME {\n");
|
||||
buffer->putTextIndent(indent + 2, "DELAY = %d\n", _delay);
|
||||
|
||||
if (_moveX != 0 || _moveY != 0) {
|
||||
buffer->putTextIndent(indent + 2, "MOVE {%d, %d}\n", _moveX, _moveY);
|
||||
}
|
||||
|
||||
if (_sound && _sound->_soundFilename && _sound->_soundFilename[0]) {
|
||||
buffer->putTextIndent(indent + 2, "SOUND=\"%s\"\n", _sound->_soundFilename);
|
||||
}
|
||||
|
||||
buffer->putTextIndent(indent + 2, "KEYFRAME=%s\n", _keyframe ? "TRUE" : "FALSE");
|
||||
|
||||
if (_killSound) {
|
||||
buffer->putTextIndent(indent + 2, "KILL_SOUND=%s\n", _killSound ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
if (_editorExpanded) {
|
||||
buffer->putTextIndent(indent + 2, "EDITOR_EXPANDED=%s\n", _editorExpanded ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
if (_subframes.getSize() > 0) {
|
||||
_subframes[0]->saveAsText(buffer, indent, false);
|
||||
}
|
||||
|
||||
for (int32 i = 1; i < _subframes.getSize(); i++) {
|
||||
_subframes[i]->saveAsText(buffer, indent + 2);
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
|
||||
buffer->putTextIndent(indent + 2, "APPLY_EVENT=\"%s\"\n", _applyEvent[i]);
|
||||
}
|
||||
|
||||
BaseClass::saveAsText(buffer, indent + 2);
|
||||
|
||||
|
||||
buffer->putTextIndent(indent, "}\n\n");
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::persist(BasePersistenceManager *persistMgr) {
|
||||
BaseScriptable::persist(persistMgr);
|
||||
|
||||
_applyEvent.persist(persistMgr);
|
||||
persistMgr->transferUint32(TMEMBER(_delay));
|
||||
persistMgr->transferBool(TMEMBER(_editorExpanded));
|
||||
persistMgr->transferBool(TMEMBER(_keyframe));
|
||||
persistMgr->transferBool(TMEMBER(_killSound));
|
||||
persistMgr->transferSint32(TMEMBER(_moveX));
|
||||
persistMgr->transferSint32(TMEMBER(_moveY));
|
||||
persistMgr->transferPtr(TMEMBER_PTR(_sound));
|
||||
_subframes.persist(persistMgr);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// high level scripting interface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GetSound
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "GetSound") == 0) {
|
||||
stack->correctParams(0);
|
||||
|
||||
if (_sound && _sound->_soundFilename && _sound->_soundFilename[0]) {
|
||||
stack->pushString(_sound->_soundFilename);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SetSound
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "SetSound") == 0) {
|
||||
stack->correctParams(1);
|
||||
ScValue *val = stack->pop();
|
||||
SAFE_DELETE(_sound);
|
||||
|
||||
if (!val->isNULL()) {
|
||||
_sound = new BaseSound(_game);
|
||||
if (!_sound || DID_FAIL(_sound->setSound(val->getString(), TSoundType::SOUND_SFX, false))) {
|
||||
stack->pushBool(false);
|
||||
SAFE_DELETE(_sound);
|
||||
} else {
|
||||
stack->pushBool(true);
|
||||
}
|
||||
} else {
|
||||
stack->pushBool(true);
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GetSubframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "GetSubframe") == 0) {
|
||||
stack->correctParams(1);
|
||||
int index = stack->pop()->getInt(-1);
|
||||
if (index < 0 || index >= _subframes.getSize()) {
|
||||
script->runtimeError("Frame.GetSubframe: Subframe index %d is out of range.", index);
|
||||
stack->pushNULL();
|
||||
} else {
|
||||
stack->pushNative(_subframes[index], true);
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// DeleteSubframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "DeleteSubframe") == 0) {
|
||||
stack->correctParams(1);
|
||||
ScValue *val = stack->pop();
|
||||
if (val->isInt()) {
|
||||
int index = val->getInt(-1);
|
||||
if (index < 0 || index >= _subframes.getSize()) {
|
||||
script->runtimeError("Frame.DeleteSubframe: Subframe index %d is out of range.", index);
|
||||
}
|
||||
} else {
|
||||
BaseSubFrame *sub = (BaseSubFrame *)val->getNative();
|
||||
for (int32 i = 0; i < _subframes.getSize(); i++) {
|
||||
if (_subframes[i] == sub) {
|
||||
delete _subframes[i];
|
||||
_subframes.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AddSubframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "AddSubframe") == 0) {
|
||||
stack->correctParams(1);
|
||||
ScValue *val = stack->pop();
|
||||
const char *filename = nullptr;
|
||||
if (!val->isNULL()) {
|
||||
filename = val->getString();
|
||||
}
|
||||
|
||||
BaseSubFrame *sub = new BaseSubFrame(_game);
|
||||
if (filename != nullptr) {
|
||||
sub->setSurface(filename);
|
||||
sub->setDefaultRect();
|
||||
}
|
||||
_subframes.add(sub);
|
||||
|
||||
stack->pushNative(sub, true);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// InsertSubframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "InsertSubframe") == 0) {
|
||||
stack->correctParams(2);
|
||||
int index = stack->pop()->getInt();
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
ScValue *val = stack->pop();
|
||||
const char *filename = nullptr;
|
||||
if (!val->isNULL()) {
|
||||
filename = val->getString();
|
||||
}
|
||||
|
||||
BaseSubFrame *sub = new BaseSubFrame(_game);
|
||||
if (filename != nullptr) {
|
||||
sub->setSurface(filename);
|
||||
}
|
||||
|
||||
if (index >= _subframes.getSize()) {
|
||||
_subframes.add(sub);
|
||||
} else {
|
||||
_subframes.insertAt(index, sub);
|
||||
}
|
||||
|
||||
stack->pushNative(sub, true);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GetEvent
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "GetSubframe") == 0) {
|
||||
stack->correctParams(1);
|
||||
int index = stack->pop()->getInt(-1);
|
||||
if (index < 0 || index >= _applyEvent.getSize()) {
|
||||
script->runtimeError("Frame.GetEvent: Event index %d is out of range.", index);
|
||||
stack->pushNULL();
|
||||
} else {
|
||||
stack->pushString(_applyEvent[index]);
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AddEvent
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "AddEvent") == 0) {
|
||||
stack->correctParams(1);
|
||||
const char *event = stack->pop()->getString();
|
||||
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
|
||||
if (scumm_stricmp(_applyEvent[i], event) == 0) {
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
}
|
||||
_applyEvent.add(event);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// DeleteEvent
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "DeleteEvent") == 0) {
|
||||
stack->correctParams(1);
|
||||
const char *event = stack->pop()->getString();
|
||||
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
|
||||
if (scumm_stricmp(_applyEvent[i], event) == 0) {
|
||||
delete[] _applyEvent[i];
|
||||
_applyEvent.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else {
|
||||
if (_subframes.getSize() == 1) {
|
||||
return _subframes[0]->scCallMethod(script, stack, thisStack, name);
|
||||
} else {
|
||||
return BaseScriptable::scCallMethod(script, stack, thisStack, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ScValue *BaseFrame::scGetProperty(const char *name) {
|
||||
if (!_scValue) {
|
||||
_scValue = new ScValue(_game);
|
||||
}
|
||||
_scValue->setNULL();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Type (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "Type") == 0) {
|
||||
_scValue->setString("frame");
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Delay
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Delay") == 0) {
|
||||
_scValue->setInt(_delay);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Keyframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Keyframe") == 0) {
|
||||
_scValue->setBool(_keyframe);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// KillSounds
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "KillSounds") == 0) {
|
||||
_scValue->setBool(_killSound);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MoveX
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "MoveX") == 0) {
|
||||
_scValue->setInt(_moveX);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MoveY
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "MoveY") == 0) {
|
||||
_scValue->setInt(_moveY);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// NumSubframes (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "NumSubframes") == 0) {
|
||||
_scValue->setInt(_subframes.getSize());
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// NumEvents (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "NumEvents") == 0) {
|
||||
_scValue->setInt(_applyEvent.getSize());
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else {
|
||||
if (_subframes.getSize() == 1) {
|
||||
return _subframes[0]->scGetProperty(name);
|
||||
} else {
|
||||
return BaseScriptable::scGetProperty(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseFrame::scSetProperty(const char *name, ScValue *value) {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Delay
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "Delay") == 0) {
|
||||
_delay = MAX(0, value->getInt());
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Keyframe
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Keyframe") == 0) {
|
||||
_keyframe = value->getBool();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// KillSounds
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "KillSounds") == 0) {
|
||||
_killSound = value->getBool();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MoveX
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "MoveX") == 0) {
|
||||
_moveX = value->getInt();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MoveY
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "MoveY") == 0) {
|
||||
_moveY = value->getInt();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else {
|
||||
if (_subframes.getSize() == 1) {
|
||||
return _subframes[0]->scSetProperty(name, value);
|
||||
} else {
|
||||
return BaseScriptable::scSetProperty(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const char *BaseFrame::scToString() {
|
||||
return "[frame]";
|
||||
}
|
||||
|
||||
Common::String BaseFrame::debuggerToString() const {
|
||||
return Common::String::format("%p: Frame \"%s\": #subframes %d ", (const void *)this, _name, _subframes.getSize());
|
||||
}
|
||||
} // End of namespace Wintermute
|
||||
Reference in New Issue
Block a user