aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/ad
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wintermute/ad')
-rw-r--r--engines/wintermute/ad/ad_actor.cpp2920
-rw-r--r--engines/wintermute/ad/ad_actor.h216
-rw-r--r--engines/wintermute/ad/ad_entity.cpp2242
-rw-r--r--engines/wintermute/ad/ad_entity.h136
-rw-r--r--engines/wintermute/ad/ad_game.cpp4560
-rw-r--r--engines/wintermute/ad/ad_game.h326
-rw-r--r--engines/wintermute/ad/ad_inventory.cpp272
-rw-r--r--engines/wintermute/ad/ad_inventory.h104
-rw-r--r--engines/wintermute/ad/ad_inventory_box.cpp776
-rw-r--r--engines/wintermute/ad/ad_inventory_box.h130
-rw-r--r--engines/wintermute/ad/ad_item.cpp1626
-rw-r--r--engines/wintermute/ad/ad_item.h138
-rw-r--r--engines/wintermute/ad/ad_layer.cpp1128
-rw-r--r--engines/wintermute/ad/ad_layer.h116
-rw-r--r--engines/wintermute/ad/ad_node_state.cpp392
-rw-r--r--engines/wintermute/ad/ad_node_state.h120
-rw-r--r--engines/wintermute/ad/ad_object.cpp2598
-rw-r--r--engines/wintermute/ad/ad_object.h248
-rw-r--r--engines/wintermute/ad/ad_path.cpp240
-rw-r--r--engines/wintermute/ad/ad_path.h112
-rw-r--r--engines/wintermute/ad/ad_path_point.cpp150
-rw-r--r--engines/wintermute/ad/ad_path_point.h100
-rw-r--r--engines/wintermute/ad/ad_region.cpp794
-rw-r--r--engines/wintermute/ad/ad_region.h116
-rw-r--r--engines/wintermute/ad/ad_response.cpp292
-rw-r--r--engines/wintermute/ad/ad_response.h122
-rw-r--r--engines/wintermute/ad/ad_response_box.cpp1424
-rw-r--r--engines/wintermute/ad/ad_response_box.h174
-rw-r--r--engines/wintermute/ad/ad_response_context.cpp142
-rw-r--r--engines/wintermute/ad/ad_response_context.h100
-rw-r--r--engines/wintermute/ad/ad_rot_level.cpp322
-rw-r--r--engines/wintermute/ad/ad_rot_level.h98
-rw-r--r--engines/wintermute/ad/ad_scale_level.cpp318
-rw-r--r--engines/wintermute/ad/ad_scale_level.h100
-rw-r--r--engines/wintermute/ad/ad_scene.cpp5972
-rw-r--r--engines/wintermute/ad/ad_scene.h362
-rw-r--r--engines/wintermute/ad/ad_scene_node.cpp164
-rw-r--r--engines/wintermute/ad/ad_scene_node.h108
-rw-r--r--engines/wintermute/ad/ad_scene_state.cpp190
-rw-r--r--engines/wintermute/ad/ad_scene_state.h102
-rw-r--r--engines/wintermute/ad/ad_sentence.cpp720
-rw-r--r--engines/wintermute/ad/ad_sentence.h170
-rw-r--r--engines/wintermute/ad/ad_sprite_set.cpp712
-rw-r--r--engines/wintermute/ad/ad_sprite_set.h106
-rw-r--r--engines/wintermute/ad/ad_talk_def.cpp570
-rw-r--r--engines/wintermute/ad/ad_talk_def.h116
-rw-r--r--engines/wintermute/ad/ad_talk_holder.cpp804
-rw-r--r--engines/wintermute/ad/ad_talk_holder.h114
-rw-r--r--engines/wintermute/ad/ad_talk_node.cpp590
-rw-r--r--engines/wintermute/ad/ad_talk_node.h126
-rw-r--r--engines/wintermute/ad/ad_types.h214
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.cpp540
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.h116
53 files changed, 17224 insertions, 17224 deletions
diff --git a/engines/wintermute/ad/ad_actor.cpp b/engines/wintermute/ad/ad_actor.cpp
index 63b1532416..9087d66844 100644
--- a/engines/wintermute/ad/ad_actor.cpp
+++ b/engines/wintermute/ad/ad_actor.cpp
@@ -1,1460 +1,1460 @@
-/* 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/ad/ad_actor.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_scene.h"
-#include "engines/wintermute/ad/ad_entity.h"
-#include "engines/wintermute/ad/ad_sprite_set.h"
-#include "engines/wintermute/ad/ad_waypoint_group.h"
-#include "engines/wintermute/ad/ad_path.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/base/base_region.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/particles/part_emitter.h"
-#include "engines/wintermute/base/base_engine.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdActor, false)
-
-
-//////////////////////////////////////////////////////////////////////////
-AdActor::AdActor(BaseGame *inGame) : AdTalkHolder(inGame) {
- _path = new AdPath(_gameRef);
-
- _type = OBJECT_ACTOR;
- _dir = DI_LEFT;
-
- _walkSprite = NULL;
- _standSprite = NULL;
- _turnLeftSprite = NULL;
- _turnRightSprite = NULL;
-
- _targetPoint = new BasePoint;
- _afterWalkDir = DI_NONE;
-
- _animSprite2 = NULL;
-
- setDefaultAnimNames();
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::setDefaultAnimNames() {
- _talkAnimName = "talk";
- _idleAnimName = "idle";
- _walkAnimName = "walk";
- _turnLeftAnimName = "turnleft";
- _turnRightAnimName = "turnright";
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-AdActor::~AdActor() {
- delete _path;
- delete _targetPoint;
- _path = NULL;
- _targetPoint = NULL;
-
- delete _walkSprite;
- delete _standSprite;
- delete _turnLeftSprite;
- delete _turnRightSprite;
- _walkSprite = NULL;
- _standSprite = NULL;
- _turnLeftSprite = NULL;
- _turnRightSprite = NULL;
-
- _animSprite2 = NULL; // ref only
-
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- delete _talkSprites[i];
- }
- _talkSprites.clear();
-
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- delete _talkSpritesEx[i];
- }
- _talkSpritesEx.clear();
-
- for (uint32 i = 0; i < _anims.size(); i++) {
- delete _anims[i];
- _anims[i] = NULL;
- }
- _anims.clear();
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdActor::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing ACTOR file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(ACTOR)
-TOKEN_DEF(X)
-TOKEN_DEF(Y)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(SCALABLE)
-TOKEN_DEF(REGISTRABLE)
-TOKEN_DEF(INTERACTIVE)
-TOKEN_DEF(SHADOWABLE)
-TOKEN_DEF(COLORABLE)
-TOKEN_DEF(ACTIVE)
-TOKEN_DEF(WALK)
-TOKEN_DEF(STAND)
-TOKEN_DEF(TALK_SPECIAL)
-TOKEN_DEF(TALK)
-TOKEN_DEF(TURN_LEFT)
-TOKEN_DEF(TURN_RIGHT)
-TOKEN_DEF(EVENTS)
-TOKEN_DEF(FONT)
-TOKEN_DEF(CURSOR)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(SOUND_VOLUME)
-TOKEN_DEF(SOUND_PANNING)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(BLOCKED_REGION)
-TOKEN_DEF(WAYPOINTS)
-TOKEN_DEF(IGNORE_ITEMS)
-TOKEN_DEF(ROTABLE)
-TOKEN_DEF(ROTATABLE)
-TOKEN_DEF(ALPHA_COLOR)
-TOKEN_DEF(SCALE)
-TOKEN_DEF(RELATIVE_SCALE)
-TOKEN_DEF(ALPHA)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF(ANIMATION)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ACTOR)
- TOKEN_TABLE(X)
- TOKEN_TABLE(Y)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(SCALABLE)
- TOKEN_TABLE(REGISTRABLE)
- TOKEN_TABLE(INTERACTIVE)
- TOKEN_TABLE(SHADOWABLE)
- TOKEN_TABLE(COLORABLE)
- TOKEN_TABLE(ACTIVE)
- TOKEN_TABLE(WALK)
- TOKEN_TABLE(STAND)
- TOKEN_TABLE(TALK_SPECIAL)
- TOKEN_TABLE(TALK)
- TOKEN_TABLE(TURN_LEFT)
- TOKEN_TABLE(TURN_RIGHT)
- TOKEN_TABLE(EVENTS)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(CURSOR)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(SOUND_VOLUME)
- TOKEN_TABLE(SOUND_PANNING)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(BLOCKED_REGION)
- TOKEN_TABLE(WAYPOINTS)
- TOKEN_TABLE(IGNORE_ITEMS)
- TOKEN_TABLE(ROTABLE)
- TOKEN_TABLE(ROTATABLE)
- TOKEN_TABLE(ALPHA_COLOR)
- TOKEN_TABLE(SCALE)
- TOKEN_TABLE(RELATIVE_SCALE)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE(ANIMATION)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTOR) {
- _gameRef->LOG(0, "'ACTOR' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- AdGame *adGame = (AdGame *)_gameRef;
- AdSpriteSet *spr = NULL;
- int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
- break;
-
- case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_FONT:
- setFont((char *)params);
- break;
-
- case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
- break;
-
- case TOKEN_ROTABLE:
- case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
- break;
-
- case TOKEN_REGISTRABLE:
- case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
- break;
-
- case TOKEN_SHADOWABLE:
- case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
- break;
-
- case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
- break;
-
- case TOKEN_WALK:
- delete _walkSprite;
- _walkSprite = NULL;
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texWalkLifeTime, CACHE_HALF))) {
- cmd = PARSERR_GENERIC;
- } else {
- _walkSprite = spr;
- }
- break;
-
- case TOKEN_TALK:
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSprites.add(spr);
- }
- break;
-
- case TOKEN_TALK_SPECIAL:
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSpritesEx.add(spr);
- }
- break;
-
- case TOKEN_STAND:
- delete _standSprite;
- _standSprite = NULL;
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texStandLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _standSprite = spr;
- }
- break;
-
- case TOKEN_TURN_LEFT:
- delete _turnLeftSprite;
- _turnLeftSprite = NULL;
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true))) {
- cmd = PARSERR_GENERIC;
- } else {
- _turnLeftSprite = spr;
- }
- break;
-
- case TOKEN_TURN_RIGHT:
- delete _turnRightSprite;
- _turnRightSprite = NULL;
- spr = new AdSpriteSet(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadBuffer(params, true))) {
- cmd = PARSERR_GENERIC;
- } else {
- _turnRightSprite = spr;
- }
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_CURSOR:
- delete _cursor;
- _cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
- delete _cursor;
- _cursor = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
- break;
-
- case TOKEN_SCALE: {
- int s;
- parser.scanStr((char *)params, "%d", &s);
- _scale = (float)s;
-
- }
- break;
-
- case TOKEN_RELATIVE_SCALE: {
- int s;
- parser.scanStr((char *)params, "%d", &s);
- _relativeScale = (float)s;
-
- }
- break;
-
- case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_BLOCKED_REGION: {
- delete _blockRegion;
- delete _currentBlockRegion;
- _blockRegion = NULL;
- _currentBlockRegion = NULL;
- BaseRegion *rgn = new BaseRegion(_gameRef);
- BaseRegion *crgn = new BaseRegion(_gameRef);
- if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) {
- delete _blockRegion;
- delete _currentBlockRegion;
- _blockRegion = NULL;
- _currentBlockRegion = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- _blockRegion = rgn;
- _currentBlockRegion = crgn;
- _currentBlockRegion->mimic(_blockRegion);
- }
- }
- break;
-
- case TOKEN_WAYPOINTS: {
- delete _wptGroup;
- delete _currentWptGroup;
- _wptGroup = NULL;
- _currentWptGroup = NULL;
- AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
- AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef);
- if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) {
- delete _wptGroup;
- delete _currentWptGroup;
- _wptGroup = NULL;
- _currentWptGroup = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- _wptGroup = wpt;
- _currentWptGroup = cwpt;
- _currentWptGroup->mimic(_wptGroup);
- }
- }
- break;
-
- case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
- break;
-
- case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
- break;
-
- case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
-
- case TOKEN_ANIMATION: {
- AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
- if (!anim || DID_FAIL(anim->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- } else {
- _anims.add(anim);
- }
- }
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ACTOR definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- if (spr) {
- delete spr;
- }
- _gameRef->LOG(0, "Error loading ACTOR definition");
- return STATUS_FAILED;
- }
-
- if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
- ar = ag = ab = 255;
- }
- _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
- _state = _nextState = STATE_READY;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdActor::turnTo(TDirection dir) {
- int delta1, delta2, delta3, delta;
-
- delta1 = dir - _dir;
- delta2 = dir + NUM_DIRECTIONS - _dir;
- delta3 = dir - NUM_DIRECTIONS - _dir;
-
- delta1 = (abs(delta1) <= abs(delta2)) ? delta1 : delta2;
- delta = (abs(delta1) <= abs(delta3)) ? delta1 : delta3;
-
- // already there?
- if (abs(delta) < 2) {
- _dir = dir;
- _state = _nextState;
- _nextState = STATE_READY;
- return;
- }
-
- _targetDir = dir;
- _state = delta < 0 ? STATE_TURNING_LEFT : STATE_TURNING_RIGHT;
-
- _tempSprite2 = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdActor::goTo(int x, int y, TDirection afterWalkDir) {
- _afterWalkDir = afterWalkDir;
- if (x == _targetPoint->x && y == _targetPoint->y && _state == STATE_FOLLOWING_PATH) {
- return;
- }
-
- _path->reset();
- _path->setReady(false);
-
- _targetPoint->x = x;
- _targetPoint->y = y;
-
- ((AdGame *)_gameRef)->_scene->correctTargetPoint(_posX, _posY, &_targetPoint->x, &_targetPoint->y, true, this);
-
- _state = STATE_SEARCHING_PATH;
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::display() {
- if (_active) {
- updateSounds();
- }
-
- uint32 alpha;
- if (_alphaColor != 0) {
- alpha = _alphaColor;
- } else {
- alpha = _shadowable ? ((AdGame *)_gameRef)->_scene->getAlphaAt(_posX, _posY, true) : 0xFFFFFFFF;
- }
-
- float scaleX, scaleY;
- getScale(&scaleX, &scaleY);
-
-
- float rotate;
- if (_rotatable) {
- if (_rotateValid) {
- rotate = _rotate;
- } else {
- rotate = ((AdGame *)_gameRef)->_scene->getRotationAt(_posX, _posY) + _relativeRotate;
- }
- } else {
- rotate = 0.0f;
- }
-
- if (_active) {
- displaySpriteAttachments(true);
- }
-
- if (_currentSprite && _active) {
- bool reg = _registrable;
- if (_ignoreItems && ((AdGame *)_gameRef)->_selectedItem) {
- reg = false;
- }
-
- _currentSprite->display(_posX,
- _posY,
- reg ? _registerAlias : NULL,
- scaleX,
- scaleY,
- alpha,
- rotate,
- _blendMode);
-
- }
-
- if (_active) {
- displaySpriteAttachments(false);
- }
- if (_active && _partEmitter) {
- _partEmitter->display();
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::update() {
- _currentSprite = NULL;
-
- if (_state == STATE_READY) {
- if (_animSprite) {
- delete _animSprite;
- _animSprite = NULL;
- }
- if (_animSprite2) {
- _animSprite2 = NULL;
- }
- }
-
- // finished playing animation?
- if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
- _state = _nextState;
- _nextState = STATE_READY;
- _currentSprite = _animSprite;
- }
-
- if (_state == STATE_PLAYING_ANIM_SET && _animSprite2 != NULL && _animSprite2->_finished) {
- _state = _nextState;
- _nextState = STATE_READY;
- _currentSprite = _animSprite2;
- }
-
- if (_sentence && _state != STATE_TALKING) {
- _sentence->finish();
- }
-
- // default: stand animation
- if (!_currentSprite) {
- if (_sprite) {
- _currentSprite = _sprite;
- } else {
- if (_standSprite) {
- _currentSprite = _standSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_idleAnimName);
- if (anim) {
- _currentSprite = anim->getSprite(_dir);
- }
- }
- }
- }
-
- bool already_moved = false;
-
- switch (_state) {
- //////////////////////////////////////////////////////////////////////////
- case STATE_PLAYING_ANIM:
- _currentSprite = _animSprite;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_PLAYING_ANIM_SET:
- _currentSprite = _animSprite2;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_TURNING_LEFT:
- if (_tempSprite2 == NULL || _tempSprite2->_finished) {
- if (_dir > 0) {
- _dir = (TDirection)(_dir - 1);
- } else {
- _dir = (TDirection)(NUM_DIRECTIONS - 1);
- }
-
- if (_dir == _targetDir) {
- _tempSprite2 = NULL;
- _state = _nextState;
- _nextState = STATE_READY;
- } else {
- if (_turnLeftSprite) {
- _tempSprite2 = _turnLeftSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_turnLeftAnimName);
- if (anim) {
- _tempSprite2 = anim->getSprite(_dir);
- }
- }
-
- if (_tempSprite2) {
- _tempSprite2->reset();
- if (_tempSprite2->_looping) {
- _tempSprite2->_looping = false;
- }
- }
- _currentSprite = _tempSprite2;
- }
- } else {
- _currentSprite = _tempSprite2;
- }
- break;
-
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_TURNING_RIGHT:
- if (_tempSprite2 == NULL || _tempSprite2->_finished) {
- _dir = (TDirection)(_dir + 1);
-
- if ((int)_dir >= (int)NUM_DIRECTIONS) {
- _dir = (TDirection)(0);
- }
-
- if (_dir == _targetDir) {
- _tempSprite2 = NULL;
- _state = _nextState;
- _nextState = STATE_READY;
- } else {
- if (_turnRightSprite) {
- _tempSprite2 = _turnRightSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_turnRightAnimName);
- if (anim) {
- _tempSprite2 = anim->getSprite(_dir);
- }
- }
-
- if (_tempSprite2) {
- _tempSprite2->reset();
- if (_tempSprite2->_looping) {
- _tempSprite2->_looping = false;
- }
- }
- _currentSprite = _tempSprite2;
- }
- } else {
- _currentSprite = _tempSprite2;
- }
- break;
-
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_SEARCHING_PATH:
- // keep asking scene for the path
- if (((AdGame *)_gameRef)->_scene->getPath(BasePoint(_posX, _posY), *_targetPoint, _path, this)) {
- _state = STATE_WAITING_PATH;
- }
- break;
-
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_WAITING_PATH:
- // wait until the scene finished the path
- if (_path->_ready) {
- followPath();
- }
- break;
-
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_FOLLOWING_PATH:
- getNextStep();
- already_moved = true;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_TALKING: {
- _sentence->update(_dir);
- if (_sentence->_currentSprite) {
- _tempSprite2 = _sentence->_currentSprite;
- }
-
- bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
- if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
- if (timeIsUp) {
- _sentence->finish();
- _tempSprite2 = NULL;
- _state = _nextState;
- _nextState = STATE_READY;
- } else {
- _tempSprite2 = getTalkStance(_sentence->getNextStance());
- if (_tempSprite2) {
- _tempSprite2->reset();
- _currentSprite = _tempSprite2;
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- }
- } else {
- _currentSprite = _tempSprite2;
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- }
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_READY:
- if (!_animSprite && !_animSprite2) {
- if (_sprite) {
- _currentSprite = _sprite;
- } else {
- if (_standSprite) {
- _currentSprite = _standSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_idleAnimName);
- if (anim) {
- _currentSprite = anim->getSprite(_dir);
- }
- }
- }
- }
- break;
- default:
- error("AdActor::Update - Unhandled enum");
- }
-
-
- if (_currentSprite && !already_moved) {
- _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100, _zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
- if (_currentSprite->_changed) {
- _posX += _currentSprite->_moveX;
- _posY += _currentSprite->_moveY;
- afterMove();
- }
- }
-
- //_gameRef->QuickMessageForm("%s", _currentSprite->_filename);
-
- updateBlockRegion();
- _ready = (_state == STATE_READY);
-
- updatePartEmitter();
- updateSpriteAttachments();
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdActor::followPath() {
- // skip current position
- _path->getFirst();
- while (_path->getCurrent() != NULL) {
- if (_path->getCurrent()->x != _posX || _path->getCurrent()->y != _posY) {
- break;
- }
- _path->getNext();
- }
-
- // are there points to follow?
- if (_path->getCurrent() != NULL) {
- _state = STATE_FOLLOWING_PATH;;
- initLine(BasePoint(_posX, _posY), *_path->getCurrent());
- } else {
- if (_afterWalkDir != DI_NONE) {
- turnTo(_afterWalkDir);
- } else {
- _state = STATE_READY;
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdActor::getNextStep() {
- if (_walkSprite) {
- _currentSprite = _walkSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_walkAnimName);
- if (anim) {
- _currentSprite = anim->getSprite(_dir);
- }
- }
-
- if (!_currentSprite) {
- return;
- }
-
- _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100, _zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
- if (!_currentSprite->_changed) {
- return;
- }
-
-
- int maxStepX, maxStepY;
- maxStepX = abs(_currentSprite->_moveX);
- maxStepY = abs(_currentSprite->_moveY);
-
- maxStepX = MAX(maxStepX, maxStepY);
- maxStepX = MAX(maxStepX, 1);
-
- while (_pFCount > 0 && maxStepX >= 0) {
- _pFX += _pFStepX;
- _pFY += _pFStepY;
-
- _pFCount--;
- maxStepX--;
- }
-
- if (((AdGame *)_gameRef)->_scene->isBlockedAt((int)_pFX, (int) _pFY, true, this)) {
- if (_pFCount == 0) {
- _state = _nextState;
- _nextState = STATE_READY;
- return;
- }
- goTo(_targetPoint->x, _targetPoint->y);
- return;
- }
-
-
- _posX = (int)_pFX;
- _posY = (int)_pFY;
-
- afterMove();
-
-
- if (_pFCount == 0) {
- if (_path->getNext() == NULL) {
- _posX = _targetPoint->x;
- _posY = _targetPoint->y;
-
- _path->reset();
- if (_afterWalkDir != DI_NONE) {
- turnTo(_afterWalkDir);
- } else {
- _state = _nextState;
- _nextState = STATE_READY;
- }
- } else {
- initLine(BasePoint(_posX, _posY), *_path->getCurrent());
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdActor::initLine(BasePoint startPt, BasePoint endPt) {
- _pFCount = MAX((abs(endPt.x - startPt.x)) , (abs(endPt.y - startPt.y)));
-
- _pFStepX = (double)(endPt.x - startPt.x) / _pFCount;
- _pFStepY = (double)(endPt.y - startPt.y) / _pFCount;
-
- _pFX = startPt.x;
- _pFY = startPt.y;
-
- int angle = (int)(atan2((double)(endPt.y - startPt.y), (double)(endPt.x - startPt.x)) * (180 / 3.14));
-
- _nextState = STATE_FOLLOWING_PATH;
-
- turnTo(angleToDirection(angle));
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // GoTo / GoToAsync
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "GoTo") == 0 || strcmp(name, "GoToAsync") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
- goTo(x, y);
- if (strcmp(name, "GoToAsync") != 0) {
- script->waitForExclusive(this);
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GoToObject / GoToObjectAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GoToObject") == 0 || strcmp(name, "GoToObjectAsync") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- if (!val->isNative()) {
- script->runtimeError("actor.%s method accepts an entity refrence only", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- AdObject *obj = (AdObject *)val->getNative();
- if (!obj || obj->_type != OBJECT_ENTITY) {
- script->runtimeError("actor.%s method accepts an entity refrence only", name);
- stack->pushNULL();
- return STATUS_OK;
- }
- AdEntity *ent = (AdEntity *)obj;
- if (ent->_walkToX == 0 && ent->_walkToY == 0) {
- goTo(ent->_posX, ent->_posY);
- } else {
- goTo(ent->_walkToX, ent->_walkToY, ent->_walkToDir);
- }
- if (strcmp(name, "GoToObjectAsync") != 0) {
- script->waitForExclusive(this);
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TurnTo / TurnToAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TurnTo") == 0 || strcmp(name, "TurnToAsync") == 0) {
- stack->correctParams(1);
- int dir;
- ScValue *val = stack->pop();
-
- // turn to object?
- if (val->isNative() && _gameRef->validObject((BaseObject *)val->getNative())) {
- BaseObject *obj = (BaseObject *)val->getNative();
- int angle = (int)(atan2((double)(obj->_posY - _posY), (double)(obj->_posX - _posX)) * (180 / 3.14));
- dir = (int)angleToDirection(angle);
- }
- // otherwise turn to direction
- else {
- dir = val->getInt();
- }
-
- if (dir >= 0 && dir < NUM_DIRECTIONS) {
- turnTo((TDirection)dir);
- if (strcmp(name, "TurnToAsync") != 0) {
- script->waitForExclusive(this);
- }
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsWalking
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsWalking") == 0) {
- stack->correctParams(0);
- stack->pushBool(_state == STATE_FOLLOWING_PATH);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // MergeAnims
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "MergeAnims") == 0) {
- stack->correctParams(1);
- stack->pushBool(DID_SUCCEED(mergeAnims(stack->pop()->getString())));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // UnloadAnim
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "UnloadAnim") == 0) {
- stack->correctParams(1);
- const char *animName = stack->pop()->getString();
-
- bool found = false;
- for (uint32 i = 0; i < _anims.size(); i++) {
- if (scumm_stricmp(_anims[i]->getName(), animName) == 0) {
- // invalidate sprites in use
- if (_anims[i]->containsSprite(_tempSprite2)) {
- _tempSprite2 = NULL;
- }
- if (_anims[i]->containsSprite(_currentSprite)) {
- _currentSprite = NULL;
- }
- if (_anims[i]->containsSprite(_animSprite2)) {
- _animSprite2 = NULL;
- }
-
- delete _anims[i];
- _anims[i] = NULL;
- _anims.remove_at(i);
- i--;
- found = true;
- }
- }
- stack->pushBool(found);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // HasAnim
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "HasAnim") == 0) {
- stack->correctParams(1);
- const char *animName = stack->pop()->getString();
- stack->pushBool(getAnimByName(animName) != NULL);
- return STATUS_OK;
- } else {
- return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdActor::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Direction
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Direction") == 0) {
- _scValue->setInt(_dir);
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Type") == 0) {
- _scValue->setString("actor");
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // TalkAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TalkAnimName") == 0) {
- _scValue->setString(_talkAnimName);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkAnimName") == 0) {
- _scValue->setString(_walkAnimName);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IdleAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IdleAnimName") == 0) {
- _scValue->setString(_idleAnimName);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TurnLeftAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TurnLeftAnimName") == 0) {
- _scValue->setString(_turnLeftAnimName);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TurnRightAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TurnRightAnimName") == 0) {
- _scValue->setString(_turnRightAnimName);
- return _scValue;
- } else {
- return AdTalkHolder::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Direction
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Direction") == 0) {
- int dir = value->getInt();
- if (dir >= 0 && dir < NUM_DIRECTIONS) {
- _dir = (TDirection)dir;
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TalkAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TalkAnimName") == 0) {
- if (value->isNULL()) {
- _talkAnimName = "talk";
- } else {
- _talkAnimName = value->getString();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkAnimName") == 0) {
- if (value->isNULL()) {
- _walkAnimName = "walk";
- } else {
- _walkAnimName = value->getString();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IdleAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IdleAnimName") == 0) {
- if (value->isNULL()) {
- _idleAnimName = "idle";
- } else {
- _idleAnimName = value->getString();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TurnLeftAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TurnLeftAnimName") == 0) {
- if (value->isNULL()) {
- _turnLeftAnimName = "turnleft";
- } else {
- _turnLeftAnimName = value->getString();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TurnRightAnimName
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TurnRightAnimName") == 0) {
- if (value->isNULL()) {
- _turnRightAnimName = "turnright";
- } else {
- _turnRightAnimName = value->getString();
- }
- return STATUS_OK;
- } else {
- return AdTalkHolder::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdActor::scToString() {
- return "[actor object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdActor::getTalkStance(const char *stance) {
- // forced stance?
- if (_forcedTalkAnimName && !_forcedTalkAnimUsed) {
- _forcedTalkAnimUsed = true;
- delete _animSprite;
- _animSprite = new BaseSprite(_gameRef, this);
- if (_animSprite) {
- bool res = _animSprite->loadFile(_forcedTalkAnimName);
- if (DID_FAIL(res)) {
- _gameRef->LOG(res, "AdActor::GetTalkStance: error loading talk sprite (object:\"%s\" sprite:\"%s\")", getName(), _forcedTalkAnimName);
- delete _animSprite;
- _animSprite = NULL;
- } else {
- return _animSprite;
- }
- }
- }
-
- // old way
- if (_talkSprites.size() > 0 || _talkSpritesEx.size() > 0) {
- return getTalkStanceOld(stance);
- }
-
- // new way
- BaseSprite *ret = NULL;
-
- // do we have an animation with this name?
- AdSpriteSet *anim = getAnimByName(stance);
- if (anim) {
- ret = anim->getSprite(_dir);
- }
-
- // not - get a random talk
- if (!ret) {
- BaseArray<AdSpriteSet *> talkAnims;
- for (uint32 i = 0; i < _anims.size(); i++) {
- if (_talkAnimName.compareToIgnoreCase(_anims[i]->getName()) == 0) {
- talkAnims.add(_anims[i]);
- }
- }
-
- if (talkAnims.size() > 0) {
- int rnd = BaseEngine::instance().randInt(0, talkAnims.size() - 1);
- ret = talkAnims[rnd]->getSprite(_dir);
- } else {
- if (_standSprite) {
- ret = _standSprite->getSprite(_dir);
- } else {
- anim = getAnimByName(_idleAnimName);
- if (anim) {
- ret = anim->getSprite(_dir);
- }
- }
- }
- }
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdActor::getTalkStanceOld(const char *stance) {
- BaseSprite *ret = NULL;
-
- if (stance != NULL) {
- // search special stances
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- if (scumm_stricmp(_talkSpritesEx[i]->getName(), stance) == 0) {
- ret = _talkSpritesEx[i]->getSprite(_dir);
- break;
- }
- }
- if (ret == NULL) {
- // search generic stances
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- if (scumm_stricmp(_talkSprites[i]->getName(), stance) == 0) {
- ret = _talkSprites[i]->getSprite(_dir);
- break;
- }
- }
- }
- }
-
- // not a valid stance? get a random one
- if (ret == NULL) {
- if (_talkSprites.size() < 1) {
- ret = _standSprite->getSprite(_dir);
- } else {
- // TODO: remember last
- int rnd = BaseEngine::instance().randInt(0, _talkSprites.size() - 1);
- ret = _talkSprites[rnd]->getSprite(_dir);
- }
- }
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::persist(BasePersistenceManager *persistMgr) {
- AdTalkHolder::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER_INT(_dir));
- persistMgr->transfer(TMEMBER(_path));
- persistMgr->transfer(TMEMBER(_pFCount));
- persistMgr->transfer(TMEMBER(_pFStepX));
- persistMgr->transfer(TMEMBER(_pFStepY));
- persistMgr->transfer(TMEMBER(_pFX));
- persistMgr->transfer(TMEMBER(_pFY));
- persistMgr->transfer(TMEMBER(_standSprite));
- _talkSprites.persist(persistMgr);
- _talkSpritesEx.persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_targetDir));
- persistMgr->transfer(TMEMBER_INT(_afterWalkDir));
- persistMgr->transfer(TMEMBER(_targetPoint));
- persistMgr->transfer(TMEMBER(_turnLeftSprite));
- persistMgr->transfer(TMEMBER(_turnRightSprite));
- persistMgr->transfer(TMEMBER(_walkSprite));
-
- persistMgr->transfer(TMEMBER(_animSprite2));
- persistMgr->transfer(TMEMBER(_talkAnimName));
- persistMgr->transfer(TMEMBER(_idleAnimName));
- persistMgr->transfer(TMEMBER(_walkAnimName));
- persistMgr->transfer(TMEMBER(_turnLeftAnimName));
- persistMgr->transfer(TMEMBER(_turnRightAnimName));
-
- _anims.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-TDirection AdActor::angleToDirection(int angle) {
- TDirection ret = DI_DOWN;;
-
- if (angle > -112 && angle <= -67) {
- ret = DI_UP;
- } else if (angle > -67 && angle <= -22) {
- ret = DI_UPRIGHT;
- } else if (angle > -22 && angle <= 22) {
- ret = DI_RIGHT;
- } else if (angle > 22 && angle <= 67) {
- ret = DI_DOWNRIGHT;
- } else if (angle > 67 && angle <= 112) {
- ret = DI_DOWN;
- } else if (angle > 112 && angle <= 157) {
- ret = DI_DOWNLEFT;
- } else if ((angle > 157 && angle <= 180) || (angle >= -180 && angle <= -157)) {
- ret = DI_LEFT;
- } else if (angle > -157 && angle <= -112) {
- ret = DI_UPLEFT;
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdActor::getHeight() {
- // if no current sprite is set, set some
- if (_currentSprite == NULL) {
- if (_standSprite) {
- _currentSprite = _standSprite->getSprite(_dir);
- } else {
- AdSpriteSet *anim = getAnimByName(_idleAnimName);
- if (anim) {
- _currentSprite = anim->getSprite(_dir);
- }
- }
- }
- // and get height
- return AdTalkHolder::getHeight();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSpriteSet *AdActor::getAnimByName(const Common::String &animName) {
- for (uint32 i = 0; i < _anims.size(); i++) {
- if (animName.compareToIgnoreCase(_anims[i]->getName()) == 0) {
- return _anims[i];
- }
- }
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::mergeAnims(const char *animsFilename) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ANIMATION)
- TOKEN_TABLE_END
-
-
- byte *fileBuffer = BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
- if (fileBuffer == NULL) {
- _gameRef->LOG(0, "AdActor::MergeAnims failed for file '%s'", animsFilename);
- return STATUS_FAILED;
- }
-
- byte *buffer = fileBuffer;
- byte *params;
- int cmd;
- BaseParser parser;
-
- bool ret = STATUS_OK;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_ANIMATION: {
- AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
- if (!anim || DID_FAIL(anim->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- ret = STATUS_FAILED;
- } else {
- _anims.add(anim);
- }
- }
- break;
- }
- }
- delete[] fileBuffer;
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdActor::playAnim(const char *filename) {
- // if we have an anim with this name, use it
- AdSpriteSet *anim = getAnimByName(filename);
- if (anim) {
- _animSprite2 = anim->getSprite(_dir);
- if (_animSprite2) {
- _animSprite2->reset();
- _state = STATE_PLAYING_ANIM_SET;
- return STATUS_OK;
- }
- }
- // otherwise call the standard handler
- return AdTalkHolder::playAnim(filename);
-}
-
-} // 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/ad/ad_actor.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_scene.h"
+#include "engines/wintermute/ad/ad_entity.h"
+#include "engines/wintermute/ad/ad_sprite_set.h"
+#include "engines/wintermute/ad/ad_waypoint_group.h"
+#include "engines/wintermute/ad/ad_path.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/base/base_region.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/particles/part_emitter.h"
+#include "engines/wintermute/base/base_engine.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdActor, false)
+
+
+//////////////////////////////////////////////////////////////////////////
+AdActor::AdActor(BaseGame *inGame) : AdTalkHolder(inGame) {
+ _path = new AdPath(_gameRef);
+
+ _type = OBJECT_ACTOR;
+ _dir = DI_LEFT;
+
+ _walkSprite = NULL;
+ _standSprite = NULL;
+ _turnLeftSprite = NULL;
+ _turnRightSprite = NULL;
+
+ _targetPoint = new BasePoint;
+ _afterWalkDir = DI_NONE;
+
+ _animSprite2 = NULL;
+
+ setDefaultAnimNames();
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::setDefaultAnimNames() {
+ _talkAnimName = "talk";
+ _idleAnimName = "idle";
+ _walkAnimName = "walk";
+ _turnLeftAnimName = "turnleft";
+ _turnRightAnimName = "turnright";
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AdActor::~AdActor() {
+ delete _path;
+ delete _targetPoint;
+ _path = NULL;
+ _targetPoint = NULL;
+
+ delete _walkSprite;
+ delete _standSprite;
+ delete _turnLeftSprite;
+ delete _turnRightSprite;
+ _walkSprite = NULL;
+ _standSprite = NULL;
+ _turnLeftSprite = NULL;
+ _turnRightSprite = NULL;
+
+ _animSprite2 = NULL; // ref only
+
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ delete _talkSprites[i];
+ }
+ _talkSprites.clear();
+
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ delete _talkSpritesEx[i];
+ }
+ _talkSpritesEx.clear();
+
+ for (uint32 i = 0; i < _anims.size(); i++) {
+ delete _anims[i];
+ _anims[i] = NULL;
+ }
+ _anims.clear();
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdActor::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing ACTOR file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(ACTOR)
+TOKEN_DEF(X)
+TOKEN_DEF(Y)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(SCALABLE)
+TOKEN_DEF(REGISTRABLE)
+TOKEN_DEF(INTERACTIVE)
+TOKEN_DEF(SHADOWABLE)
+TOKEN_DEF(COLORABLE)
+TOKEN_DEF(ACTIVE)
+TOKEN_DEF(WALK)
+TOKEN_DEF(STAND)
+TOKEN_DEF(TALK_SPECIAL)
+TOKEN_DEF(TALK)
+TOKEN_DEF(TURN_LEFT)
+TOKEN_DEF(TURN_RIGHT)
+TOKEN_DEF(EVENTS)
+TOKEN_DEF(FONT)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(SOUND_VOLUME)
+TOKEN_DEF(SOUND_PANNING)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(BLOCKED_REGION)
+TOKEN_DEF(WAYPOINTS)
+TOKEN_DEF(IGNORE_ITEMS)
+TOKEN_DEF(ROTABLE)
+TOKEN_DEF(ROTATABLE)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(SCALE)
+TOKEN_DEF(RELATIVE_SCALE)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(ANIMATION)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ACTOR)
+ TOKEN_TABLE(X)
+ TOKEN_TABLE(Y)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(SCALABLE)
+ TOKEN_TABLE(REGISTRABLE)
+ TOKEN_TABLE(INTERACTIVE)
+ TOKEN_TABLE(SHADOWABLE)
+ TOKEN_TABLE(COLORABLE)
+ TOKEN_TABLE(ACTIVE)
+ TOKEN_TABLE(WALK)
+ TOKEN_TABLE(STAND)
+ TOKEN_TABLE(TALK_SPECIAL)
+ TOKEN_TABLE(TALK)
+ TOKEN_TABLE(TURN_LEFT)
+ TOKEN_TABLE(TURN_RIGHT)
+ TOKEN_TABLE(EVENTS)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(SOUND_VOLUME)
+ TOKEN_TABLE(SOUND_PANNING)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(BLOCKED_REGION)
+ TOKEN_TABLE(WAYPOINTS)
+ TOKEN_TABLE(IGNORE_ITEMS)
+ TOKEN_TABLE(ROTABLE)
+ TOKEN_TABLE(ROTATABLE)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(SCALE)
+ TOKEN_TABLE(RELATIVE_SCALE)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(ANIMATION)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTOR) {
+ _gameRef->LOG(0, "'ACTOR' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ AdGame *adGame = (AdGame *)_gameRef;
+ AdSpriteSet *spr = NULL;
+ int ar = 0, ag = 0, ab = 0, alpha = 0;
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_X:
+ parser.scanStr((char *)params, "%d", &_posX);
+ break;
+
+ case TOKEN_Y:
+ parser.scanStr((char *)params, "%d", &_posY);
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_FONT:
+ setFont((char *)params);
+ break;
+
+ case TOKEN_SCALABLE:
+ parser.scanStr((char *)params, "%b", &_zoomable);
+ break;
+
+ case TOKEN_ROTABLE:
+ case TOKEN_ROTATABLE:
+ parser.scanStr((char *)params, "%b", &_rotatable);
+ break;
+
+ case TOKEN_REGISTRABLE:
+ case TOKEN_INTERACTIVE:
+ parser.scanStr((char *)params, "%b", &_registrable);
+ break;
+
+ case TOKEN_SHADOWABLE:
+ case TOKEN_COLORABLE:
+ parser.scanStr((char *)params, "%b", &_shadowable);
+ break;
+
+ case TOKEN_ACTIVE:
+ parser.scanStr((char *)params, "%b", &_active);
+ break;
+
+ case TOKEN_WALK:
+ delete _walkSprite;
+ _walkSprite = NULL;
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texWalkLifeTime, CACHE_HALF))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _walkSprite = spr;
+ }
+ break;
+
+ case TOKEN_TALK:
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSprites.add(spr);
+ }
+ break;
+
+ case TOKEN_TALK_SPECIAL:
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSpritesEx.add(spr);
+ }
+ break;
+
+ case TOKEN_STAND:
+ delete _standSprite;
+ _standSprite = NULL;
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texStandLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _standSprite = spr;
+ }
+ break;
+
+ case TOKEN_TURN_LEFT:
+ delete _turnLeftSprite;
+ _turnLeftSprite = NULL;
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _turnLeftSprite = spr;
+ }
+ break;
+
+ case TOKEN_TURN_RIGHT:
+ delete _turnRightSprite;
+ _turnRightSprite = NULL;
+ spr = new AdSpriteSet(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadBuffer(params, true))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _turnRightSprite = spr;
+ }
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_CURSOR:
+ delete _cursor;
+ _cursor = new BaseSprite(_gameRef);
+ if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ delete _cursor;
+ _cursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_SOUND_VOLUME:
+ parser.scanStr((char *)params, "%d", &_sFXVolume);
+ break;
+
+ case TOKEN_SCALE: {
+ int s;
+ parser.scanStr((char *)params, "%d", &s);
+ _scale = (float)s;
+
+ }
+ break;
+
+ case TOKEN_RELATIVE_SCALE: {
+ int s;
+ parser.scanStr((char *)params, "%d", &s);
+ _relativeScale = (float)s;
+
+ }
+ break;
+
+ case TOKEN_SOUND_PANNING:
+ parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_BLOCKED_REGION: {
+ delete _blockRegion;
+ delete _currentBlockRegion;
+ _blockRegion = NULL;
+ _currentBlockRegion = NULL;
+ BaseRegion *rgn = new BaseRegion(_gameRef);
+ BaseRegion *crgn = new BaseRegion(_gameRef);
+ if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) {
+ delete _blockRegion;
+ delete _currentBlockRegion;
+ _blockRegion = NULL;
+ _currentBlockRegion = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ _blockRegion = rgn;
+ _currentBlockRegion = crgn;
+ _currentBlockRegion->mimic(_blockRegion);
+ }
+ }
+ break;
+
+ case TOKEN_WAYPOINTS: {
+ delete _wptGroup;
+ delete _currentWptGroup;
+ _wptGroup = NULL;
+ _currentWptGroup = NULL;
+ AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
+ AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef);
+ if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) {
+ delete _wptGroup;
+ delete _currentWptGroup;
+ _wptGroup = NULL;
+ _currentWptGroup = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ _wptGroup = wpt;
+ _currentWptGroup = cwpt;
+ _currentWptGroup->mimic(_wptGroup);
+ }
+ }
+ break;
+
+ case TOKEN_IGNORE_ITEMS:
+ parser.scanStr((char *)params, "%b", &_ignoreItems);
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.scanStr((char *)params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+
+ case TOKEN_ANIMATION: {
+ AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
+ if (!anim || DID_FAIL(anim->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _anims.add(anim);
+ }
+ }
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ACTOR definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ if (spr) {
+ delete spr;
+ }
+ _gameRef->LOG(0, "Error loading ACTOR definition");
+ return STATUS_FAILED;
+ }
+
+ if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
+ ar = ag = ab = 255;
+ }
+ _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
+ _state = _nextState = STATE_READY;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdActor::turnTo(TDirection dir) {
+ int delta1, delta2, delta3, delta;
+
+ delta1 = dir - _dir;
+ delta2 = dir + NUM_DIRECTIONS - _dir;
+ delta3 = dir - NUM_DIRECTIONS - _dir;
+
+ delta1 = (abs(delta1) <= abs(delta2)) ? delta1 : delta2;
+ delta = (abs(delta1) <= abs(delta3)) ? delta1 : delta3;
+
+ // already there?
+ if (abs(delta) < 2) {
+ _dir = dir;
+ _state = _nextState;
+ _nextState = STATE_READY;
+ return;
+ }
+
+ _targetDir = dir;
+ _state = delta < 0 ? STATE_TURNING_LEFT : STATE_TURNING_RIGHT;
+
+ _tempSprite2 = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdActor::goTo(int x, int y, TDirection afterWalkDir) {
+ _afterWalkDir = afterWalkDir;
+ if (x == _targetPoint->x && y == _targetPoint->y && _state == STATE_FOLLOWING_PATH) {
+ return;
+ }
+
+ _path->reset();
+ _path->setReady(false);
+
+ _targetPoint->x = x;
+ _targetPoint->y = y;
+
+ ((AdGame *)_gameRef)->_scene->correctTargetPoint(_posX, _posY, &_targetPoint->x, &_targetPoint->y, true, this);
+
+ _state = STATE_SEARCHING_PATH;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::display() {
+ if (_active) {
+ updateSounds();
+ }
+
+ uint32 alpha;
+ if (_alphaColor != 0) {
+ alpha = _alphaColor;
+ } else {
+ alpha = _shadowable ? ((AdGame *)_gameRef)->_scene->getAlphaAt(_posX, _posY, true) : 0xFFFFFFFF;
+ }
+
+ float scaleX, scaleY;
+ getScale(&scaleX, &scaleY);
+
+
+ float rotate;
+ if (_rotatable) {
+ if (_rotateValid) {
+ rotate = _rotate;
+ } else {
+ rotate = ((AdGame *)_gameRef)->_scene->getRotationAt(_posX, _posY) + _relativeRotate;
+ }
+ } else {
+ rotate = 0.0f;
+ }
+
+ if (_active) {
+ displaySpriteAttachments(true);
+ }
+
+ if (_currentSprite && _active) {
+ bool reg = _registrable;
+ if (_ignoreItems && ((AdGame *)_gameRef)->_selectedItem) {
+ reg = false;
+ }
+
+ _currentSprite->display(_posX,
+ _posY,
+ reg ? _registerAlias : NULL,
+ scaleX,
+ scaleY,
+ alpha,
+ rotate,
+ _blendMode);
+
+ }
+
+ if (_active) {
+ displaySpriteAttachments(false);
+ }
+ if (_active && _partEmitter) {
+ _partEmitter->display();
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::update() {
+ _currentSprite = NULL;
+
+ if (_state == STATE_READY) {
+ if (_animSprite) {
+ delete _animSprite;
+ _animSprite = NULL;
+ }
+ if (_animSprite2) {
+ _animSprite2 = NULL;
+ }
+ }
+
+ // finished playing animation?
+ if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
+ _state = _nextState;
+ _nextState = STATE_READY;
+ _currentSprite = _animSprite;
+ }
+
+ if (_state == STATE_PLAYING_ANIM_SET && _animSprite2 != NULL && _animSprite2->_finished) {
+ _state = _nextState;
+ _nextState = STATE_READY;
+ _currentSprite = _animSprite2;
+ }
+
+ if (_sentence && _state != STATE_TALKING) {
+ _sentence->finish();
+ }
+
+ // default: stand animation
+ if (!_currentSprite) {
+ if (_sprite) {
+ _currentSprite = _sprite;
+ } else {
+ if (_standSprite) {
+ _currentSprite = _standSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_idleAnimName);
+ if (anim) {
+ _currentSprite = anim->getSprite(_dir);
+ }
+ }
+ }
+ }
+
+ bool already_moved = false;
+
+ switch (_state) {
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_PLAYING_ANIM:
+ _currentSprite = _animSprite;
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_PLAYING_ANIM_SET:
+ _currentSprite = _animSprite2;
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_TURNING_LEFT:
+ if (_tempSprite2 == NULL || _tempSprite2->_finished) {
+ if (_dir > 0) {
+ _dir = (TDirection)(_dir - 1);
+ } else {
+ _dir = (TDirection)(NUM_DIRECTIONS - 1);
+ }
+
+ if (_dir == _targetDir) {
+ _tempSprite2 = NULL;
+ _state = _nextState;
+ _nextState = STATE_READY;
+ } else {
+ if (_turnLeftSprite) {
+ _tempSprite2 = _turnLeftSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_turnLeftAnimName);
+ if (anim) {
+ _tempSprite2 = anim->getSprite(_dir);
+ }
+ }
+
+ if (_tempSprite2) {
+ _tempSprite2->reset();
+ if (_tempSprite2->_looping) {
+ _tempSprite2->_looping = false;
+ }
+ }
+ _currentSprite = _tempSprite2;
+ }
+ } else {
+ _currentSprite = _tempSprite2;
+ }
+ break;
+
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_TURNING_RIGHT:
+ if (_tempSprite2 == NULL || _tempSprite2->_finished) {
+ _dir = (TDirection)(_dir + 1);
+
+ if ((int)_dir >= (int)NUM_DIRECTIONS) {
+ _dir = (TDirection)(0);
+ }
+
+ if (_dir == _targetDir) {
+ _tempSprite2 = NULL;
+ _state = _nextState;
+ _nextState = STATE_READY;
+ } else {
+ if (_turnRightSprite) {
+ _tempSprite2 = _turnRightSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_turnRightAnimName);
+ if (anim) {
+ _tempSprite2 = anim->getSprite(_dir);
+ }
+ }
+
+ if (_tempSprite2) {
+ _tempSprite2->reset();
+ if (_tempSprite2->_looping) {
+ _tempSprite2->_looping = false;
+ }
+ }
+ _currentSprite = _tempSprite2;
+ }
+ } else {
+ _currentSprite = _tempSprite2;
+ }
+ break;
+
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_SEARCHING_PATH:
+ // keep asking scene for the path
+ if (((AdGame *)_gameRef)->_scene->getPath(BasePoint(_posX, _posY), *_targetPoint, _path, this)) {
+ _state = STATE_WAITING_PATH;
+ }
+ break;
+
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_WAITING_PATH:
+ // wait until the scene finished the path
+ if (_path->_ready) {
+ followPath();
+ }
+ break;
+
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_FOLLOWING_PATH:
+ getNextStep();
+ already_moved = true;
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_TALKING: {
+ _sentence->update(_dir);
+ if (_sentence->_currentSprite) {
+ _tempSprite2 = _sentence->_currentSprite;
+ }
+
+ bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
+ if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
+ if (timeIsUp) {
+ _sentence->finish();
+ _tempSprite2 = NULL;
+ _state = _nextState;
+ _nextState = STATE_READY;
+ } else {
+ _tempSprite2 = getTalkStance(_sentence->getNextStance());
+ if (_tempSprite2) {
+ _tempSprite2->reset();
+ _currentSprite = _tempSprite2;
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ }
+ } else {
+ _currentSprite = _tempSprite2;
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ }
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_READY:
+ if (!_animSprite && !_animSprite2) {
+ if (_sprite) {
+ _currentSprite = _sprite;
+ } else {
+ if (_standSprite) {
+ _currentSprite = _standSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_idleAnimName);
+ if (anim) {
+ _currentSprite = anim->getSprite(_dir);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ error("AdActor::Update - Unhandled enum");
+ }
+
+
+ if (_currentSprite && !already_moved) {
+ _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100, _zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
+ if (_currentSprite->_changed) {
+ _posX += _currentSprite->_moveX;
+ _posY += _currentSprite->_moveY;
+ afterMove();
+ }
+ }
+
+ //_gameRef->QuickMessageForm("%s", _currentSprite->_filename);
+
+ updateBlockRegion();
+ _ready = (_state == STATE_READY);
+
+ updatePartEmitter();
+ updateSpriteAttachments();
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdActor::followPath() {
+ // skip current position
+ _path->getFirst();
+ while (_path->getCurrent() != NULL) {
+ if (_path->getCurrent()->x != _posX || _path->getCurrent()->y != _posY) {
+ break;
+ }
+ _path->getNext();
+ }
+
+ // are there points to follow?
+ if (_path->getCurrent() != NULL) {
+ _state = STATE_FOLLOWING_PATH;;
+ initLine(BasePoint(_posX, _posY), *_path->getCurrent());
+ } else {
+ if (_afterWalkDir != DI_NONE) {
+ turnTo(_afterWalkDir);
+ } else {
+ _state = STATE_READY;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdActor::getNextStep() {
+ if (_walkSprite) {
+ _currentSprite = _walkSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_walkAnimName);
+ if (anim) {
+ _currentSprite = anim->getSprite(_dir);
+ }
+ }
+
+ if (!_currentSprite) {
+ return;
+ }
+
+ _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100, _zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
+ if (!_currentSprite->_changed) {
+ return;
+ }
+
+
+ int maxStepX, maxStepY;
+ maxStepX = abs(_currentSprite->_moveX);
+ maxStepY = abs(_currentSprite->_moveY);
+
+ maxStepX = MAX(maxStepX, maxStepY);
+ maxStepX = MAX(maxStepX, 1);
+
+ while (_pFCount > 0 && maxStepX >= 0) {
+ _pFX += _pFStepX;
+ _pFY += _pFStepY;
+
+ _pFCount--;
+ maxStepX--;
+ }
+
+ if (((AdGame *)_gameRef)->_scene->isBlockedAt((int)_pFX, (int) _pFY, true, this)) {
+ if (_pFCount == 0) {
+ _state = _nextState;
+ _nextState = STATE_READY;
+ return;
+ }
+ goTo(_targetPoint->x, _targetPoint->y);
+ return;
+ }
+
+
+ _posX = (int)_pFX;
+ _posY = (int)_pFY;
+
+ afterMove();
+
+
+ if (_pFCount == 0) {
+ if (_path->getNext() == NULL) {
+ _posX = _targetPoint->x;
+ _posY = _targetPoint->y;
+
+ _path->reset();
+ if (_afterWalkDir != DI_NONE) {
+ turnTo(_afterWalkDir);
+ } else {
+ _state = _nextState;
+ _nextState = STATE_READY;
+ }
+ } else {
+ initLine(BasePoint(_posX, _posY), *_path->getCurrent());
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdActor::initLine(BasePoint startPt, BasePoint endPt) {
+ _pFCount = MAX((abs(endPt.x - startPt.x)) , (abs(endPt.y - startPt.y)));
+
+ _pFStepX = (double)(endPt.x - startPt.x) / _pFCount;
+ _pFStepY = (double)(endPt.y - startPt.y) / _pFCount;
+
+ _pFX = startPt.x;
+ _pFY = startPt.y;
+
+ int angle = (int)(atan2((double)(endPt.y - startPt.y), (double)(endPt.x - startPt.x)) * (180 / 3.14));
+
+ _nextState = STATE_FOLLOWING_PATH;
+
+ turnTo(angleToDirection(angle));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // GoTo / GoToAsync
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "GoTo") == 0 || strcmp(name, "GoToAsync") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+ goTo(x, y);
+ if (strcmp(name, "GoToAsync") != 0) {
+ script->waitForExclusive(this);
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GoToObject / GoToObjectAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GoToObject") == 0 || strcmp(name, "GoToObjectAsync") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ if (!val->isNative()) {
+ script->runtimeError("actor.%s method accepts an entity refrence only", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ AdObject *obj = (AdObject *)val->getNative();
+ if (!obj || obj->_type != OBJECT_ENTITY) {
+ script->runtimeError("actor.%s method accepts an entity refrence only", name);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+ AdEntity *ent = (AdEntity *)obj;
+ if (ent->_walkToX == 0 && ent->_walkToY == 0) {
+ goTo(ent->_posX, ent->_posY);
+ } else {
+ goTo(ent->_walkToX, ent->_walkToY, ent->_walkToDir);
+ }
+ if (strcmp(name, "GoToObjectAsync") != 0) {
+ script->waitForExclusive(this);
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TurnTo / TurnToAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TurnTo") == 0 || strcmp(name, "TurnToAsync") == 0) {
+ stack->correctParams(1);
+ int dir;
+ ScValue *val = stack->pop();
+
+ // turn to object?
+ if (val->isNative() && _gameRef->validObject((BaseObject *)val->getNative())) {
+ BaseObject *obj = (BaseObject *)val->getNative();
+ int angle = (int)(atan2((double)(obj->_posY - _posY), (double)(obj->_posX - _posX)) * (180 / 3.14));
+ dir = (int)angleToDirection(angle);
+ }
+ // otherwise turn to direction
+ else {
+ dir = val->getInt();
+ }
+
+ if (dir >= 0 && dir < NUM_DIRECTIONS) {
+ turnTo((TDirection)dir);
+ if (strcmp(name, "TurnToAsync") != 0) {
+ script->waitForExclusive(this);
+ }
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsWalking
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsWalking") == 0) {
+ stack->correctParams(0);
+ stack->pushBool(_state == STATE_FOLLOWING_PATH);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MergeAnims
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "MergeAnims") == 0) {
+ stack->correctParams(1);
+ stack->pushBool(DID_SUCCEED(mergeAnims(stack->pop()->getString())));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // UnloadAnim
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "UnloadAnim") == 0) {
+ stack->correctParams(1);
+ const char *animName = stack->pop()->getString();
+
+ bool found = false;
+ for (uint32 i = 0; i < _anims.size(); i++) {
+ if (scumm_stricmp(_anims[i]->getName(), animName) == 0) {
+ // invalidate sprites in use
+ if (_anims[i]->containsSprite(_tempSprite2)) {
+ _tempSprite2 = NULL;
+ }
+ if (_anims[i]->containsSprite(_currentSprite)) {
+ _currentSprite = NULL;
+ }
+ if (_anims[i]->containsSprite(_animSprite2)) {
+ _animSprite2 = NULL;
+ }
+
+ delete _anims[i];
+ _anims[i] = NULL;
+ _anims.remove_at(i);
+ i--;
+ found = true;
+ }
+ }
+ stack->pushBool(found);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HasAnim
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "HasAnim") == 0) {
+ stack->correctParams(1);
+ const char *animName = stack->pop()->getString();
+ stack->pushBool(getAnimByName(animName) != NULL);
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdActor::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Direction
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Direction") == 0) {
+ _scValue->setInt(_dir);
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Type") == 0) {
+ _scValue->setString("actor");
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // TalkAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TalkAnimName") == 0) {
+ _scValue->setString(_talkAnimName);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkAnimName") == 0) {
+ _scValue->setString(_walkAnimName);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IdleAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IdleAnimName") == 0) {
+ _scValue->setString(_idleAnimName);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TurnLeftAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TurnLeftAnimName") == 0) {
+ _scValue->setString(_turnLeftAnimName);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TurnRightAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TurnRightAnimName") == 0) {
+ _scValue->setString(_turnRightAnimName);
+ return _scValue;
+ } else {
+ return AdTalkHolder::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Direction
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Direction") == 0) {
+ int dir = value->getInt();
+ if (dir >= 0 && dir < NUM_DIRECTIONS) {
+ _dir = (TDirection)dir;
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TalkAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TalkAnimName") == 0) {
+ if (value->isNULL()) {
+ _talkAnimName = "talk";
+ } else {
+ _talkAnimName = value->getString();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkAnimName") == 0) {
+ if (value->isNULL()) {
+ _walkAnimName = "walk";
+ } else {
+ _walkAnimName = value->getString();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IdleAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IdleAnimName") == 0) {
+ if (value->isNULL()) {
+ _idleAnimName = "idle";
+ } else {
+ _idleAnimName = value->getString();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TurnLeftAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TurnLeftAnimName") == 0) {
+ if (value->isNULL()) {
+ _turnLeftAnimName = "turnleft";
+ } else {
+ _turnLeftAnimName = value->getString();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TurnRightAnimName
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TurnRightAnimName") == 0) {
+ if (value->isNULL()) {
+ _turnRightAnimName = "turnright";
+ } else {
+ _turnRightAnimName = value->getString();
+ }
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdActor::scToString() {
+ return "[actor object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdActor::getTalkStance(const char *stance) {
+ // forced stance?
+ if (_forcedTalkAnimName && !_forcedTalkAnimUsed) {
+ _forcedTalkAnimUsed = true;
+ delete _animSprite;
+ _animSprite = new BaseSprite(_gameRef, this);
+ if (_animSprite) {
+ bool res = _animSprite->loadFile(_forcedTalkAnimName);
+ if (DID_FAIL(res)) {
+ _gameRef->LOG(res, "AdActor::GetTalkStance: error loading talk sprite (object:\"%s\" sprite:\"%s\")", getName(), _forcedTalkAnimName);
+ delete _animSprite;
+ _animSprite = NULL;
+ } else {
+ return _animSprite;
+ }
+ }
+ }
+
+ // old way
+ if (_talkSprites.size() > 0 || _talkSpritesEx.size() > 0) {
+ return getTalkStanceOld(stance);
+ }
+
+ // new way
+ BaseSprite *ret = NULL;
+
+ // do we have an animation with this name?
+ AdSpriteSet *anim = getAnimByName(stance);
+ if (anim) {
+ ret = anim->getSprite(_dir);
+ }
+
+ // not - get a random talk
+ if (!ret) {
+ BaseArray<AdSpriteSet *> talkAnims;
+ for (uint32 i = 0; i < _anims.size(); i++) {
+ if (_talkAnimName.compareToIgnoreCase(_anims[i]->getName()) == 0) {
+ talkAnims.add(_anims[i]);
+ }
+ }
+
+ if (talkAnims.size() > 0) {
+ int rnd = BaseEngine::instance().randInt(0, talkAnims.size() - 1);
+ ret = talkAnims[rnd]->getSprite(_dir);
+ } else {
+ if (_standSprite) {
+ ret = _standSprite->getSprite(_dir);
+ } else {
+ anim = getAnimByName(_idleAnimName);
+ if (anim) {
+ ret = anim->getSprite(_dir);
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdActor::getTalkStanceOld(const char *stance) {
+ BaseSprite *ret = NULL;
+
+ if (stance != NULL) {
+ // search special stances
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ if (scumm_stricmp(_talkSpritesEx[i]->getName(), stance) == 0) {
+ ret = _talkSpritesEx[i]->getSprite(_dir);
+ break;
+ }
+ }
+ if (ret == NULL) {
+ // search generic stances
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ if (scumm_stricmp(_talkSprites[i]->getName(), stance) == 0) {
+ ret = _talkSprites[i]->getSprite(_dir);
+ break;
+ }
+ }
+ }
+ }
+
+ // not a valid stance? get a random one
+ if (ret == NULL) {
+ if (_talkSprites.size() < 1) {
+ ret = _standSprite->getSprite(_dir);
+ } else {
+ // TODO: remember last
+ int rnd = BaseEngine::instance().randInt(0, _talkSprites.size() - 1);
+ ret = _talkSprites[rnd]->getSprite(_dir);
+ }
+ }
+
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::persist(BasePersistenceManager *persistMgr) {
+ AdTalkHolder::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER_INT(_dir));
+ persistMgr->transfer(TMEMBER(_path));
+ persistMgr->transfer(TMEMBER(_pFCount));
+ persistMgr->transfer(TMEMBER(_pFStepX));
+ persistMgr->transfer(TMEMBER(_pFStepY));
+ persistMgr->transfer(TMEMBER(_pFX));
+ persistMgr->transfer(TMEMBER(_pFY));
+ persistMgr->transfer(TMEMBER(_standSprite));
+ _talkSprites.persist(persistMgr);
+ _talkSpritesEx.persist(persistMgr);
+ persistMgr->transfer(TMEMBER_INT(_targetDir));
+ persistMgr->transfer(TMEMBER_INT(_afterWalkDir));
+ persistMgr->transfer(TMEMBER(_targetPoint));
+ persistMgr->transfer(TMEMBER(_turnLeftSprite));
+ persistMgr->transfer(TMEMBER(_turnRightSprite));
+ persistMgr->transfer(TMEMBER(_walkSprite));
+
+ persistMgr->transfer(TMEMBER(_animSprite2));
+ persistMgr->transfer(TMEMBER(_talkAnimName));
+ persistMgr->transfer(TMEMBER(_idleAnimName));
+ persistMgr->transfer(TMEMBER(_walkAnimName));
+ persistMgr->transfer(TMEMBER(_turnLeftAnimName));
+ persistMgr->transfer(TMEMBER(_turnRightAnimName));
+
+ _anims.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+TDirection AdActor::angleToDirection(int angle) {
+ TDirection ret = DI_DOWN;;
+
+ if (angle > -112 && angle <= -67) {
+ ret = DI_UP;
+ } else if (angle > -67 && angle <= -22) {
+ ret = DI_UPRIGHT;
+ } else if (angle > -22 && angle <= 22) {
+ ret = DI_RIGHT;
+ } else if (angle > 22 && angle <= 67) {
+ ret = DI_DOWNRIGHT;
+ } else if (angle > 67 && angle <= 112) {
+ ret = DI_DOWN;
+ } else if (angle > 112 && angle <= 157) {
+ ret = DI_DOWNLEFT;
+ } else if ((angle > 157 && angle <= 180) || (angle >= -180 && angle <= -157)) {
+ ret = DI_LEFT;
+ } else if (angle > -157 && angle <= -112) {
+ ret = DI_UPLEFT;
+ }
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdActor::getHeight() {
+ // if no current sprite is set, set some
+ if (_currentSprite == NULL) {
+ if (_standSprite) {
+ _currentSprite = _standSprite->getSprite(_dir);
+ } else {
+ AdSpriteSet *anim = getAnimByName(_idleAnimName);
+ if (anim) {
+ _currentSprite = anim->getSprite(_dir);
+ }
+ }
+ }
+ // and get height
+ return AdTalkHolder::getHeight();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSpriteSet *AdActor::getAnimByName(const Common::String &animName) {
+ for (uint32 i = 0; i < _anims.size(); i++) {
+ if (animName.compareToIgnoreCase(_anims[i]->getName()) == 0) {
+ return _anims[i];
+ }
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::mergeAnims(const char *animsFilename) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ANIMATION)
+ TOKEN_TABLE_END
+
+
+ byte *fileBuffer = BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
+ if (fileBuffer == NULL) {
+ _gameRef->LOG(0, "AdActor::MergeAnims failed for file '%s'", animsFilename);
+ return STATUS_FAILED;
+ }
+
+ byte *buffer = fileBuffer;
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ bool ret = STATUS_OK;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_ANIMATION: {
+ AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
+ if (!anim || DID_FAIL(anim->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ ret = STATUS_FAILED;
+ } else {
+ _anims.add(anim);
+ }
+ }
+ break;
+ }
+ }
+ delete[] fileBuffer;
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdActor::playAnim(const char *filename) {
+ // if we have an anim with this name, use it
+ AdSpriteSet *anim = getAnimByName(filename);
+ if (anim) {
+ _animSprite2 = anim->getSprite(_dir);
+ if (_animSprite2) {
+ _animSprite2->reset();
+ _state = STATE_PLAYING_ANIM_SET;
+ return STATUS_OK;
+ }
+ }
+ // otherwise call the standard handler
+ return AdTalkHolder::playAnim(filename);
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_actor.h b/engines/wintermute/ad/ad_actor.h
index 370a91cc22..271e57cb85 100644
--- a/engines/wintermute/ad/ad_actor.h
+++ b/engines/wintermute/ad/ad_actor.h
@@ -1,108 +1,108 @@
-/* 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_ADACTOR_H
-#define WINTERMUTE_ADACTOR_H
-
-
-#include "engines/wintermute/dctypes.h" // Added by ClassView
-#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
-#include "engines/wintermute/ad/ad_talk_holder.h"
-#include "engines/wintermute/coll_templ.h"
-#include "engines/wintermute/base/base_point.h" // Added by ClassView
-#include "engines/wintermute/persistent.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-class AdSpriteSet;
-class AdPath;
-class BaseSprite;
-class AdActor : public AdTalkHolder {
-public:
- TDirection angleToDirection(int angle);
- DECLARE_PERSISTENT(AdActor, AdTalkHolder)
- virtual int getHeight();
- BaseSprite *getTalkStance(const char *stance);
- virtual void goTo(int x, int y, TDirection afterWalkDir = DI_NONE);
- BasePoint *_targetPoint;
- virtual bool update();
- virtual bool display();
- virtual void turnTo(TDirection dir);
- AdActor(BaseGame *inGame/*=NULL*/);
- virtual ~AdActor();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
-
-
-private:
- TDirection _targetDir;
- TDirection _afterWalkDir;
-
- AdPath *_path;
- AdSpriteSet *_walkSprite;
- AdSpriteSet *_standSprite;
- AdSpriteSet *_turnLeftSprite;
- AdSpriteSet *_turnRightSprite;
- BaseArray<AdSpriteSet *> _talkSprites;
- BaseArray<AdSpriteSet *> _talkSpritesEx;
- TDirection _dir;
- // new anim system
- Common::String _talkAnimName;
- Common::String _idleAnimName;
- Common::String _walkAnimName;
- Common::String _turnLeftAnimName;
- Common::String _turnRightAnimName;
- BaseArray<AdSpriteSet *> _anims;
- virtual bool playAnim(const char *filename);
- AdSpriteSet *getAnimByName(const Common::String &animName);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-
- bool setDefaultAnimNames();
- BaseSprite *getTalkStanceOld(const char *stance);
- bool mergeAnims(const char *animsFilename);
- BaseSprite *_animSprite2;
-
- void initLine(BasePoint startPt, BasePoint endPt);
- void getNextStep();
- void followPath();
- double _pFStepX;
- double _pFStepY;
- double _pFX;
- double _pFY;
- int _pFCount;
-};
-
-} // 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_ADACTOR_H
+#define WINTERMUTE_ADACTOR_H
+
+
+#include "engines/wintermute/dctypes.h" // Added by ClassView
+#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
+#include "engines/wintermute/ad/ad_talk_holder.h"
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/base/base_point.h" // Added by ClassView
+#include "engines/wintermute/persistent.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+class AdSpriteSet;
+class AdPath;
+class BaseSprite;
+class AdActor : public AdTalkHolder {
+public:
+ TDirection angleToDirection(int angle);
+ DECLARE_PERSISTENT(AdActor, AdTalkHolder)
+ virtual int getHeight();
+ BaseSprite *getTalkStance(const char *stance);
+ virtual void goTo(int x, int y, TDirection afterWalkDir = DI_NONE);
+ BasePoint *_targetPoint;
+ virtual bool update();
+ virtual bool display();
+ virtual void turnTo(TDirection dir);
+ AdActor(BaseGame *inGame/*=NULL*/);
+ virtual ~AdActor();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+
+
+private:
+ TDirection _targetDir;
+ TDirection _afterWalkDir;
+
+ AdPath *_path;
+ AdSpriteSet *_walkSprite;
+ AdSpriteSet *_standSprite;
+ AdSpriteSet *_turnLeftSprite;
+ AdSpriteSet *_turnRightSprite;
+ BaseArray<AdSpriteSet *> _talkSprites;
+ BaseArray<AdSpriteSet *> _talkSpritesEx;
+ TDirection _dir;
+ // new anim system
+ Common::String _talkAnimName;
+ Common::String _idleAnimName;
+ Common::String _walkAnimName;
+ Common::String _turnLeftAnimName;
+ Common::String _turnRightAnimName;
+ BaseArray<AdSpriteSet *> _anims;
+ virtual bool playAnim(const char *filename);
+ AdSpriteSet *getAnimByName(const Common::String &animName);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+
+ bool setDefaultAnimNames();
+ BaseSprite *getTalkStanceOld(const char *stance);
+ bool mergeAnims(const char *animsFilename);
+ BaseSprite *_animSprite2;
+
+ void initLine(BasePoint startPt, BasePoint endPt);
+ void getNextStep();
+ void followPath();
+ double _pFStepX;
+ double _pFStepY;
+ double _pFX;
+ double _pFY;
+ int _pFCount;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_entity.cpp b/engines/wintermute/ad/ad_entity.cpp
index 67a919dd6b..234af1fffa 100644
--- a/engines/wintermute/ad/ad_entity.cpp
+++ b/engines/wintermute/ad/ad_entity.cpp
@@ -1,1121 +1,1121 @@
-/* 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/ad/ad_entity.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_active_rect.h"
-#include "engines/wintermute/base/base_surface_storage.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_scene.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/ad/ad_waypoint_group.h"
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/base/base_region.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/utils/utils.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/video/video_theora_player.h"
-#include "engines/wintermute/base/particles/part_emitter.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdEntity, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdEntity::AdEntity(BaseGame *inGame) : AdTalkHolder(inGame) {
- _type = OBJECT_ENTITY;
- _subtype = ENTITY_NORMAL;
- _region = NULL;
- _item = NULL;
-
- _walkToX = _walkToY = 0;
- _walkToDir = DI_NONE;
-
- _theora = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdEntity::~AdEntity() {
- _gameRef->unregisterObject(_region);
-
- delete _theora;
- _theora = NULL;
-
- delete[] _item;
- _item = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdEntity::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing ENTITY file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(ENTITY)
-TOKEN_DEF(SPRITE)
-TOKEN_DEF(X)
-TOKEN_DEF(Y)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(SCALABLE)
-TOKEN_DEF(REGISTRABLE)
-TOKEN_DEF(INTERACTIVE)
-TOKEN_DEF(SHADOWABLE)
-TOKEN_DEF(COLORABLE)
-TOKEN_DEF(ACTIVE)
-TOKEN_DEF(EVENTS)
-TOKEN_DEF(FONT)
-TOKEN_DEF(TALK_SPECIAL)
-TOKEN_DEF(TALK)
-TOKEN_DEF(CURSOR)
-TOKEN_DEF(REGION)
-TOKEN_DEF(BLOCKED_REGION)
-TOKEN_DEF(EDITOR_SELECTED)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(SOUND_START_TIME)
-TOKEN_DEF(SOUND_VOLUME)
-TOKEN_DEF(SOUND_PANNING)
-TOKEN_DEF(SOUND)
-TOKEN_DEF(SUBTYPE)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(WAYPOINTS)
-TOKEN_DEF(IGNORE_ITEMS)
-TOKEN_DEF(ROTABLE)
-TOKEN_DEF(ROTATABLE)
-TOKEN_DEF(ALPHA_COLOR)
-TOKEN_DEF(SCALE)
-TOKEN_DEF(RELATIVE_SCALE)
-TOKEN_DEF(ALPHA)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF(ITEM)
-TOKEN_DEF(WALK_TO_X)
-TOKEN_DEF(WALK_TO_Y)
-TOKEN_DEF(WALK_TO_DIR)
-TOKEN_DEF(SAVE_STATE)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ENTITY)
- TOKEN_TABLE(SPRITE)
- TOKEN_TABLE(X)
- TOKEN_TABLE(Y)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(SCALABLE)
- TOKEN_TABLE(REGISTRABLE)
- TOKEN_TABLE(INTERACTIVE)
- TOKEN_TABLE(SHADOWABLE)
- TOKEN_TABLE(COLORABLE)
- TOKEN_TABLE(ACTIVE)
- TOKEN_TABLE(EVENTS)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(TALK_SPECIAL)
- TOKEN_TABLE(TALK)
- TOKEN_TABLE(CURSOR)
- TOKEN_TABLE(REGION)
- TOKEN_TABLE(BLOCKED_REGION)
- TOKEN_TABLE(EDITOR_SELECTED)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(SOUND_START_TIME)
- TOKEN_TABLE(SOUND_VOLUME)
- TOKEN_TABLE(SOUND_PANNING)
- TOKEN_TABLE(SOUND)
- TOKEN_TABLE(SUBTYPE)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(WAYPOINTS)
- TOKEN_TABLE(IGNORE_ITEMS)
- TOKEN_TABLE(ROTABLE)
- TOKEN_TABLE(ROTATABLE)
- TOKEN_TABLE(ALPHA_COLOR)
- TOKEN_TABLE(SCALE)
- TOKEN_TABLE(RELATIVE_SCALE)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE(ITEM)
- TOKEN_TABLE(WALK_TO_X)
- TOKEN_TABLE(WALK_TO_Y)
- TOKEN_TABLE(WALK_TO_DIR)
- TOKEN_TABLE(SAVE_STATE)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY) {
- _gameRef->LOG(0, "'ENTITY' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- AdGame *adGame = (AdGame *)_gameRef;
- BaseSprite *spr = NULL;
- int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
- break;
-
- case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
- break;
-
- case TOKEN_SPRITE: {
- delete _sprite;
- _sprite = NULL;
- spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprite = spr;
- }
- }
- break;
-
- case TOKEN_TALK: {
- spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSprites.add(spr);
- }
- }
- break;
-
- case TOKEN_TALK_SPECIAL: {
- spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSpritesEx.add(spr);
- }
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_ITEM:
- setItem((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_FONT:
- setFont((char *)params);
- break;
-
- case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
- break;
-
- case TOKEN_SCALE: {
- int s;
- parser.scanStr((char *)params, "%d", &s);
- _scale = (float)s;
-
- }
- break;
-
- case TOKEN_RELATIVE_SCALE: {
- int s;
- parser.scanStr((char *)params, "%d", &s);
- _relativeScale = (float)s;
-
- }
- break;
-
- case TOKEN_ROTABLE:
- case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
- break;
-
- case TOKEN_REGISTRABLE:
- case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
- break;
-
- case TOKEN_SHADOWABLE:
- case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
- break;
-
- case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
- break;
-
- case TOKEN_CURSOR:
- delete _cursor;
- _cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
- delete _cursor;
- _cursor = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
- break;
-
- case TOKEN_REGION: {
- if (_region) {
- _gameRef->unregisterObject(_region);
- }
- _region = NULL;
- BaseRegion *rgn = new BaseRegion(_gameRef);
- if (!rgn || DID_FAIL(rgn->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- } else {
- _region = rgn;
- _gameRef->registerObject(_region);
- }
- }
- break;
-
- case TOKEN_BLOCKED_REGION: {
- delete _blockRegion;
- _blockRegion = NULL;
- delete _currentBlockRegion;
- _currentBlockRegion = NULL;
- BaseRegion *rgn = new BaseRegion(_gameRef);
- BaseRegion *crgn = new BaseRegion(_gameRef);
- if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) {
- delete _blockRegion;
- _blockRegion = NULL;
- delete _currentBlockRegion;
- _currentBlockRegion = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- _blockRegion = rgn;
- _currentBlockRegion = crgn;
- _currentBlockRegion->mimic(_blockRegion);
- }
- }
- break;
-
- case TOKEN_WAYPOINTS: {
- delete _wptGroup;
- _wptGroup = NULL;
- delete _currentWptGroup;
- _currentWptGroup = NULL;
- AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
- AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef);
- if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) {
- delete _wptGroup;
- _wptGroup = NULL;
- delete _currentWptGroup;
- _currentWptGroup = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- _wptGroup = wpt;
- _currentWptGroup = cwpt;
- _currentWptGroup->mimic(_wptGroup);
- }
- }
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_SUBTYPE: {
- if (scumm_stricmp((char *)params, "sound") == 0) {
- delete _sprite;
- _sprite = NULL;
- if (_gameRef->_editorMode) {
- spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile("entity_sound.sprite"))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprite = spr;
- }
- }
- if (_gameRef->_editorMode) {
- _editorOnly = true;
- }
- _zoomable = false;
- _rotatable = false;
- _registrable = _gameRef->_editorMode;
- _shadowable = false;
- _subtype = ENTITY_SOUND;
- }
- }
- break;
-
- case TOKEN_SOUND:
- playSFX((char *)params, false, false);
- break;
-
- case TOKEN_SOUND_START_TIME:
- parser.scanStr((char *)params, "%d", &_sFXStart);
- break;
-
- case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
- break;
-
- case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
- break;
-
- case TOKEN_SAVE_STATE:
- parser.scanStr((char *)params, "%b", &_saveState);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
- break;
-
- case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
- break;
-
- case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
-
- case TOKEN_WALK_TO_X:
- parser.scanStr((char *)params, "%d", &_walkToX);
- break;
-
- case TOKEN_WALK_TO_Y:
- parser.scanStr((char *)params, "%d", &_walkToY);
- break;
-
- case TOKEN_WALK_TO_DIR: {
- int i;
- parser.scanStr((char *)params, "%d", &i);
- if (i < 0) {
- i = 0;
- }
- if (i >= NUM_DIRECTIONS) {
- i = DI_NONE;
- }
- _walkToDir = (TDirection)i;
- }
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ENTITY definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading ENTITY definition");
- if (spr) {
- delete spr;
- }
- return STATUS_FAILED;
- }
-
- if (_region && _sprite) {
- _gameRef->LOG(0, "Warning: Entity '%s' has both sprite and region.", getName());
- }
-
- updatePosition();
-
- if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
- ar = ag = ab = 255;
- }
- _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
- _state = STATE_READY;
-
- if (_item && ((AdGame *)_gameRef)->isItemTaken(_item)) {
- _active = false;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::display() {
- if (_active) {
- updateSounds();
-
- uint32 alpha;
- if (_alphaColor != 0) {
- alpha = _alphaColor;
- } else {
- alpha = _shadowable ? ((AdGame *)_gameRef)->_scene->getAlphaAt(_posX, _posY) : 0xFFFFFFFF;
- }
-
- float scaleX, scaleY;
- getScale(&scaleX, &scaleY);
-
- float rotate;
- if (_rotatable) {
- if (_rotateValid) {
- rotate = _rotate;
- } else {
- rotate = ((AdGame *)_gameRef)->_scene->getRotationAt(_posX, _posY) + _relativeRotate;
- }
- } else {
- rotate = 0.0f;
- }
-
-
- bool reg = _registrable;
- if (_ignoreItems && ((AdGame *)_gameRef)->_selectedItem) {
- reg = false;
- }
-
- if (_region && (reg || _editorAlwaysRegister)) {
- _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, _registerAlias, _region, _gameRef->_offsetX, _gameRef->_offsetY));
- }
-
- displaySpriteAttachments(true);
- if (_theora && (_theora->isPlaying() || _theora->isPaused())) {
- _theora->display(alpha);
- } else if (_currentSprite) {
- _currentSprite->display(_posX,
- _posY,
- (reg || _editorAlwaysRegister) ? _registerAlias : NULL,
- scaleX,
- scaleY,
- alpha,
- rotate,
- _blendMode);
- }
- displaySpriteAttachments(false);
-
- if (_partEmitter) {
- _partEmitter->display(_region);
- }
-
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::update() {
- _currentSprite = NULL;
-
- if (_state == STATE_READY && _animSprite) {
- delete _animSprite;
- _animSprite = NULL;
- }
-
- // finished playing animation?
- if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
- _state = STATE_READY;
- _currentSprite = _animSprite;
- }
-
- if (_sentence && _state != STATE_TALKING) {
- _sentence->finish();
- }
-
- // default: stand animation
- if (!_currentSprite) {
- _currentSprite = _sprite;
- }
-
- switch (_state) {
- //////////////////////////////////////////////////////////////////////////
- case STATE_PLAYING_ANIM:
- _currentSprite = _animSprite;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_READY:
- if (!_animSprite) {
- _currentSprite = _sprite;
- }
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_TALKING: {
- _sentence->update();
- if (_sentence->_currentSprite) {
- _tempSprite2 = _sentence->_currentSprite;
- }
-
- bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
- if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
- if (timeIsUp) {
- _sentence->finish();
- _tempSprite2 = NULL;
- _state = STATE_READY;
- } else {
- _tempSprite2 = getTalkStance(_sentence->getNextStance());
- if (_tempSprite2) {
- _tempSprite2->reset();
- _currentSprite = _tempSprite2;
- }
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- } else {
- _currentSprite = _tempSprite2;
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- }
- break;
- default: // Silence unhandled enum-warning
- break;
- }
-
-
- if (_currentSprite) {
- _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
- if (_currentSprite->_changed) {
- _posX += _currentSprite->_moveX;
- _posY += _currentSprite->_moveY;
- }
- }
-
- updateBlockRegion();
- _ready = (_state == STATE_READY);
-
- if (_theora) {
- int offsetX, offsetY;
- _gameRef->getOffset(&offsetX, &offsetY);
- _theora->_posX = _posX - offsetX;
- _theora->_posY = _posY - offsetY;
-
- _theora->update();
- if (_theora->isFinished()) {
- _theora->stop();
- delete _theora;
- _theora = NULL;
- }
- }
-
- updatePartEmitter();
- updateSpriteAttachments();
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // StopSound
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "StopSound") == 0 && _subtype == ENTITY_SOUND) {
- stack->correctParams(0);
-
- if (DID_FAIL(stopSFX(false))) {
- stack->pushBool(false);
- } else {
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PlayTheora
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PlayTheora") == 0) {
- stack->correctParams(4);
- const char *filename = stack->pop()->getString();
- bool looping = stack->pop()->getBool(false);
- ScValue *valAlpha = stack->pop();
- int startTime = stack->pop()->getInt();
-
- delete _theora;
- _theora = new VideoTheoraPlayer(_gameRef);
- if (_theora && DID_SUCCEED(_theora->initialize(filename))) {
- if (!valAlpha->isNULL()) {
- _theora->setAlphaImage(valAlpha->getString());
- }
- _theora->play(VID_PLAY_POS, 0, 0, false, false, looping, startTime, _scale >= 0.0f ? _scale : -1.0f, _sFXVolume);
- //if (_scale>=0) _theora->_playZoom = _scale;
- stack->pushBool(true);
- } else {
- script->runtimeError("Entity.PlayTheora - error playing video '%s'", filename);
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // StopTheora
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StopTheora") == 0) {
- stack->correctParams(0);
- if (_theora) {
- _theora->stop();
- delete _theora;
- _theora = NULL;
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsTheoraPlaying
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsTheoraPlaying") == 0) {
- stack->correctParams(0);
- if (_theora && _theora->isPlaying()) {
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PauseTheora
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PauseTheora") == 0) {
- stack->correctParams(0);
- if (_theora && _theora->isPlaying()) {
- _theora->pause();
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ResumeTheora
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ResumeTheora") == 0) {
- stack->correctParams(0);
- if (_theora && _theora->isPaused()) {
- _theora->resume();
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsTheoraPaused
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsTheoraPaused") == 0) {
- stack->correctParams(0);
- if (_theora && _theora->isPaused()) {
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // CreateRegion
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CreateRegion") == 0) {
- stack->correctParams(0);
- if (!_region) {
- _region = new BaseRegion(_gameRef);
- _gameRef->registerObject(_region);
- }
- if (_region) {
- stack->pushNative(_region, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DeleteRegion
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DeleteRegion") == 0) {
- stack->correctParams(0);
- if (_region) {
- _gameRef->unregisterObject(_region);
- _region = NULL;
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
-
- return STATUS_OK;
- } else {
- return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdEntity::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("entity");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Item
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Item") == 0) {
- if (_item) {
- _scValue->setString(_item);
- } else {
- _scValue->setNULL();
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Subtype (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Subtype") == 0) {
- if (_subtype == ENTITY_SOUND) {
- _scValue->setString("sound");
- } else {
- _scValue->setString("normal");
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToX") == 0) {
- _scValue->setInt(_walkToX);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToY") == 0) {
- _scValue->setInt(_walkToY);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToDirection
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToDirection") == 0) {
- _scValue->setInt((int)_walkToDir);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Region (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Region") == 0) {
- if (_region) {
- _scValue->setNative(_region, true);
- } else {
- _scValue->setNULL();
- }
- return _scValue;
- } else {
- return AdTalkHolder::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::scSetProperty(const char *name, ScValue *value) {
-
- //////////////////////////////////////////////////////////////////////////
- // Item
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Item") == 0) {
- setItem(value->getString());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToX") == 0) {
- _walkToX = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToY") == 0) {
- _walkToY = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // WalkToDirection
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "WalkToDirection") == 0) {
- int dir = value->getInt();
- if (dir >= 0 && dir < NUM_DIRECTIONS) {
- _walkToDir = (TDirection)dir;
- }
- return STATUS_OK;
- } else {
- return AdTalkHolder::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdEntity::scToString() {
- return "[entity object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "ENTITY {\n");
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- if (_subtype == ENTITY_SOUND) {
- buffer->putTextIndent(indent + 2, "SUBTYPE=\"SOUND\"\n");
- }
- buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
- buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
- buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
- buffer->putTextIndent(indent + 2, "SCALABLE=%s\n", _zoomable ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "INTERACTIVE=%s\n", _registrable ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "COLORABLE=%s\n", _shadowable ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
- if (_ignoreItems) {
- buffer->putTextIndent(indent + 2, "IGNORE_ITEMS=%s\n", _ignoreItems ? "TRUE" : "FALSE");
- }
- if (_rotatable) {
- buffer->putTextIndent(indent + 2, "ROTATABLE=%s\n", _rotatable ? "TRUE" : "FALSE");
- }
-
- if (!_autoSoundPanning) {
- buffer->putTextIndent(indent + 2, "SOUND_PANNING=%s\n", _autoSoundPanning ? "TRUE" : "FALSE");
- }
-
- if (!_saveState) {
- buffer->putTextIndent(indent + 2, "SAVE_STATE=%s\n", _saveState ? "TRUE" : "FALSE");
- }
-
- if (_item && _item[0] != '\0') {
- buffer->putTextIndent(indent + 2, "ITEM=\"%s\"\n", _item);
- }
-
- buffer->putTextIndent(indent + 2, "WALK_TO_X=%d\n", _walkToX);
- buffer->putTextIndent(indent + 2, "WALK_TO_Y=%d\n", _walkToY);
- if (_walkToDir != DI_NONE) {
- buffer->putTextIndent(indent + 2, "WALK_TO_DIR=%d\n", (int)_walkToDir);
- }
-
- for (uint32 i = 0; i < _scripts.size(); i++) {
- buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
- }
-
- if (_subtype == ENTITY_NORMAL && _sprite && _sprite->getFilename()) {
- buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _sprite->getFilename());
- }
-
- if (_subtype == ENTITY_SOUND && _sFX && _sFX->getFilename()) {
- buffer->putTextIndent(indent + 2, "SOUND=\"%s\"\n", _sFX->getFilename());
- buffer->putTextIndent(indent + 2, "SOUND_START_TIME=%d\n", _sFXStart);
- buffer->putTextIndent(indent + 2, "SOUND_VOLUME=%d\n", _sFXVolume);
- }
-
-
- if (RGBCOLGetR(_alphaColor) != 0 || RGBCOLGetG(_alphaColor) != 0 || RGBCOLGetB(_alphaColor) != 0) {
- buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alphaColor), RGBCOLGetG(_alphaColor), RGBCOLGetB(_alphaColor));
- }
-
- if (RGBCOLGetA(_alphaColor) != 0) {
- buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alphaColor));
- }
-
- if (_scale >= 0) {
- buffer->putTextIndent(indent + 2, "SCALE = %d\n", (int)_scale);
- }
-
- if (_relativeScale != 0) {
- buffer->putTextIndent(indent + 2, "RELATIVE_SCALE = %d\n", (int)_relativeScale);
- }
-
- if (_font && _font->getFilename()) {
- buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename());
- }
-
- if (_cursor && _cursor->getFilename()) {
- buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename());
- }
-
- AdTalkHolder::saveAsText(buffer, indent + 2);
-
- if (_region) {
- _region->saveAsText(buffer, indent + 2);
- }
-
- if (_scProp) {
- _scProp->saveAsText(buffer, indent + 2);
- }
-
- AdObject::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdEntity::getHeight() {
- if (_region && !_sprite) {
- return _region->_rect.bottom - _region->_rect.top;
- } else {
- if (_currentSprite == NULL) {
- _currentSprite = _sprite;
- }
- return AdObject::getHeight();
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdEntity::updatePosition() {
- if (_region && !_sprite) {
- _posX = _region->_rect.left + (_region->_rect.right - _region->_rect.left) / 2;
- _posY = _region->_rect.bottom;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::persist(BasePersistenceManager *persistMgr) {
- AdTalkHolder::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_item));
- persistMgr->transfer(TMEMBER(_region));
- //persistMgr->transfer(TMEMBER(_sprite));
- persistMgr->transfer(TMEMBER_INT(_subtype));
- _talkSprites.persist(persistMgr);
- _talkSpritesEx.persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_walkToX));
- persistMgr->transfer(TMEMBER(_walkToY));
- persistMgr->transfer(TMEMBER_INT(_walkToDir));
-
- persistMgr->transfer(TMEMBER(_theora));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdEntity::setItem(const char *itemName) {
- BaseUtils::setString(&_item, itemName);
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdEntity::setSprite(const char *filename) {
- if (_currentSprite == _sprite) {
- _currentSprite = NULL;
- }
-
- delete _sprite;
- _sprite = NULL;
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- delete _sprite;
- _sprite = NULL;
- return STATUS_FAILED;
- } else {
- _sprite = spr;
- _currentSprite = _sprite;
- 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/ad/ad_entity.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_active_rect.h"
+#include "engines/wintermute/base/base_surface_storage.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_scene.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/ad/ad_waypoint_group.h"
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/base/base_region.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/utils/utils.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/video/video_theora_player.h"
+#include "engines/wintermute/base/particles/part_emitter.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdEntity, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdEntity::AdEntity(BaseGame *inGame) : AdTalkHolder(inGame) {
+ _type = OBJECT_ENTITY;
+ _subtype = ENTITY_NORMAL;
+ _region = NULL;
+ _item = NULL;
+
+ _walkToX = _walkToY = 0;
+ _walkToDir = DI_NONE;
+
+ _theora = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdEntity::~AdEntity() {
+ _gameRef->unregisterObject(_region);
+
+ delete _theora;
+ _theora = NULL;
+
+ delete[] _item;
+ _item = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdEntity::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing ENTITY file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(ENTITY)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(X)
+TOKEN_DEF(Y)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(SCALABLE)
+TOKEN_DEF(REGISTRABLE)
+TOKEN_DEF(INTERACTIVE)
+TOKEN_DEF(SHADOWABLE)
+TOKEN_DEF(COLORABLE)
+TOKEN_DEF(ACTIVE)
+TOKEN_DEF(EVENTS)
+TOKEN_DEF(FONT)
+TOKEN_DEF(TALK_SPECIAL)
+TOKEN_DEF(TALK)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(REGION)
+TOKEN_DEF(BLOCKED_REGION)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(SOUND_START_TIME)
+TOKEN_DEF(SOUND_VOLUME)
+TOKEN_DEF(SOUND_PANNING)
+TOKEN_DEF(SOUND)
+TOKEN_DEF(SUBTYPE)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(WAYPOINTS)
+TOKEN_DEF(IGNORE_ITEMS)
+TOKEN_DEF(ROTABLE)
+TOKEN_DEF(ROTATABLE)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(SCALE)
+TOKEN_DEF(RELATIVE_SCALE)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(ITEM)
+TOKEN_DEF(WALK_TO_X)
+TOKEN_DEF(WALK_TO_Y)
+TOKEN_DEF(WALK_TO_DIR)
+TOKEN_DEF(SAVE_STATE)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ENTITY)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(X)
+ TOKEN_TABLE(Y)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(SCALABLE)
+ TOKEN_TABLE(REGISTRABLE)
+ TOKEN_TABLE(INTERACTIVE)
+ TOKEN_TABLE(SHADOWABLE)
+ TOKEN_TABLE(COLORABLE)
+ TOKEN_TABLE(ACTIVE)
+ TOKEN_TABLE(EVENTS)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(TALK_SPECIAL)
+ TOKEN_TABLE(TALK)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(REGION)
+ TOKEN_TABLE(BLOCKED_REGION)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(SOUND_START_TIME)
+ TOKEN_TABLE(SOUND_VOLUME)
+ TOKEN_TABLE(SOUND_PANNING)
+ TOKEN_TABLE(SOUND)
+ TOKEN_TABLE(SUBTYPE)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(WAYPOINTS)
+ TOKEN_TABLE(IGNORE_ITEMS)
+ TOKEN_TABLE(ROTABLE)
+ TOKEN_TABLE(ROTATABLE)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(SCALE)
+ TOKEN_TABLE(RELATIVE_SCALE)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(ITEM)
+ TOKEN_TABLE(WALK_TO_X)
+ TOKEN_TABLE(WALK_TO_Y)
+ TOKEN_TABLE(WALK_TO_DIR)
+ TOKEN_TABLE(SAVE_STATE)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY) {
+ _gameRef->LOG(0, "'ENTITY' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ AdGame *adGame = (AdGame *)_gameRef;
+ BaseSprite *spr = NULL;
+ int ar = 0, ag = 0, ab = 0, alpha = 0;
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_X:
+ parser.scanStr((char *)params, "%d", &_posX);
+ break;
+
+ case TOKEN_Y:
+ parser.scanStr((char *)params, "%d", &_posY);
+ break;
+
+ case TOKEN_SPRITE: {
+ delete _sprite;
+ _sprite = NULL;
+ spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprite = spr;
+ }
+ }
+ break;
+
+ case TOKEN_TALK: {
+ spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSprites.add(spr);
+ }
+ }
+ break;
+
+ case TOKEN_TALK_SPECIAL: {
+ spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSpritesEx.add(spr);
+ }
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_ITEM:
+ setItem((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_FONT:
+ setFont((char *)params);
+ break;
+
+ case TOKEN_SCALABLE:
+ parser.scanStr((char *)params, "%b", &_zoomable);
+ break;
+
+ case TOKEN_SCALE: {
+ int s;
+ parser.scanStr((char *)params, "%d", &s);
+ _scale = (float)s;
+
+ }
+ break;
+
+ case TOKEN_RELATIVE_SCALE: {
+ int s;
+ parser.scanStr((char *)params, "%d", &s);
+ _relativeScale = (float)s;
+
+ }
+ break;
+
+ case TOKEN_ROTABLE:
+ case TOKEN_ROTATABLE:
+ parser.scanStr((char *)params, "%b", &_rotatable);
+ break;
+
+ case TOKEN_REGISTRABLE:
+ case TOKEN_INTERACTIVE:
+ parser.scanStr((char *)params, "%b", &_registrable);
+ break;
+
+ case TOKEN_SHADOWABLE:
+ case TOKEN_COLORABLE:
+ parser.scanStr((char *)params, "%b", &_shadowable);
+ break;
+
+ case TOKEN_ACTIVE:
+ parser.scanStr((char *)params, "%b", &_active);
+ break;
+
+ case TOKEN_CURSOR:
+ delete _cursor;
+ _cursor = new BaseSprite(_gameRef);
+ if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ delete _cursor;
+ _cursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.scanStr((char *)params, "%b", &_editorSelected);
+ break;
+
+ case TOKEN_REGION: {
+ if (_region) {
+ _gameRef->unregisterObject(_region);
+ }
+ _region = NULL;
+ BaseRegion *rgn = new BaseRegion(_gameRef);
+ if (!rgn || DID_FAIL(rgn->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _region = rgn;
+ _gameRef->registerObject(_region);
+ }
+ }
+ break;
+
+ case TOKEN_BLOCKED_REGION: {
+ delete _blockRegion;
+ _blockRegion = NULL;
+ delete _currentBlockRegion;
+ _currentBlockRegion = NULL;
+ BaseRegion *rgn = new BaseRegion(_gameRef);
+ BaseRegion *crgn = new BaseRegion(_gameRef);
+ if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) {
+ delete _blockRegion;
+ _blockRegion = NULL;
+ delete _currentBlockRegion;
+ _currentBlockRegion = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ _blockRegion = rgn;
+ _currentBlockRegion = crgn;
+ _currentBlockRegion->mimic(_blockRegion);
+ }
+ }
+ break;
+
+ case TOKEN_WAYPOINTS: {
+ delete _wptGroup;
+ _wptGroup = NULL;
+ delete _currentWptGroup;
+ _currentWptGroup = NULL;
+ AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
+ AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef);
+ if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) {
+ delete _wptGroup;
+ _wptGroup = NULL;
+ delete _currentWptGroup;
+ _currentWptGroup = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ _wptGroup = wpt;
+ _currentWptGroup = cwpt;
+ _currentWptGroup->mimic(_wptGroup);
+ }
+ }
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_SUBTYPE: {
+ if (scumm_stricmp((char *)params, "sound") == 0) {
+ delete _sprite;
+ _sprite = NULL;
+ if (_gameRef->_editorMode) {
+ spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile("entity_sound.sprite"))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprite = spr;
+ }
+ }
+ if (_gameRef->_editorMode) {
+ _editorOnly = true;
+ }
+ _zoomable = false;
+ _rotatable = false;
+ _registrable = _gameRef->_editorMode;
+ _shadowable = false;
+ _subtype = ENTITY_SOUND;
+ }
+ }
+ break;
+
+ case TOKEN_SOUND:
+ playSFX((char *)params, false, false);
+ break;
+
+ case TOKEN_SOUND_START_TIME:
+ parser.scanStr((char *)params, "%d", &_sFXStart);
+ break;
+
+ case TOKEN_SOUND_VOLUME:
+ parser.scanStr((char *)params, "%d", &_sFXVolume);
+ break;
+
+ case TOKEN_SOUND_PANNING:
+ parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ break;
+
+ case TOKEN_SAVE_STATE:
+ parser.scanStr((char *)params, "%b", &_saveState);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_IGNORE_ITEMS:
+ parser.scanStr((char *)params, "%b", &_ignoreItems);
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.scanStr((char *)params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+
+ case TOKEN_WALK_TO_X:
+ parser.scanStr((char *)params, "%d", &_walkToX);
+ break;
+
+ case TOKEN_WALK_TO_Y:
+ parser.scanStr((char *)params, "%d", &_walkToY);
+ break;
+
+ case TOKEN_WALK_TO_DIR: {
+ int i;
+ parser.scanStr((char *)params, "%d", &i);
+ if (i < 0) {
+ i = 0;
+ }
+ if (i >= NUM_DIRECTIONS) {
+ i = DI_NONE;
+ }
+ _walkToDir = (TDirection)i;
+ }
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ENTITY definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading ENTITY definition");
+ if (spr) {
+ delete spr;
+ }
+ return STATUS_FAILED;
+ }
+
+ if (_region && _sprite) {
+ _gameRef->LOG(0, "Warning: Entity '%s' has both sprite and region.", getName());
+ }
+
+ updatePosition();
+
+ if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
+ ar = ag = ab = 255;
+ }
+ _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
+ _state = STATE_READY;
+
+ if (_item && ((AdGame *)_gameRef)->isItemTaken(_item)) {
+ _active = false;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::display() {
+ if (_active) {
+ updateSounds();
+
+ uint32 alpha;
+ if (_alphaColor != 0) {
+ alpha = _alphaColor;
+ } else {
+ alpha = _shadowable ? ((AdGame *)_gameRef)->_scene->getAlphaAt(_posX, _posY) : 0xFFFFFFFF;
+ }
+
+ float scaleX, scaleY;
+ getScale(&scaleX, &scaleY);
+
+ float rotate;
+ if (_rotatable) {
+ if (_rotateValid) {
+ rotate = _rotate;
+ } else {
+ rotate = ((AdGame *)_gameRef)->_scene->getRotationAt(_posX, _posY) + _relativeRotate;
+ }
+ } else {
+ rotate = 0.0f;
+ }
+
+
+ bool reg = _registrable;
+ if (_ignoreItems && ((AdGame *)_gameRef)->_selectedItem) {
+ reg = false;
+ }
+
+ if (_region && (reg || _editorAlwaysRegister)) {
+ _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, _registerAlias, _region, _gameRef->_offsetX, _gameRef->_offsetY));
+ }
+
+ displaySpriteAttachments(true);
+ if (_theora && (_theora->isPlaying() || _theora->isPaused())) {
+ _theora->display(alpha);
+ } else if (_currentSprite) {
+ _currentSprite->display(_posX,
+ _posY,
+ (reg || _editorAlwaysRegister) ? _registerAlias : NULL,
+ scaleX,
+ scaleY,
+ alpha,
+ rotate,
+ _blendMode);
+ }
+ displaySpriteAttachments(false);
+
+ if (_partEmitter) {
+ _partEmitter->display(_region);
+ }
+
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::update() {
+ _currentSprite = NULL;
+
+ if (_state == STATE_READY && _animSprite) {
+ delete _animSprite;
+ _animSprite = NULL;
+ }
+
+ // finished playing animation?
+ if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
+ _state = STATE_READY;
+ _currentSprite = _animSprite;
+ }
+
+ if (_sentence && _state != STATE_TALKING) {
+ _sentence->finish();
+ }
+
+ // default: stand animation
+ if (!_currentSprite) {
+ _currentSprite = _sprite;
+ }
+
+ switch (_state) {
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_PLAYING_ANIM:
+ _currentSprite = _animSprite;
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_READY:
+ if (!_animSprite) {
+ _currentSprite = _sprite;
+ }
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_TALKING: {
+ _sentence->update();
+ if (_sentence->_currentSprite) {
+ _tempSprite2 = _sentence->_currentSprite;
+ }
+
+ bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
+ if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
+ if (timeIsUp) {
+ _sentence->finish();
+ _tempSprite2 = NULL;
+ _state = STATE_READY;
+ } else {
+ _tempSprite2 = getTalkStance(_sentence->getNextStance());
+ if (_tempSprite2) {
+ _tempSprite2->reset();
+ _currentSprite = _tempSprite2;
+ }
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ } else {
+ _currentSprite = _tempSprite2;
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ }
+ break;
+ default: // Silence unhandled enum-warning
+ break;
+ }
+
+
+ if (_currentSprite) {
+ _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100);
+ if (_currentSprite->_changed) {
+ _posX += _currentSprite->_moveX;
+ _posY += _currentSprite->_moveY;
+ }
+ }
+
+ updateBlockRegion();
+ _ready = (_state == STATE_READY);
+
+ if (_theora) {
+ int offsetX, offsetY;
+ _gameRef->getOffset(&offsetX, &offsetY);
+ _theora->_posX = _posX - offsetX;
+ _theora->_posY = _posY - offsetY;
+
+ _theora->update();
+ if (_theora->isFinished()) {
+ _theora->stop();
+ delete _theora;
+ _theora = NULL;
+ }
+ }
+
+ updatePartEmitter();
+ updateSpriteAttachments();
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // StopSound
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "StopSound") == 0 && _subtype == ENTITY_SOUND) {
+ stack->correctParams(0);
+
+ if (DID_FAIL(stopSFX(false))) {
+ stack->pushBool(false);
+ } else {
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlayTheora
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PlayTheora") == 0) {
+ stack->correctParams(4);
+ const char *filename = stack->pop()->getString();
+ bool looping = stack->pop()->getBool(false);
+ ScValue *valAlpha = stack->pop();
+ int startTime = stack->pop()->getInt();
+
+ delete _theora;
+ _theora = new VideoTheoraPlayer(_gameRef);
+ if (_theora && DID_SUCCEED(_theora->initialize(filename))) {
+ if (!valAlpha->isNULL()) {
+ _theora->setAlphaImage(valAlpha->getString());
+ }
+ _theora->play(VID_PLAY_POS, 0, 0, false, false, looping, startTime, _scale >= 0.0f ? _scale : -1.0f, _sFXVolume);
+ //if (_scale>=0) _theora->_playZoom = _scale;
+ stack->pushBool(true);
+ } else {
+ script->runtimeError("Entity.PlayTheora - error playing video '%s'", filename);
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StopTheora
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StopTheora") == 0) {
+ stack->correctParams(0);
+ if (_theora) {
+ _theora->stop();
+ delete _theora;
+ _theora = NULL;
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsTheoraPlaying
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsTheoraPlaying") == 0) {
+ stack->correctParams(0);
+ if (_theora && _theora->isPlaying()) {
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PauseTheora
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PauseTheora") == 0) {
+ stack->correctParams(0);
+ if (_theora && _theora->isPlaying()) {
+ _theora->pause();
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ResumeTheora
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ResumeTheora") == 0) {
+ stack->correctParams(0);
+ if (_theora && _theora->isPaused()) {
+ _theora->resume();
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsTheoraPaused
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsTheoraPaused") == 0) {
+ stack->correctParams(0);
+ if (_theora && _theora->isPaused()) {
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateRegion
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CreateRegion") == 0) {
+ stack->correctParams(0);
+ if (!_region) {
+ _region = new BaseRegion(_gameRef);
+ _gameRef->registerObject(_region);
+ }
+ if (_region) {
+ stack->pushNative(_region, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteRegion
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DeleteRegion") == 0) {
+ stack->correctParams(0);
+ if (_region) {
+ _gameRef->unregisterObject(_region);
+ _region = NULL;
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdEntity::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("entity");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Item
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Item") == 0) {
+ if (_item) {
+ _scValue->setString(_item);
+ } else {
+ _scValue->setNULL();
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Subtype (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Subtype") == 0) {
+ if (_subtype == ENTITY_SOUND) {
+ _scValue->setString("sound");
+ } else {
+ _scValue->setString("normal");
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToX") == 0) {
+ _scValue->setInt(_walkToX);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToY") == 0) {
+ _scValue->setInt(_walkToY);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToDirection
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToDirection") == 0) {
+ _scValue->setInt((int)_walkToDir);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Region (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Region") == 0) {
+ if (_region) {
+ _scValue->setNative(_region, true);
+ } else {
+ _scValue->setNULL();
+ }
+ return _scValue;
+ } else {
+ return AdTalkHolder::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::scSetProperty(const char *name, ScValue *value) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // Item
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Item") == 0) {
+ setItem(value->getString());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToX") == 0) {
+ _walkToX = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToY") == 0) {
+ _walkToY = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WalkToDirection
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "WalkToDirection") == 0) {
+ int dir = value->getInt();
+ if (dir >= 0 && dir < NUM_DIRECTIONS) {
+ _walkToDir = (TDirection)dir;
+ }
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdEntity::scToString() {
+ return "[entity object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "ENTITY {\n");
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ if (_subtype == ENTITY_SOUND) {
+ buffer->putTextIndent(indent + 2, "SUBTYPE=\"SOUND\"\n");
+ }
+ buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
+ buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
+ buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
+ buffer->putTextIndent(indent + 2, "SCALABLE=%s\n", _zoomable ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "INTERACTIVE=%s\n", _registrable ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "COLORABLE=%s\n", _shadowable ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
+ if (_ignoreItems) {
+ buffer->putTextIndent(indent + 2, "IGNORE_ITEMS=%s\n", _ignoreItems ? "TRUE" : "FALSE");
+ }
+ if (_rotatable) {
+ buffer->putTextIndent(indent + 2, "ROTATABLE=%s\n", _rotatable ? "TRUE" : "FALSE");
+ }
+
+ if (!_autoSoundPanning) {
+ buffer->putTextIndent(indent + 2, "SOUND_PANNING=%s\n", _autoSoundPanning ? "TRUE" : "FALSE");
+ }
+
+ if (!_saveState) {
+ buffer->putTextIndent(indent + 2, "SAVE_STATE=%s\n", _saveState ? "TRUE" : "FALSE");
+ }
+
+ if (_item && _item[0] != '\0') {
+ buffer->putTextIndent(indent + 2, "ITEM=\"%s\"\n", _item);
+ }
+
+ buffer->putTextIndent(indent + 2, "WALK_TO_X=%d\n", _walkToX);
+ buffer->putTextIndent(indent + 2, "WALK_TO_Y=%d\n", _walkToY);
+ if (_walkToDir != DI_NONE) {
+ buffer->putTextIndent(indent + 2, "WALK_TO_DIR=%d\n", (int)_walkToDir);
+ }
+
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
+ }
+
+ if (_subtype == ENTITY_NORMAL && _sprite && _sprite->getFilename()) {
+ buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _sprite->getFilename());
+ }
+
+ if (_subtype == ENTITY_SOUND && _sFX && _sFX->getFilename()) {
+ buffer->putTextIndent(indent + 2, "SOUND=\"%s\"\n", _sFX->getFilename());
+ buffer->putTextIndent(indent + 2, "SOUND_START_TIME=%d\n", _sFXStart);
+ buffer->putTextIndent(indent + 2, "SOUND_VOLUME=%d\n", _sFXVolume);
+ }
+
+
+ if (RGBCOLGetR(_alphaColor) != 0 || RGBCOLGetG(_alphaColor) != 0 || RGBCOLGetB(_alphaColor) != 0) {
+ buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alphaColor), RGBCOLGetG(_alphaColor), RGBCOLGetB(_alphaColor));
+ }
+
+ if (RGBCOLGetA(_alphaColor) != 0) {
+ buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alphaColor));
+ }
+
+ if (_scale >= 0) {
+ buffer->putTextIndent(indent + 2, "SCALE = %d\n", (int)_scale);
+ }
+
+ if (_relativeScale != 0) {
+ buffer->putTextIndent(indent + 2, "RELATIVE_SCALE = %d\n", (int)_relativeScale);
+ }
+
+ if (_font && _font->getFilename()) {
+ buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename());
+ }
+
+ if (_cursor && _cursor->getFilename()) {
+ buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename());
+ }
+
+ AdTalkHolder::saveAsText(buffer, indent + 2);
+
+ if (_region) {
+ _region->saveAsText(buffer, indent + 2);
+ }
+
+ if (_scProp) {
+ _scProp->saveAsText(buffer, indent + 2);
+ }
+
+ AdObject::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdEntity::getHeight() {
+ if (_region && !_sprite) {
+ return _region->_rect.bottom - _region->_rect.top;
+ } else {
+ if (_currentSprite == NULL) {
+ _currentSprite = _sprite;
+ }
+ return AdObject::getHeight();
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdEntity::updatePosition() {
+ if (_region && !_sprite) {
+ _posX = _region->_rect.left + (_region->_rect.right - _region->_rect.left) / 2;
+ _posY = _region->_rect.bottom;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::persist(BasePersistenceManager *persistMgr) {
+ AdTalkHolder::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_item));
+ persistMgr->transfer(TMEMBER(_region));
+ //persistMgr->transfer(TMEMBER(_sprite));
+ persistMgr->transfer(TMEMBER_INT(_subtype));
+ _talkSprites.persist(persistMgr);
+ _talkSpritesEx.persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_walkToX));
+ persistMgr->transfer(TMEMBER(_walkToY));
+ persistMgr->transfer(TMEMBER_INT(_walkToDir));
+
+ persistMgr->transfer(TMEMBER(_theora));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdEntity::setItem(const char *itemName) {
+ BaseUtils::setString(&_item, itemName);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdEntity::setSprite(const char *filename) {
+ if (_currentSprite == _sprite) {
+ _currentSprite = NULL;
+ }
+
+ delete _sprite;
+ _sprite = NULL;
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ delete _sprite;
+ _sprite = NULL;
+ return STATUS_FAILED;
+ } else {
+ _sprite = spr;
+ _currentSprite = _sprite;
+ return STATUS_OK;
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_entity.h b/engines/wintermute/ad/ad_entity.h
index 2178563534..39dc133eef 100644
--- a/engines/wintermute/ad/ad_entity.h
+++ b/engines/wintermute/ad/ad_entity.h
@@ -1,68 +1,68 @@
-/* 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_ADENTITY_H
-#define WINTERMUTE_ADENTITY_H
-
-#include "engines/wintermute/ad/ad_talk_holder.h"
-
-namespace Wintermute {
-class VideoTheoraPlayer;
-class AdEntity : public AdTalkHolder {
-public:
- VideoTheoraPlayer *_theora;
- bool setSprite(const char *filename);
- int _walkToX;
- int _walkToY;
- TDirection _walkToDir;
- void setItem(const char *itemName);
- char *_item;
- DECLARE_PERSISTENT(AdEntity, AdTalkHolder)
- void updatePosition();
- virtual int getHeight();
- BaseRegion *_region;
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- virtual bool update();
- virtual bool display();
- AdEntity(BaseGame *inGame);
- virtual ~AdEntity();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- TEntityType _subtype;
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-
-};
-
-} // 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_ADENTITY_H
+#define WINTERMUTE_ADENTITY_H
+
+#include "engines/wintermute/ad/ad_talk_holder.h"
+
+namespace Wintermute {
+class VideoTheoraPlayer;
+class AdEntity : public AdTalkHolder {
+public:
+ VideoTheoraPlayer *_theora;
+ bool setSprite(const char *filename);
+ int _walkToX;
+ int _walkToY;
+ TDirection _walkToDir;
+ void setItem(const char *itemName);
+ char *_item;
+ DECLARE_PERSISTENT(AdEntity, AdTalkHolder)
+ void updatePosition();
+ virtual int getHeight();
+ BaseRegion *_region;
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ virtual bool update();
+ virtual bool display();
+ AdEntity(BaseGame *inGame);
+ virtual ~AdEntity();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ TEntityType _subtype;
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp
index f5d865d9f8..fe8a5991e2 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -1,2280 +1,2280 @@
-/* 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/ad/ad_actor.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_entity.h"
-#include "engines/wintermute/ad/ad_inventory.h"
-#include "engines/wintermute/ad/ad_inventory_box.h"
-#include "engines/wintermute/ad/ad_item.h"
-#include "engines/wintermute/ad/ad_response.h"
-#include "engines/wintermute/ad/ad_response_box.h"
-#include "engines/wintermute/ad/ad_response_context.h"
-#include "engines/wintermute/ad/ad_scene.h"
-#include "engines/wintermute/ad/ad_scene_state.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/base_object.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/base/base_string_table.h"
-#include "engines/wintermute/base/base_surface_storage.h"
-#include "engines/wintermute/base/base_transition_manager.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_viewport.h"
-#include "engines/wintermute/base/particles/part_emitter.h"
-#include "engines/wintermute/base/saveload.h"
-#include "engines/wintermute/base/scriptables/script_engine.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/ui/ui_entity.h"
-#include "engines/wintermute/ui/ui_window.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/video/video_player.h"
-#include "engines/wintermute/video/video_theora_player.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdGame, true)
-
-//////////////////////////////////////////////////////////////////////////
-AdGame::AdGame(const Common::String &gameId) : BaseGame(gameId) {
- _responseBox = NULL;
- _inventoryBox = NULL;
-
- _scene = new AdScene(_gameRef);
- _scene->setName("");
- registerObject(_scene);
-
- _prevSceneName = NULL;
- _prevSceneFilename = NULL;
- _scheduledScene = NULL;
- _scheduledFadeIn = false;
-
-
- _stateEx = GAME_NORMAL;
-
- _selectedItem = NULL;
-
-
- _texItemLifeTime = 10000;
- _texWalkLifeTime = 10000;
- _texStandLifeTime = 10000;
- _texTalkLifeTime = 10000;
-
- _talkSkipButton = TALK_SKIP_LEFT;
-
- _sceneViewport = NULL;
-
- _initialScene = true;
- _debugStartupScene = NULL;
- _startupScene = NULL;
-
- _invObject = new AdObject(this);
- _inventoryOwner = _invObject;
-
- _tempDisableSaveState = false;
- _itemsFile = NULL;
-
- _smartItemCursor = false;
-
- addSpeechDir("speech");
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdGame::~AdGame() {
- cleanup();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::cleanup() {
- for (uint32 i = 0; i < _objects.size(); i++) {
- unregisterObject(_objects[i]);
- _objects[i] = NULL;
- }
- _objects.clear();
-
-
- for (uint32 i = 0; i < _dlgPendingBranches.size(); i++) {
- delete[] _dlgPendingBranches[i];
- }
- _dlgPendingBranches.clear();
-
- for (uint32 i = 0; i < _speechDirs.size(); i++) {
- delete[] _speechDirs[i];
- }
- _speechDirs.clear();
-
-
- unregisterObject(_scene);
- _scene = NULL;
-
- // remove items
- for (uint32 i = 0; i < _items.size(); i++) {
- _gameRef->unregisterObject(_items[i]);
- }
- _items.clear();
-
-
- // clear remaining inventories
- delete _invObject;
- _invObject = NULL;
-
- for (uint32 i = 0; i < _inventories.size(); i++) {
- delete _inventories[i];
- }
- _inventories.clear();
-
-
- if (_responseBox) {
- _gameRef->unregisterObject(_responseBox);
- _responseBox = NULL;
- }
-
- if (_inventoryBox) {
- _gameRef->unregisterObject(_inventoryBox);
- _inventoryBox = NULL;
- }
-
- delete[] _prevSceneName;
- delete[] _prevSceneFilename;
- delete[] _scheduledScene;
- delete[] _debugStartupScene;
- delete[] _itemsFile;
- _prevSceneName = NULL;
- _prevSceneFilename = NULL;
- _scheduledScene = NULL;
- _debugStartupScene = NULL;
- _startupScene = NULL;
- _itemsFile = NULL;
-
- delete _sceneViewport;
- _sceneViewport = NULL;
-
- for (uint32 i = 0; i < _sceneStates.size(); i++) {
- delete _sceneStates[i];
- }
- _sceneStates.clear();
-
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- delete _responsesBranch[i];
- }
- _responsesBranch.clear();
-
- for (uint32 i = 0; i < _responsesGame.size(); i++) {
- delete _responsesGame[i];
- }
- _responsesGame.clear();
-
- return BaseGame::cleanup();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::initLoop() {
- if (_scheduledScene && _transMgr->isReady()) {
- changeScene(_scheduledScene, _scheduledFadeIn);
- delete[] _scheduledScene;
- _scheduledScene = NULL;
-
- _gameRef->_activeObject = NULL;
- }
-
-
- bool res;
- res = BaseGame::initLoop();
- if (DID_FAIL(res)) {
- return res;
- }
-
- if (_scene) {
- res = _scene->initLoop();
- }
-
- _sentences.clear();
-
- return res;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::addObject(AdObject *object) {
- _objects.add(object);
- return registerObject(object);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::removeObject(AdObject *object) {
- // in case the user called Scene.CreateXXX() and Game.DeleteXXX()
- if (_scene) {
- bool res = _scene->removeObject(object);
- if (DID_SUCCEED(res)) {
- return res;
- }
- }
-
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i] == object) {
- _objects.remove_at(i);
- break;
- }
- }
- return unregisterObject(object);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::changeScene(const char *filename, bool fadeIn) {
- if (_scene == NULL) {
- _scene = new AdScene(_gameRef);
- registerObject(_scene);
- } else {
- _scene->applyEvent("SceneShutdown", true);
-
- setPrevSceneName(_scene->getName());
- setPrevSceneFilename(_scene->getFilename());
-
- if (!_tempDisableSaveState) {
- _scene->saveState();
- }
- _tempDisableSaveState = false;
- }
-
- if (_scene) {
- // reset objects
- for (uint32 i = 0; i < _objects.size(); i++) {
- _objects[i]->reset();
- }
-
- // reset scene properties
- _scene->_sFXVolume = 100;
- if (_scene->_scProp) {
- _scene->_scProp->cleanup();
- }
-
- bool ret;
- if (_initialScene && _debugDebugMode && _debugStartupScene) {
- _initialScene = false;
- ret = _scene->loadFile(_debugStartupScene);
- } else {
- ret = _scene->loadFile(filename);
- }
-
- if (DID_SUCCEED(ret)) {
- // invalidate references to the original scene
- for (uint32 i = 0; i < _objects.size(); i++) {
- _objects[i]->invalidateCurrRegions();
- _objects[i]->_stickRegion = NULL;
- }
-
- _scene->loadState();
- }
- if (fadeIn) {
- _gameRef->_transMgr->start(TRANSITION_FADE_IN);
- }
- return ret;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdGame::addSentence(AdSentence *sentence) {
- _sentences.add(sentence);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::displaySentences(bool frozen) {
- for (uint32 i = 0; i < _sentences.size(); i++) {
- if (frozen && _sentences[i]->_freezable) {
- continue;
- } else {
- _sentences[i]->display();
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdGame::finishSentences() {
- for (uint32 i = 0; i < _sentences.size(); i++) {
- if (_sentences[i]->canSkip()) {
- _sentences[i]->_duration = 0;
- if (_sentences[i]->_sound) {
- _sentences[i]->_sound->stop();
- }
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // ChangeScene
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "ChangeScene") == 0) {
- stack->correctParams(3);
- const char *filename = stack->pop()->getString();
- ScValue *valFadeOut = stack->pop();
- ScValue *valFadeIn = stack->pop();
-
- bool transOut = valFadeOut->isNULL() ? true : valFadeOut->getBool();
- bool transIn = valFadeIn->isNULL() ? true : valFadeIn->getBool();
-
- scheduleChangeScene(filename, transIn);
- if (transOut) {
- _transMgr->start(TRANSITION_FADE_OUT, true);
- }
- stack->pushNULL();
-
-
- //bool ret = ChangeScene(stack->pop()->getString());
- //if (DID_FAIL(ret)) stack->pushBool(false);
- //else stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadActor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadActor") == 0) {
- stack->correctParams(1);
- AdActor *act = new AdActor(_gameRef);
- if (act && DID_SUCCEED(act->loadFile(stack->pop()->getString()))) {
- addObject(act);
- stack->pushNative(act, true);
- } else {
- delete act;
- act = NULL;
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadEntity") == 0) {
- stack->correctParams(1);
- AdEntity *ent = new AdEntity(_gameRef);
- if (ent && DID_SUCCEED(ent->loadFile(stack->pop()->getString()))) {
- addObject(ent);
- stack->pushNative(ent, true);
- } else {
- delete ent;
- ent = NULL;
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // UnloadObject / UnloadActor / UnloadEntity / DeleteEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "UnloadObject") == 0 || strcmp(name, "UnloadActor") == 0 || strcmp(name, "UnloadEntity") == 0 || strcmp(name, "DeleteEntity") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- AdObject *obj = (AdObject *)val->getNative();
- removeObject(obj);
- if (val->getType() == VAL_VARIABLE_REF) {
- val->setNULL();
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CreateEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CreateEntity") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdEntity *ent = new AdEntity(_gameRef);
- addObject(ent);
- if (!val->isNULL()) {
- ent->setName(val->getString());
- }
- stack->pushNative(ent, true);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CreateItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CreateItem") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdItem *item = new AdItem(_gameRef);
- addItem(item);
- if (!val->isNULL()) {
- item->setName(val->getString());
- }
- stack->pushNative(item, true);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DeleteItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DeleteItem") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdItem *item = NULL;
- if (val->isNative()) {
- item = (AdItem *)val->getNative();
- } else {
- item = getItemByName(val->getString());
- }
-
- if (item) {
- deleteItem(item);
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // QueryItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "QueryItem") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdItem *item = NULL;
- if (val->isInt()) {
- int index = val->getInt();
- if (index >= 0 && index < (int32)_items.size()) {
- item = _items[index];
- }
- } else {
- item = getItemByName(val->getString());
- }
-
- if (item) {
- stack->pushNative(item, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // AddResponse/AddResponseOnce/AddResponseOnceGame
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddResponse") == 0 || strcmp(name, "AddResponseOnce") == 0 || strcmp(name, "AddResponseOnceGame") == 0) {
- stack->correctParams(6);
- int id = stack->pop()->getInt();
- const char *text = stack->pop()->getString();
- ScValue *val1 = stack->pop();
- ScValue *val2 = stack->pop();
- ScValue *val3 = stack->pop();
- ScValue *val4 = stack->pop();
-
- if (_responseBox) {
- AdResponse *res = new AdResponse(_gameRef);
- if (res) {
- res->_iD = id;
- res->setText(text);
- _stringTable->expand(&res->_text);
- if (!val1->isNULL()) {
- res->setIcon(val1->getString());
- }
- if (!val2->isNULL()) {
- res->setIconHover(val2->getString());
- }
- if (!val3->isNULL()) {
- res->setIconPressed(val3->getString());
- }
- if (!val4->isNULL()) {
- res->setFont(val4->getString());
- }
-
- if (strcmp(name, "AddResponseOnce") == 0) {
- res->_responseType = RESPONSE_ONCE;
- } else if (strcmp(name, "AddResponseOnceGame") == 0) {
- res->_responseType = RESPONSE_ONCE_GAME;
- }
-
- _responseBox->_responses.add(res);
- }
- } else {
- script->runtimeError("Game.AddResponse: response box is not defined");
- }
- stack->pushNULL();
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ResetResponse
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ResetResponse") == 0) {
- stack->correctParams(1);
- int id = stack->pop()->getInt(-1);
- resetResponse(id);
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ClearResponses
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ClearResponses") == 0) {
- stack->correctParams(0);
- _responseBox->clearResponses();
- _responseBox->clearButtons();
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetResponse
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetResponse") == 0) {
- stack->correctParams(1);
- bool autoSelectLast = stack->pop()->getBool();
-
- if (_responseBox) {
- _responseBox->weedResponses();
-
- if (_responseBox->_responses.size() == 0) {
- stack->pushNULL();
- return STATUS_OK;
- }
-
-
- if (_responseBox->_responses.size() == 1 && autoSelectLast) {
- stack->pushInt(_responseBox->_responses[0]->_iD);
- _responseBox->handleResponse(_responseBox->_responses[0]);
- _responseBox->clearResponses();
- return STATUS_OK;
- }
-
- _responseBox->createButtons();
- _responseBox->_waitingScript = script;
- script->waitForExclusive(_responseBox);
- _state = GAME_SEMI_FROZEN;
- _stateEx = GAME_WAITING_RESPONSE;
- } else {
- script->runtimeError("Game.GetResponse: response box is not defined");
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // GetNumResponses
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetNumResponses") == 0) {
- stack->correctParams(0);
- if (_responseBox) {
- _responseBox->weedResponses();
- stack->pushInt(_responseBox->_responses.size());
- } else {
- script->runtimeError("Game.GetNumResponses: response box is not defined");
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // StartDlgBranch
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StartDlgBranch") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- Common::String branchName;
- if (val->isNULL()) {
- branchName.format("line%d", script->_currentLine);
- } else {
- branchName = val->getString();
- }
-
- startDlgBranch(branchName.c_str(), script->_filename == NULL ? "" : script->_filename, script->_threadEvent == NULL ? "" : script->_threadEvent);
- stack->pushNULL();
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // EndDlgBranch
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "EndDlgBranch") == 0) {
- stack->correctParams(1);
-
- const char *branchName = NULL;
- ScValue *val = stack->pop();
- if (!val->isNULL()) {
- branchName = val->getString();
- }
- endDlgBranch(branchName, script->_filename == NULL ? "" : script->_filename, script->_threadEvent == NULL ? "" : script->_threadEvent);
-
- stack->pushNULL();
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetCurrentDlgBranch
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetCurrentDlgBranch") == 0) {
- stack->correctParams(0);
-
- if (_dlgPendingBranches.size() > 0) {
- stack->pushString(_dlgPendingBranches[_dlgPendingBranches.size() - 1]);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TakeItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TakeItem") == 0) {
- return _invObject->scCallMethod(script, stack, thisStack, name);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DropItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DropItem") == 0) {
- return _invObject->scCallMethod(script, stack, thisStack, name);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetItem") == 0) {
- return _invObject->scCallMethod(script, stack, thisStack, name);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // HasItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "HasItem") == 0) {
- return _invObject->scCallMethod(script, stack, thisStack, name);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsItemTaken
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsItemTaken") == 0) {
- stack->correctParams(1);
-
- ScValue *val = stack->pop();
- if (!val->isNULL()) {
- for (uint32 i = 0; i < _inventories.size(); i++) {
- AdInventory *inv = _inventories[i];
-
- for (uint32 j = 0; j < inv->_takenItems.size(); j++) {
- if (val->getNative() == inv->_takenItems[j]) {
- stack->pushBool(true);
- return STATUS_OK;
- } else if (scumm_stricmp(val->getString(), inv->_takenItems[j]->getName()) == 0) {
- stack->pushBool(true);
- return STATUS_OK;
- }
- }
- }
- } else {
- script->runtimeError("Game.IsItemTaken: item name expected");
- }
-
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetInventoryWindow
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetInventoryWindow") == 0) {
- stack->correctParams(0);
- if (_inventoryBox && _inventoryBox->_window) {
- stack->pushNative(_inventoryBox->_window, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetResponsesWindow
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetResponsesWindow") == 0 || strcmp(name, "GetResponseWindow") == 0) {
- stack->correctParams(0);
- if (_responseBox && _responseBox->_window) {
- stack->pushNative(_responseBox->_window, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadResponseBox
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadResponseBox") == 0) {
- stack->correctParams(1);
- const char *filename = stack->pop()->getString();
-
- _gameRef->unregisterObject(_responseBox);
- _responseBox = new AdResponseBox(_gameRef);
- if (_responseBox && !DID_FAIL(_responseBox->loadFile(filename))) {
- registerObject(_responseBox);
- stack->pushBool(true);
- } else {
- delete _responseBox;
- _responseBox = NULL;
- stack->pushBool(false);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadInventoryBox
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadInventoryBox") == 0) {
- stack->correctParams(1);
- const char *filename = stack->pop()->getString();
-
- _gameRef->unregisterObject(_inventoryBox);
- _inventoryBox = new AdInventoryBox(_gameRef);
- if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile(filename))) {
- registerObject(_inventoryBox);
- stack->pushBool(true);
- } else {
- delete _inventoryBox;
- _inventoryBox = NULL;
- stack->pushBool(false);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadItems
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadItems") == 0) {
- stack->correctParams(2);
- const char *filename = stack->pop()->getString();
- bool merge = stack->pop()->getBool(false);
-
- bool ret = loadItemsFile(filename, merge);
- stack->pushBool(DID_SUCCEED(ret));
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AddSpeechDir
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddSpeechDir") == 0) {
- stack->correctParams(1);
- const char *dir = stack->pop()->getString();
- stack->pushBool(DID_SUCCEED(addSpeechDir(dir)));
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // RemoveSpeechDir
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "RemoveSpeechDir") == 0) {
- stack->correctParams(1);
- const char *dir = stack->pop()->getString();
- stack->pushBool(DID_SUCCEED(removeSpeechDir(dir)));
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetSceneViewport
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetSceneViewport") == 0) {
- stack->correctParams(4);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
- int width = stack->pop()->getInt();
- int height = stack->pop()->getInt();
-
- if (width <= 0) {
- width = _renderer->_width;
- }
- if (height <= 0) {
- height = _renderer->_height;
- }
-
- if (!_sceneViewport) {
- _sceneViewport = new BaseViewport(_gameRef);
- }
- if (_sceneViewport) {
- _sceneViewport->setRect(x, y, x + width, y + height);
- }
-
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
-
- else {
- return BaseGame::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdGame::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("game");
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // Scene
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Scene") == 0) {
- if (_scene) {
- _scValue->setNative(_scene, true);
- } else {
- _scValue->setNULL();
- }
-
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // SelectedItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SelectedItem") == 0) {
- //if (_selectedItem) _scValue->setString(_selectedItem->_name);
- if (_selectedItem) {
- _scValue->setNative(_selectedItem, true);
- } else {
- _scValue->setNULL();
- }
-
- return _scValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // NumItems
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumItems") == 0) {
- return _invObject->scGetProperty(name);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SmartItemCursor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SmartItemCursor") == 0) {
- _scValue->setBool(_smartItemCursor);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryVisible
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryVisible") == 0) {
- _scValue->setBool(_inventoryBox && _inventoryBox->_visible);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryScrollOffset
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryScrollOffset") == 0) {
- if (_inventoryBox) {
- _scValue->setInt(_inventoryBox->_scrollOffset);
- } else {
- _scValue->setInt(0);
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ResponsesVisible (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ResponsesVisible") == 0) {
- _scValue->setBool(_stateEx == GAME_WAITING_RESPONSE);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PrevScene / PreviousScene (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PrevScene") == 0 || strcmp(name, "PreviousScene") == 0) {
- if (!_prevSceneName) {
- _scValue->setString("");
- } else {
- _scValue->setString(_prevSceneName);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PrevSceneFilename / PreviousSceneFilename (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PrevSceneFilename") == 0 || strcmp(name, "PreviousSceneFilename") == 0) {
- if (!_prevSceneFilename) {
- _scValue->setString("");
- } else {
- _scValue->setString(_prevSceneFilename);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LastResponse (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LastResponse") == 0) {
- if (!_responseBox || !_responseBox->_lastResponseText) {
- _scValue->setString("");
- } else {
- _scValue->setString(_responseBox->_lastResponseText);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LastResponseOrig (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LastResponseOrig") == 0) {
- if (!_responseBox || !_responseBox->_lastResponseTextOrig) {
- _scValue->setString("");
- } else {
- _scValue->setString(_responseBox->_lastResponseTextOrig);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryObject") == 0) {
- if (_inventoryOwner == _invObject) {
- _scValue->setNative(this, true);
- } else {
- _scValue->setNative(_inventoryOwner, true);
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TotalNumItems
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TotalNumItems") == 0) {
- _scValue->setInt(_items.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TalkSkipButton
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TalkSkipButton") == 0) {
- _scValue->setInt(_talkSkipButton);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ChangingScene
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ChangingScene") == 0) {
- _scValue->setBool(_scheduledScene != NULL);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // StartupScene
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StartupScene") == 0) {
- if (!_startupScene) {
- _scValue->setNULL();
- } else {
- _scValue->setString(_startupScene);
- }
- return _scValue;
- }
-
- else {
- return BaseGame::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::scSetProperty(const char *name, ScValue *value) {
-
- //////////////////////////////////////////////////////////////////////////
- // SelectedItem
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SelectedItem") == 0) {
- if (value->isNULL()) {
- _selectedItem = NULL;
- } else {
- if (value->isNative()) {
- _selectedItem = NULL;
- for (uint32 i = 0; i < _items.size(); i++) {
- if (_items[i] == value->getNative()) {
- _selectedItem = (AdItem *)value->getNative();
- break;
- }
- }
- } else {
- // try to get by name
- _selectedItem = getItemByName(value->getString());
- }
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SmartItemCursor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SmartItemCursor") == 0) {
- _smartItemCursor = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryVisible
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryVisible") == 0) {
- if (_inventoryBox) {
- _inventoryBox->_visible = value->getBool();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryObject") == 0) {
- if (_inventoryOwner && _inventoryBox) {
- _inventoryOwner->getInventory()->_scrollOffset = _inventoryBox->_scrollOffset;
- }
-
- if (value->isNULL()) {
- _inventoryOwner = _invObject;
- } else {
- BaseObject *obj = (BaseObject *)value->getNative();
- if (obj == this) {
- _inventoryOwner = _invObject;
- } else if (_gameRef->validObject(obj)) {
- _inventoryOwner = (AdObject *)obj;
- }
- }
-
- if (_inventoryOwner && _inventoryBox) {
- _inventoryBox->_scrollOffset = _inventoryOwner->getInventory()->_scrollOffset;
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InventoryScrollOffset
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InventoryScrollOffset") == 0) {
- if (_inventoryBox) {
- _inventoryBox->_scrollOffset = value->getInt();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TalkSkipButton
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TalkSkipButton") == 0) {
- int val = value->getInt();
- if (val < 0) {
- val = 0;
- }
- if (val > TALK_SKIP_NONE) {
- val = TALK_SKIP_NONE;
- }
- _talkSkipButton = (TTalkSkipButton)val;
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // StartupScene
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StartupScene") == 0) {
- if (value == NULL) {
- delete[] _startupScene;
- _startupScene = NULL;
- } else {
- BaseUtils::setString(&_startupScene, value->getString());
- }
-
- return STATUS_OK;
- }
-
- else {
- return BaseGame::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name) {
- ScValue *thisObj;
-
- //////////////////////////////////////////////////////////////////////////
- // Actor
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Actor") == 0) {
- stack->correctParams(0);
- thisObj = thisStack->getTop();
-
- thisObj->setNative(new AdActor(_gameRef));
- stack->pushNULL();
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Entity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Entity") == 0) {
- stack->correctParams(0);
- thisObj = thisStack->getTop();
-
- thisObj->setNative(new AdEntity(_gameRef));
- stack->pushNULL();
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // call parent
- else {
- return BaseGame::externalCall(script, stack, thisStack, name);
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::showCursor() {
- if (_cursorHidden) {
- return STATUS_OK;
- }
-
- if (_selectedItem && _gameRef->_state == GAME_RUNNING && _stateEx == GAME_NORMAL && _interactive) {
- if (_selectedItem->_cursorCombined) {
- BaseSprite *origLastCursor = _lastCursor;
- BaseGame::showCursor();
- _lastCursor = origLastCursor;
- }
- if (_activeObject && _selectedItem->_cursorHover && _activeObject->getExtendedFlag("usable")) {
- if (!_smartItemCursor || _activeObject->canHandleEvent(_selectedItem->getName())) {
- return drawCursor(_selectedItem->_cursorHover);
- } else {
- return drawCursor(_selectedItem->_cursorNormal);
- }
- } else {
- return drawCursor(_selectedItem->_cursorNormal);
- }
- } else {
- return BaseGame::showCursor();
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdGame::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing GAME file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(GAME)
-TOKEN_DEF(AD_GAME)
-TOKEN_DEF(RESPONSE_BOX)
-TOKEN_DEF(INVENTORY_BOX)
-TOKEN_DEF(ITEMS)
-TOKEN_DEF(ITEM)
-TOKEN_DEF(TALK_SKIP_BUTTON)
-TOKEN_DEF(SCENE_VIEWPORT)
-TOKEN_DEF(ENTITY_CONTAINER)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF(STARTUP_SCENE)
-TOKEN_DEF(DEBUG_STARTUP_SCENE)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(GAME)
- TOKEN_TABLE(AD_GAME)
- TOKEN_TABLE(RESPONSE_BOX)
- TOKEN_TABLE(INVENTORY_BOX)
- TOKEN_TABLE(ITEMS)
- TOKEN_TABLE(TALK_SKIP_BUTTON)
- TOKEN_TABLE(SCENE_VIEWPORT)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE(STARTUP_SCENE)
- TOKEN_TABLE(DEBUG_STARTUP_SCENE)
- TOKEN_TABLE_END
-
- byte *params;
- byte *params2;
- int cmd = 1;
- BaseParser parser;
-
- bool itemFound = false, itemsFound = false;
-
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_GAME:
- if (DID_FAIL(BaseGame::loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_AD_GAME:
- while (cmd > 0 && (cmd = parser.getCommand((char **)&params, commands, (char **)&params2)) > 0) {
- switch (cmd) {
- case TOKEN_RESPONSE_BOX:
- delete _responseBox;
- _responseBox = new AdResponseBox(_gameRef);
- if (_responseBox && !DID_FAIL(_responseBox->loadFile((char *)params2))) {
- registerObject(_responseBox);
- } else {
- delete _responseBox;
- _responseBox = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_INVENTORY_BOX:
- delete _inventoryBox;
- _inventoryBox = new AdInventoryBox(_gameRef);
- if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile((char *)params2))) {
- registerObject(_inventoryBox);
- } else {
- delete _inventoryBox;
- _inventoryBox = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_ITEMS:
- itemsFound = true;
- BaseUtils::setString(&_itemsFile, (char *)params2);
- if (DID_FAIL(loadItemsFile(_itemsFile))) {
- delete[] _itemsFile;
- _itemsFile = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_TALK_SKIP_BUTTON:
- if (scumm_stricmp((char *)params2, "right") == 0) {
- _talkSkipButton = TALK_SKIP_RIGHT;
- } else if (scumm_stricmp((char *)params2, "both") == 0) {
- _talkSkipButton = TALK_SKIP_BOTH;
- } else {
- _talkSkipButton = TALK_SKIP_LEFT;
- }
- break;
-
- case TOKEN_SCENE_VIEWPORT: {
- Rect32 rc;
- parser.scanStr((char *)params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
- if (!_sceneViewport) {
- _sceneViewport = new BaseViewport(_gameRef);
- }
- if (_sceneViewport) {
- _sceneViewport->setRect(rc.left, rc.top, rc.right, rc.bottom);
- }
- }
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params2, false);
- break;
-
- case TOKEN_STARTUP_SCENE:
- BaseUtils::setString(&_startupScene, (char *)params2);
- break;
-
- case TOKEN_DEBUG_STARTUP_SCENE:
- BaseUtils::setString(&_debugStartupScene, (char *)params2);
- break;
- }
- }
- break;
- }
- }
-
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in GAME definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading GAME definition");
- return STATUS_FAILED;
- }
-
- if (itemFound && !itemsFound) {
- _gameRef->LOG(0, "**Warning** Please put the items definition to a separate file.");
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::persist(BasePersistenceManager *persistMgr) {
- if (!persistMgr->getIsSaving()) {
- cleanup();
- }
- BaseGame::persist(persistMgr);
-
- _dlgPendingBranches.persist(persistMgr);
-
- _inventories.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_inventoryBox));
-
- _objects.persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_prevSceneName));
- persistMgr->transfer(TMEMBER(_prevSceneFilename));
-
- persistMgr->transfer(TMEMBER(_responseBox));
- _responsesBranch.persist(persistMgr);
- _responsesGame.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scene));
- _sceneStates.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scheduledFadeIn));
- persistMgr->transfer(TMEMBER(_scheduledScene));
- persistMgr->transfer(TMEMBER(_selectedItem));
- persistMgr->transfer(TMEMBER_INT(_talkSkipButton));
-
- _sentences.persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_sceneViewport));
- persistMgr->transfer(TMEMBER_INT(_stateEx));
- persistMgr->transfer(TMEMBER(_initialScene));
- persistMgr->transfer(TMEMBER(_debugStartupScene));
-
- persistMgr->transfer(TMEMBER(_invObject));
- persistMgr->transfer(TMEMBER(_inventoryOwner));
- persistMgr->transfer(TMEMBER(_tempDisableSaveState));
- _items.persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_itemsFile));
-
- _speechDirs.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_smartItemCursor));
-
- if (!persistMgr->getIsSaving()) {
- _initialScene = false;
- }
-
- persistMgr->transfer(TMEMBER(_startupScene));
-
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void AdGame::setPrevSceneName(const char *name) {
- delete[] _prevSceneName;
- _prevSceneName = NULL;
- if (name) {
- _prevSceneName = new char[strlen(name) + 1];
- if (_prevSceneName) {
- strcpy(_prevSceneName, name);
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdGame::setPrevSceneFilename(const char *name) {
- delete[] _prevSceneFilename;
- _prevSceneFilename = NULL;
- if (name) {
- _prevSceneFilename = new char[strlen(name) + 1];
- if (_prevSceneFilename) {
- strcpy(_prevSceneFilename, name);
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::scheduleChangeScene(const char *filename, bool fadeIn) {
- delete[] _scheduledScene;
- _scheduledScene = NULL;
-
- if (_scene && !_scene->_initialized) {
- return changeScene(filename, fadeIn);
- } else {
- _scheduledScene = new char [strlen(filename) + 1];
- strcpy(_scheduledScene, filename);
-
- _scheduledFadeIn = fadeIn;
-
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor) {
- BaseGame::getVersion(verMajor, verMinor, NULL, NULL);
-
- if (extMajor) {
- *extMajor = 0;
- }
- if (extMinor) {
- *extMinor = 0;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadItemsFile(const char *filename, bool merge) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdGame::LoadItemsFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- //_filename = new char [strlen(filename)+1];
- //strcpy(_filename, filename);
-
- if (DID_FAIL(ret = loadItemsBuffer(buffer, merge))) {
- _gameRef->LOG(0, "Error parsing ITEMS file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ITEM)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (!merge) {
- while (_items.size() > 0) {
- deleteItem(_items[0]);
- }
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_ITEM: {
- AdItem *item = new AdItem(_gameRef);
- if (item && !DID_FAIL(item->loadBuffer(params, false))) {
- // delete item with the same name, if exists
- if (merge) {
- AdItem *prevItem = getItemByName(item->getName());
- if (prevItem) {
- deleteItem(prevItem);
- }
- }
- addItem(item);
- } else {
- delete item;
- item = NULL;
- cmd = PARSERR_GENERIC;
- }
- }
- break;
- }
- }
-
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ITEMS definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading ITEMS definition");
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSceneState *AdGame::getSceneState(const char *filename, bool saving) {
- char *filenameCor = new char[strlen(filename) + 1];
- strcpy(filenameCor, filename);
- for (uint32 i = 0; i < strlen(filenameCor); i++) {
- if (filenameCor[i] == '/') {
- filenameCor[i] = '\\';
- }
- }
-
- for (uint32 i = 0; i < _sceneStates.size(); i++) {
- if (scumm_stricmp(_sceneStates[i]->_filename, filenameCor) == 0) {
- delete[] filenameCor;
- return _sceneStates[i];
- }
- }
-
- if (saving) {
- AdSceneState *ret = new AdSceneState(_gameRef);
- ret->setFilename(filenameCor);
-
- _sceneStates.add(ret);
-
- delete[] filenameCor;
- return ret;
- } else {
- delete[] filenameCor;
- return NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::windowLoadHook(UIWindow *win, char **buffer, char **params) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ENTITY_CONTAINER)
- TOKEN_TABLE_END
-
- int cmd = PARSERR_GENERIC;
- BaseParser parser;
-
- cmd = parser.getCommand(buffer, commands, params);
- switch (cmd) {
- case TOKEN_ENTITY_CONTAINER: {
- UIEntity *ent = new UIEntity(_gameRef);
- if (!ent || DID_FAIL(ent->loadBuffer((byte *)*params, false))) {
- delete ent;
- ent = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- ent->_parent = win;
- win->_widgets.add(ent);
- }
- }
- break;
- }
-
- if (cmd == PARSERR_TOKENNOTFOUND || cmd == PARSERR_GENERIC) {
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name) {
- if (strcmp(name, "CreateEntityContainer") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- UIEntity *ent = new UIEntity(_gameRef);
- if (!val->isNULL()) {
- ent->setName(val->getString());
- }
- stack->pushNative(ent, true);
-
- ent->_parent = win;
- win->_widgets.add(ent);
-
- return STATUS_OK;
- } else {
- return STATUS_FAILED;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::startDlgBranch(const char *branchName, const char *scriptName, const char *eventName) {
- char *name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
- if (name) {
- sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
- _dlgPendingBranches.add(name);
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::endDlgBranch(const char *branchName, const char *scriptName, const char *eventName) {
- char *name = NULL;
- bool deleteName = false;
- if (branchName == NULL && _dlgPendingBranches.size() > 0) {
- name = _dlgPendingBranches[_dlgPendingBranches.size() - 1];
- } else {
- if (branchName != NULL) {
- name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
- if (name) {
- sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
- deleteName = true;
- }
- }
- }
-
- if (name == NULL) {
- return STATUS_OK;
- }
-
-
- int startIndex = -1;
- for (int i = _dlgPendingBranches.size() - 1; i >= 0; i--) {
- if (scumm_stricmp(name, _dlgPendingBranches[i]) == 0) {
- startIndex = i;
- break;
- }
- }
- if (startIndex >= 0) {
- for (uint32 i = startIndex; i < _dlgPendingBranches.size(); i++) {
- //ClearBranchResponses(_dlgPendingBranches[i]);
- delete[] _dlgPendingBranches[i];
- _dlgPendingBranches[i] = NULL;
- }
- _dlgPendingBranches.remove_at(startIndex, _dlgPendingBranches.size() - startIndex);
- }
-
- // dialogue is over, forget selected responses
- if (_dlgPendingBranches.size() == 0) {
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- delete _responsesBranch[i];
- }
- _responsesBranch.clear();
- }
-
- if (deleteName) {
- delete[] name;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::clearBranchResponses(char *name) {
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- if (scumm_stricmp(name, _responsesBranch[i]->_context) == 0) {
- delete _responsesBranch[i];
- _responsesBranch.remove_at(i);
- i--;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::addBranchResponse(int id) {
- if (branchResponseUsed(id)) {
- return STATUS_OK;
- }
- AdResponseContext *r = new AdResponseContext(_gameRef);
- r->_id = id;
- r->setContext(_dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL);
- _responsesBranch.add(r);
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::branchResponseUsed(int id) {
- char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- if (_responsesBranch[i]->_id == id) {
- if ((context == NULL && _responsesBranch[i]->_context == NULL) || scumm_stricmp(context, _responsesBranch[i]->_context) == 0) {
- return true;
- }
- }
- }
- return false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::addGameResponse(int id) {
- if (gameResponseUsed(id)) {
- return STATUS_OK;
- }
- AdResponseContext *r = new AdResponseContext(_gameRef);
- r->_id = id;
- r->setContext(_dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL);
- _responsesGame.add(r);
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::gameResponseUsed(int id) {
- char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
- for (uint32 i = 0; i < _responsesGame.size(); i++) {
- AdResponseContext *respContext = _responsesGame[i];
- if (respContext->_id == id) {
- if ((context == NULL && respContext->_context == NULL) || ((context != NULL && respContext->_context != NULL) && scumm_stricmp(context, respContext->_context) == 0)) {
- return true;
- }
- }
- }
- return false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::resetResponse(int id) {
- char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
-
- for (uint32 i = 0; i < _responsesGame.size(); i++) {
- if (_responsesGame[i]->_id == id) {
- if ((context == NULL && _responsesGame[i]->_context == NULL) || scumm_stricmp(context, _responsesGame[i]->_context) == 0) {
- delete _responsesGame[i];
- _responsesGame.remove_at(i);
- break;
- }
- }
- }
-
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- if (_responsesBranch[i]->_id == id) {
- if ((context == NULL && _responsesBranch[i]->_context == NULL) || scumm_stricmp(context, _responsesBranch[i]->_context) == 0) {
- delete _responsesBranch[i];
- _responsesBranch.remove_at(i);
- break;
- }
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::displayContent(bool doUpdate, bool displayAll) {
- // init
- if (doUpdate) {
- initLoop();
- }
-
- // fill black
- _renderer->fill(0, 0, 0);
- if (!_editorMode) {
- _renderer->setScreenViewport();
- }
-
- // playing exclusive video?
- if (_videoPlayer->isPlaying()) {
- if (doUpdate) {
- _videoPlayer->update();
- }
- _videoPlayer->display();
- } else if (_theoraPlayer) {
- if (_theoraPlayer->isPlaying()) {
- if (doUpdate) {
- _theoraPlayer->update();
- }
- _theoraPlayer->display();
- }
- if (_theoraPlayer->isFinished()) {
- delete _theoraPlayer;
- _theoraPlayer = NULL;
- }
- } else {
-
- // process scripts
- if (doUpdate) {
- _scEngine->tick();
- }
-
- Point32 p;
- getMousePos(&p);
-
- _scene->update();
- _scene->display();
-
-
- // display in-game windows
- displayWindows(true);
- if (_inventoryBox) {
- _inventoryBox->display();
- }
- if (_stateEx == GAME_WAITING_RESPONSE) {
- _responseBox->display();
- }
- _renderer->displayIndicator();
-
-
- if (doUpdate || displayAll) {
- // display normal windows
- displayWindows(false);
-
- setActiveObject(_gameRef->_renderer->getObjectAt(p.x, p.y));
-
- // textual info
- displaySentences(_state == GAME_FROZEN);
-
- showCursor();
-
- if (_fader) {
- _fader->display();
- }
- _transMgr->update();
- }
-
- }
- if (_loadingIcon) {
- _loadingIcon->display(_loadingIconX, _loadingIconY);
- if (!_loadingIconPersistent) {
- delete _loadingIcon;
- _loadingIcon = NULL;
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::registerInventory(AdInventory *inv) {
- for (uint32 i = 0; i < _inventories.size(); i++) {
- if (_inventories[i] == inv) {
- return STATUS_OK;
- }
- }
- registerObject(inv);
- _inventories.add(inv);
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::unregisterInventory(AdInventory *inv) {
- for (uint32 i = 0; i < _inventories.size(); i++) {
- if (_inventories[i] == inv) {
- unregisterObject(_inventories[i]);
- _inventories.remove_at(i);
- return STATUS_OK;
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::isItemTaken(char *itemName) {
- for (uint32 i = 0; i < _inventories.size(); i++) {
- AdInventory *inv = _inventories[i];
-
- for (uint32 j = 0; j < inv->_takenItems.size(); j++) {
- if (scumm_stricmp(itemName, inv->_takenItems[j]->getName()) == 0) {
- return true;
- }
- }
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-AdItem *AdGame::getItemByName(const char *name) {
- for (uint32 i = 0; i < _items.size(); i++) {
- if (scumm_stricmp(_items[i]->getName(), name) == 0) {
- return _items[i];
- }
- }
- return NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::addItem(AdItem *item) {
- _items.add(item);
- return _gameRef->registerObject(item);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::resetContent() {
- // clear pending dialogs
- for (uint32 i = 0; i < _dlgPendingBranches.size(); i++) {
- delete[] _dlgPendingBranches[i];
- }
- _dlgPendingBranches.clear();
-
-
- // clear inventories
- for (uint32 i = 0; i < _inventories.size(); i++) {
- _inventories[i]->_takenItems.clear();
- }
-
- // clear scene states
- for (uint32 i = 0; i < _sceneStates.size(); i++) {
- delete _sceneStates[i];
- }
- _sceneStates.clear();
-
- // clear once responses
- for (uint32 i = 0; i < _responsesBranch.size(); i++) {
- delete _responsesBranch[i];
- }
- _responsesBranch.clear();
-
- // clear once game responses
- for (uint32 i = 0; i < _responsesGame.size(); i++) {
- delete _responsesGame[i];
- }
- _responsesGame.clear();
-
- // reload inventory items
- if (_itemsFile) {
- loadItemsFile(_itemsFile);
- }
-
- _tempDisableSaveState = true;
-
- return BaseGame::resetContent();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::deleteItem(AdItem *item) {
- if (!item) {
- return STATUS_FAILED;
- }
-
- if (_selectedItem == item) {
- _selectedItem = NULL;
- }
- _scene->handleItemAssociations(item->getName(), false);
-
- // remove from all inventories
- for (uint32 i = 0; i < _inventories.size(); i++) {
- _inventories[i]->removeItem(item);
- }
-
- // remove object
- for (uint32 i = 0; i < _items.size(); i++) {
- if (_items[i] == item) {
- unregisterObject(_items[i]);
- _items.remove_at(i);
- break;
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::addSpeechDir(const char *dir) {
- if (!dir || dir[0] == '\0') {
- return STATUS_FAILED;
- }
-
- char *temp = new char[strlen(dir) + 2];
- strcpy(temp, dir);
- if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
- strcat(temp, "\\");
- }
-
- for (uint32 i = 0; i < _speechDirs.size(); i++) {
- if (scumm_stricmp(_speechDirs[i], temp) == 0) {
- delete[] temp;
- return STATUS_OK;
- }
- }
- _speechDirs.add(temp);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::removeSpeechDir(const char *dir) {
- if (!dir || dir[0] == '\0') {
- return STATUS_FAILED;
- }
-
- char *temp = new char[strlen(dir) + 2];
- strcpy(temp, dir);
- if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
- strcat(temp, "\\");
- }
-
- bool found = false;
- for (uint32 i = 0; i < _speechDirs.size(); i++) {
- if (scumm_stricmp(_speechDirs[i], temp) == 0) {
- delete[] _speechDirs[i];
- _speechDirs.remove_at(i);
- found = true;
- break;
- }
- }
- delete[] temp;
-
- return found;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-char *AdGame::findSpeechFile(char *stringID) {
- char *ret = new char[MAX_PATH_LENGTH];
-
- for (uint32 i = 0; i < _speechDirs.size(); i++) {
- sprintf(ret, "%s%s.ogg", _speechDirs[i], stringID);
- if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
- return ret;
- }
-
- sprintf(ret, "%s%s.wav", _speechDirs[i], stringID);
- if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
- return ret;
- }
- }
- delete[] ret;
- return NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::validMouse() {
- Point32 pos;
- BasePlatform::getCursorPos(&pos);
-
- return _renderer->pointInViewport(&pos);
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onMouseLeftDown() {
- if (!validMouse()) {
- return STATUS_OK;
- }
- if (_state == GAME_RUNNING && !_interactive) {
- if (_talkSkipButton == TALK_SKIP_LEFT || _talkSkipButton == TALK_SKIP_BOTH) {
- finishSentences();
- }
- return STATUS_OK;
- }
-
- if (_activeObject) {
- _activeObject->handleMouse(MOUSE_CLICK, MOUSE_BUTTON_LEFT);
- }
-
- bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("LeftClick"));
- if (!handled) {
- if (_activeObject != NULL) {
- _activeObject->applyEvent("LeftClick");
- } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
- _scene->applyEvent("LeftClick");
- }
- }
-
- if (_activeObject != NULL) {
- _gameRef->_capturedObject = _gameRef->_activeObject;
- }
- _mouseLeftDown = true;
- BasePlatform::setCapture(/*_renderer->_window*/);
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onMouseLeftUp() {
- if (_activeObject) {
- _activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
- }
-
- BasePlatform::releaseCapture();
- _capturedObject = NULL;
- _mouseLeftDown = false;
-
- bool handled = /*_state==GAME_RUNNING &&*/ DID_SUCCEED(applyEvent("LeftRelease"));
- if (!handled) {
- if (_activeObject != NULL) {
- _activeObject->applyEvent("LeftRelease");
- } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
- _scene->applyEvent("LeftRelease");
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onMouseLeftDblClick() {
- if (!validMouse()) {
- return STATUS_OK;
- }
-
- if (_state == GAME_RUNNING && !_interactive) {
- return STATUS_OK;
- }
-
- if (_activeObject) {
- _activeObject->handleMouse(MOUSE_DBLCLICK, MOUSE_BUTTON_LEFT);
- }
-
- bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("LeftDoubleClick"));
- if (!handled) {
- if (_activeObject != NULL) {
- _activeObject->applyEvent("LeftDoubleClick");
- } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
- _scene->applyEvent("LeftDoubleClick");
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onMouseRightDown() {
- if (!validMouse()) {
- return STATUS_OK;
- }
- if (_state == GAME_RUNNING && !_interactive) {
- if (_talkSkipButton == TALK_SKIP_RIGHT || _talkSkipButton == TALK_SKIP_BOTH) {
- finishSentences();
- }
- return STATUS_OK;
- }
-
- if ((_state == GAME_RUNNING && !_interactive) || _stateEx == GAME_WAITING_RESPONSE) {
- return STATUS_OK;
- }
-
- if (_activeObject) {
- _activeObject->handleMouse(MOUSE_CLICK, MOUSE_BUTTON_RIGHT);
- }
-
- bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("RightClick"));
- if (!handled) {
- if (_activeObject != NULL) {
- _activeObject->applyEvent("RightClick");
- } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
- _scene->applyEvent("RightClick");
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onMouseRightUp() {
- if (_activeObject) {
- _activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_RIGHT);
- }
-
- bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("RightRelease"));
- if (!handled) {
- if (_activeObject != NULL) {
- _activeObject->applyEvent("RightRelease");
- } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
- _scene->applyEvent("RightRelease");
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::displayDebugInfo() {
- char str[100];
- if (_gameRef->_debugDebugMode) {
- sprintf(str, "Mouse: %d, %d (scene: %d, %d)", _mousePos.x, _mousePos.y, _mousePos.x + _scene->getOffsetLeft(), _mousePos.y + _scene->getOffsetTop());
- _systemFont->drawText((byte *)str, 0, 90, _renderer->_width, TAL_RIGHT);
-
- sprintf(str, "Scene: %s (prev: %s)", (_scene && _scene->getName()) ? _scene->getName() : "???", _prevSceneName ? _prevSceneName : "???");
- _systemFont->drawText((byte *)str, 0, 110, _renderer->_width, TAL_RIGHT);
- }
- return BaseGame::displayDebugInfo();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdGame::onScriptShutdown(ScScript *script) {
- if (_responseBox && _responseBox->_waitingScript == script) {
- _responseBox->_waitingScript = NULL;
- }
-
- 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/ad/ad_actor.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_entity.h"
+#include "engines/wintermute/ad/ad_inventory.h"
+#include "engines/wintermute/ad/ad_inventory_box.h"
+#include "engines/wintermute/ad/ad_item.h"
+#include "engines/wintermute/ad/ad_response.h"
+#include "engines/wintermute/ad/ad_response_box.h"
+#include "engines/wintermute/ad/ad_response_context.h"
+#include "engines/wintermute/ad/ad_scene.h"
+#include "engines/wintermute/ad/ad_scene_state.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_object.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/base/base_string_table.h"
+#include "engines/wintermute/base/base_surface_storage.h"
+#include "engines/wintermute/base/base_transition_manager.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_viewport.h"
+#include "engines/wintermute/base/particles/part_emitter.h"
+#include "engines/wintermute/base/saveload.h"
+#include "engines/wintermute/base/scriptables/script_engine.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/ui/ui_entity.h"
+#include "engines/wintermute/ui/ui_window.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/video/video_player.h"
+#include "engines/wintermute/video/video_theora_player.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdGame, true)
+
+//////////////////////////////////////////////////////////////////////////
+AdGame::AdGame(const Common::String &gameId) : BaseGame(gameId) {
+ _responseBox = NULL;
+ _inventoryBox = NULL;
+
+ _scene = new AdScene(_gameRef);
+ _scene->setName("");
+ registerObject(_scene);
+
+ _prevSceneName = NULL;
+ _prevSceneFilename = NULL;
+ _scheduledScene = NULL;
+ _scheduledFadeIn = false;
+
+
+ _stateEx = GAME_NORMAL;
+
+ _selectedItem = NULL;
+
+
+ _texItemLifeTime = 10000;
+ _texWalkLifeTime = 10000;
+ _texStandLifeTime = 10000;
+ _texTalkLifeTime = 10000;
+
+ _talkSkipButton = TALK_SKIP_LEFT;
+
+ _sceneViewport = NULL;
+
+ _initialScene = true;
+ _debugStartupScene = NULL;
+ _startupScene = NULL;
+
+ _invObject = new AdObject(this);
+ _inventoryOwner = _invObject;
+
+ _tempDisableSaveState = false;
+ _itemsFile = NULL;
+
+ _smartItemCursor = false;
+
+ addSpeechDir("speech");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdGame::~AdGame() {
+ cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::cleanup() {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ unregisterObject(_objects[i]);
+ _objects[i] = NULL;
+ }
+ _objects.clear();
+
+
+ for (uint32 i = 0; i < _dlgPendingBranches.size(); i++) {
+ delete[] _dlgPendingBranches[i];
+ }
+ _dlgPendingBranches.clear();
+
+ for (uint32 i = 0; i < _speechDirs.size(); i++) {
+ delete[] _speechDirs[i];
+ }
+ _speechDirs.clear();
+
+
+ unregisterObject(_scene);
+ _scene = NULL;
+
+ // remove items
+ for (uint32 i = 0; i < _items.size(); i++) {
+ _gameRef->unregisterObject(_items[i]);
+ }
+ _items.clear();
+
+
+ // clear remaining inventories
+ delete _invObject;
+ _invObject = NULL;
+
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ delete _inventories[i];
+ }
+ _inventories.clear();
+
+
+ if (_responseBox) {
+ _gameRef->unregisterObject(_responseBox);
+ _responseBox = NULL;
+ }
+
+ if (_inventoryBox) {
+ _gameRef->unregisterObject(_inventoryBox);
+ _inventoryBox = NULL;
+ }
+
+ delete[] _prevSceneName;
+ delete[] _prevSceneFilename;
+ delete[] _scheduledScene;
+ delete[] _debugStartupScene;
+ delete[] _itemsFile;
+ _prevSceneName = NULL;
+ _prevSceneFilename = NULL;
+ _scheduledScene = NULL;
+ _debugStartupScene = NULL;
+ _startupScene = NULL;
+ _itemsFile = NULL;
+
+ delete _sceneViewport;
+ _sceneViewport = NULL;
+
+ for (uint32 i = 0; i < _sceneStates.size(); i++) {
+ delete _sceneStates[i];
+ }
+ _sceneStates.clear();
+
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ delete _responsesBranch[i];
+ }
+ _responsesBranch.clear();
+
+ for (uint32 i = 0; i < _responsesGame.size(); i++) {
+ delete _responsesGame[i];
+ }
+ _responsesGame.clear();
+
+ return BaseGame::cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::initLoop() {
+ if (_scheduledScene && _transMgr->isReady()) {
+ changeScene(_scheduledScene, _scheduledFadeIn);
+ delete[] _scheduledScene;
+ _scheduledScene = NULL;
+
+ _gameRef->_activeObject = NULL;
+ }
+
+
+ bool res;
+ res = BaseGame::initLoop();
+ if (DID_FAIL(res)) {
+ return res;
+ }
+
+ if (_scene) {
+ res = _scene->initLoop();
+ }
+
+ _sentences.clear();
+
+ return res;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::addObject(AdObject *object) {
+ _objects.add(object);
+ return registerObject(object);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::removeObject(AdObject *object) {
+ // in case the user called Scene.CreateXXX() and Game.DeleteXXX()
+ if (_scene) {
+ bool res = _scene->removeObject(object);
+ if (DID_SUCCEED(res)) {
+ return res;
+ }
+ }
+
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i] == object) {
+ _objects.remove_at(i);
+ break;
+ }
+ }
+ return unregisterObject(object);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::changeScene(const char *filename, bool fadeIn) {
+ if (_scene == NULL) {
+ _scene = new AdScene(_gameRef);
+ registerObject(_scene);
+ } else {
+ _scene->applyEvent("SceneShutdown", true);
+
+ setPrevSceneName(_scene->getName());
+ setPrevSceneFilename(_scene->getFilename());
+
+ if (!_tempDisableSaveState) {
+ _scene->saveState();
+ }
+ _tempDisableSaveState = false;
+ }
+
+ if (_scene) {
+ // reset objects
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ _objects[i]->reset();
+ }
+
+ // reset scene properties
+ _scene->_sFXVolume = 100;
+ if (_scene->_scProp) {
+ _scene->_scProp->cleanup();
+ }
+
+ bool ret;
+ if (_initialScene && _debugDebugMode && _debugStartupScene) {
+ _initialScene = false;
+ ret = _scene->loadFile(_debugStartupScene);
+ } else {
+ ret = _scene->loadFile(filename);
+ }
+
+ if (DID_SUCCEED(ret)) {
+ // invalidate references to the original scene
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ _objects[i]->invalidateCurrRegions();
+ _objects[i]->_stickRegion = NULL;
+ }
+
+ _scene->loadState();
+ }
+ if (fadeIn) {
+ _gameRef->_transMgr->start(TRANSITION_FADE_IN);
+ }
+ return ret;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdGame::addSentence(AdSentence *sentence) {
+ _sentences.add(sentence);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::displaySentences(bool frozen) {
+ for (uint32 i = 0; i < _sentences.size(); i++) {
+ if (frozen && _sentences[i]->_freezable) {
+ continue;
+ } else {
+ _sentences[i]->display();
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdGame::finishSentences() {
+ for (uint32 i = 0; i < _sentences.size(); i++) {
+ if (_sentences[i]->canSkip()) {
+ _sentences[i]->_duration = 0;
+ if (_sentences[i]->_sound) {
+ _sentences[i]->_sound->stop();
+ }
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // ChangeScene
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "ChangeScene") == 0) {
+ stack->correctParams(3);
+ const char *filename = stack->pop()->getString();
+ ScValue *valFadeOut = stack->pop();
+ ScValue *valFadeIn = stack->pop();
+
+ bool transOut = valFadeOut->isNULL() ? true : valFadeOut->getBool();
+ bool transIn = valFadeIn->isNULL() ? true : valFadeIn->getBool();
+
+ scheduleChangeScene(filename, transIn);
+ if (transOut) {
+ _transMgr->start(TRANSITION_FADE_OUT, true);
+ }
+ stack->pushNULL();
+
+
+ //bool ret = ChangeScene(stack->pop()->getString());
+ //if (DID_FAIL(ret)) stack->pushBool(false);
+ //else stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadActor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadActor") == 0) {
+ stack->correctParams(1);
+ AdActor *act = new AdActor(_gameRef);
+ if (act && DID_SUCCEED(act->loadFile(stack->pop()->getString()))) {
+ addObject(act);
+ stack->pushNative(act, true);
+ } else {
+ delete act;
+ act = NULL;
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadEntity") == 0) {
+ stack->correctParams(1);
+ AdEntity *ent = new AdEntity(_gameRef);
+ if (ent && DID_SUCCEED(ent->loadFile(stack->pop()->getString()))) {
+ addObject(ent);
+ stack->pushNative(ent, true);
+ } else {
+ delete ent;
+ ent = NULL;
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // UnloadObject / UnloadActor / UnloadEntity / DeleteEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "UnloadObject") == 0 || strcmp(name, "UnloadActor") == 0 || strcmp(name, "UnloadEntity") == 0 || strcmp(name, "DeleteEntity") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ AdObject *obj = (AdObject *)val->getNative();
+ removeObject(obj);
+ if (val->getType() == VAL_VARIABLE_REF) {
+ val->setNULL();
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CreateEntity") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdEntity *ent = new AdEntity(_gameRef);
+ addObject(ent);
+ if (!val->isNULL()) {
+ ent->setName(val->getString());
+ }
+ stack->pushNative(ent, true);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CreateItem") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdItem *item = new AdItem(_gameRef);
+ addItem(item);
+ if (!val->isNULL()) {
+ item->setName(val->getString());
+ }
+ stack->pushNative(item, true);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DeleteItem") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdItem *item = NULL;
+ if (val->isNative()) {
+ item = (AdItem *)val->getNative();
+ } else {
+ item = getItemByName(val->getString());
+ }
+
+ if (item) {
+ deleteItem(item);
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // QueryItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "QueryItem") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdItem *item = NULL;
+ if (val->isInt()) {
+ int index = val->getInt();
+ if (index >= 0 && index < (int32)_items.size()) {
+ item = _items[index];
+ }
+ } else {
+ item = getItemByName(val->getString());
+ }
+
+ if (item) {
+ stack->pushNative(item, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddResponse/AddResponseOnce/AddResponseOnceGame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddResponse") == 0 || strcmp(name, "AddResponseOnce") == 0 || strcmp(name, "AddResponseOnceGame") == 0) {
+ stack->correctParams(6);
+ int id = stack->pop()->getInt();
+ const char *text = stack->pop()->getString();
+ ScValue *val1 = stack->pop();
+ ScValue *val2 = stack->pop();
+ ScValue *val3 = stack->pop();
+ ScValue *val4 = stack->pop();
+
+ if (_responseBox) {
+ AdResponse *res = new AdResponse(_gameRef);
+ if (res) {
+ res->_iD = id;
+ res->setText(text);
+ _stringTable->expand(&res->_text);
+ if (!val1->isNULL()) {
+ res->setIcon(val1->getString());
+ }
+ if (!val2->isNULL()) {
+ res->setIconHover(val2->getString());
+ }
+ if (!val3->isNULL()) {
+ res->setIconPressed(val3->getString());
+ }
+ if (!val4->isNULL()) {
+ res->setFont(val4->getString());
+ }
+
+ if (strcmp(name, "AddResponseOnce") == 0) {
+ res->_responseType = RESPONSE_ONCE;
+ } else if (strcmp(name, "AddResponseOnceGame") == 0) {
+ res->_responseType = RESPONSE_ONCE_GAME;
+ }
+
+ _responseBox->_responses.add(res);
+ }
+ } else {
+ script->runtimeError("Game.AddResponse: response box is not defined");
+ }
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ResetResponse
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ResetResponse") == 0) {
+ stack->correctParams(1);
+ int id = stack->pop()->getInt(-1);
+ resetResponse(id);
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ClearResponses
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ClearResponses") == 0) {
+ stack->correctParams(0);
+ _responseBox->clearResponses();
+ _responseBox->clearButtons();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetResponse
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetResponse") == 0) {
+ stack->correctParams(1);
+ bool autoSelectLast = stack->pop()->getBool();
+
+ if (_responseBox) {
+ _responseBox->weedResponses();
+
+ if (_responseBox->_responses.size() == 0) {
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+
+ if (_responseBox->_responses.size() == 1 && autoSelectLast) {
+ stack->pushInt(_responseBox->_responses[0]->_iD);
+ _responseBox->handleResponse(_responseBox->_responses[0]);
+ _responseBox->clearResponses();
+ return STATUS_OK;
+ }
+
+ _responseBox->createButtons();
+ _responseBox->_waitingScript = script;
+ script->waitForExclusive(_responseBox);
+ _state = GAME_SEMI_FROZEN;
+ _stateEx = GAME_WAITING_RESPONSE;
+ } else {
+ script->runtimeError("Game.GetResponse: response box is not defined");
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetNumResponses
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetNumResponses") == 0) {
+ stack->correctParams(0);
+ if (_responseBox) {
+ _responseBox->weedResponses();
+ stack->pushInt(_responseBox->_responses.size());
+ } else {
+ script->runtimeError("Game.GetNumResponses: response box is not defined");
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // StartDlgBranch
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StartDlgBranch") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ Common::String branchName;
+ if (val->isNULL()) {
+ branchName.format("line%d", script->_currentLine);
+ } else {
+ branchName = val->getString();
+ }
+
+ startDlgBranch(branchName.c_str(), script->_filename == NULL ? "" : script->_filename, script->_threadEvent == NULL ? "" : script->_threadEvent);
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // EndDlgBranch
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "EndDlgBranch") == 0) {
+ stack->correctParams(1);
+
+ const char *branchName = NULL;
+ ScValue *val = stack->pop();
+ if (!val->isNULL()) {
+ branchName = val->getString();
+ }
+ endDlgBranch(branchName, script->_filename == NULL ? "" : script->_filename, script->_threadEvent == NULL ? "" : script->_threadEvent);
+
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetCurrentDlgBranch
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetCurrentDlgBranch") == 0) {
+ stack->correctParams(0);
+
+ if (_dlgPendingBranches.size() > 0) {
+ stack->pushString(_dlgPendingBranches[_dlgPendingBranches.size() - 1]);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TakeItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TakeItem") == 0) {
+ return _invObject->scCallMethod(script, stack, thisStack, name);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DropItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DropItem") == 0) {
+ return _invObject->scCallMethod(script, stack, thisStack, name);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetItem") == 0) {
+ return _invObject->scCallMethod(script, stack, thisStack, name);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HasItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "HasItem") == 0) {
+ return _invObject->scCallMethod(script, stack, thisStack, name);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsItemTaken
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsItemTaken") == 0) {
+ stack->correctParams(1);
+
+ ScValue *val = stack->pop();
+ if (!val->isNULL()) {
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ AdInventory *inv = _inventories[i];
+
+ for (uint32 j = 0; j < inv->_takenItems.size(); j++) {
+ if (val->getNative() == inv->_takenItems[j]) {
+ stack->pushBool(true);
+ return STATUS_OK;
+ } else if (scumm_stricmp(val->getString(), inv->_takenItems[j]->getName()) == 0) {
+ stack->pushBool(true);
+ return STATUS_OK;
+ }
+ }
+ }
+ } else {
+ script->runtimeError("Game.IsItemTaken: item name expected");
+ }
+
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetInventoryWindow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetInventoryWindow") == 0) {
+ stack->correctParams(0);
+ if (_inventoryBox && _inventoryBox->_window) {
+ stack->pushNative(_inventoryBox->_window, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetResponsesWindow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetResponsesWindow") == 0 || strcmp(name, "GetResponseWindow") == 0) {
+ stack->correctParams(0);
+ if (_responseBox && _responseBox->_window) {
+ stack->pushNative(_responseBox->_window, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadResponseBox
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadResponseBox") == 0) {
+ stack->correctParams(1);
+ const char *filename = stack->pop()->getString();
+
+ _gameRef->unregisterObject(_responseBox);
+ _responseBox = new AdResponseBox(_gameRef);
+ if (_responseBox && !DID_FAIL(_responseBox->loadFile(filename))) {
+ registerObject(_responseBox);
+ stack->pushBool(true);
+ } else {
+ delete _responseBox;
+ _responseBox = NULL;
+ stack->pushBool(false);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadInventoryBox
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadInventoryBox") == 0) {
+ stack->correctParams(1);
+ const char *filename = stack->pop()->getString();
+
+ _gameRef->unregisterObject(_inventoryBox);
+ _inventoryBox = new AdInventoryBox(_gameRef);
+ if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile(filename))) {
+ registerObject(_inventoryBox);
+ stack->pushBool(true);
+ } else {
+ delete _inventoryBox;
+ _inventoryBox = NULL;
+ stack->pushBool(false);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadItems
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadItems") == 0) {
+ stack->correctParams(2);
+ const char *filename = stack->pop()->getString();
+ bool merge = stack->pop()->getBool(false);
+
+ bool ret = loadItemsFile(filename, merge);
+ stack->pushBool(DID_SUCCEED(ret));
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddSpeechDir
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddSpeechDir") == 0) {
+ stack->correctParams(1);
+ const char *dir = stack->pop()->getString();
+ stack->pushBool(DID_SUCCEED(addSpeechDir(dir)));
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveSpeechDir
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RemoveSpeechDir") == 0) {
+ stack->correctParams(1);
+ const char *dir = stack->pop()->getString();
+ stack->pushBool(DID_SUCCEED(removeSpeechDir(dir)));
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetSceneViewport
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetSceneViewport") == 0) {
+ stack->correctParams(4);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+ int width = stack->pop()->getInt();
+ int height = stack->pop()->getInt();
+
+ if (width <= 0) {
+ width = _renderer->_width;
+ }
+ if (height <= 0) {
+ height = _renderer->_height;
+ }
+
+ if (!_sceneViewport) {
+ _sceneViewport = new BaseViewport(_gameRef);
+ }
+ if (_sceneViewport) {
+ _sceneViewport->setRect(x, y, x + width, y + height);
+ }
+
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+
+ else {
+ return BaseGame::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdGame::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("game");
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Scene
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Scene") == 0) {
+ if (_scene) {
+ _scValue->setNative(_scene, true);
+ } else {
+ _scValue->setNULL();
+ }
+
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SelectedItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SelectedItem") == 0) {
+ //if (_selectedItem) _scValue->setString(_selectedItem->_name);
+ if (_selectedItem) {
+ _scValue->setNative(_selectedItem, true);
+ } else {
+ _scValue->setNULL();
+ }
+
+ return _scValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // NumItems
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumItems") == 0) {
+ return _invObject->scGetProperty(name);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SmartItemCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SmartItemCursor") == 0) {
+ _scValue->setBool(_smartItemCursor);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryVisible
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryVisible") == 0) {
+ _scValue->setBool(_inventoryBox && _inventoryBox->_visible);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryScrollOffset
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryScrollOffset") == 0) {
+ if (_inventoryBox) {
+ _scValue->setInt(_inventoryBox->_scrollOffset);
+ } else {
+ _scValue->setInt(0);
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ResponsesVisible (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ResponsesVisible") == 0) {
+ _scValue->setBool(_stateEx == GAME_WAITING_RESPONSE);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PrevScene / PreviousScene (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PrevScene") == 0 || strcmp(name, "PreviousScene") == 0) {
+ if (!_prevSceneName) {
+ _scValue->setString("");
+ } else {
+ _scValue->setString(_prevSceneName);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PrevSceneFilename / PreviousSceneFilename (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PrevSceneFilename") == 0 || strcmp(name, "PreviousSceneFilename") == 0) {
+ if (!_prevSceneFilename) {
+ _scValue->setString("");
+ } else {
+ _scValue->setString(_prevSceneFilename);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LastResponse (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LastResponse") == 0) {
+ if (!_responseBox || !_responseBox->_lastResponseText) {
+ _scValue->setString("");
+ } else {
+ _scValue->setString(_responseBox->_lastResponseText);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LastResponseOrig (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LastResponseOrig") == 0) {
+ if (!_responseBox || !_responseBox->_lastResponseTextOrig) {
+ _scValue->setString("");
+ } else {
+ _scValue->setString(_responseBox->_lastResponseTextOrig);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryObject") == 0) {
+ if (_inventoryOwner == _invObject) {
+ _scValue->setNative(this, true);
+ } else {
+ _scValue->setNative(_inventoryOwner, true);
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TotalNumItems
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TotalNumItems") == 0) {
+ _scValue->setInt(_items.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TalkSkipButton
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TalkSkipButton") == 0) {
+ _scValue->setInt(_talkSkipButton);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ChangingScene
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ChangingScene") == 0) {
+ _scValue->setBool(_scheduledScene != NULL);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StartupScene
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StartupScene") == 0) {
+ if (!_startupScene) {
+ _scValue->setNULL();
+ } else {
+ _scValue->setString(_startupScene);
+ }
+ return _scValue;
+ }
+
+ else {
+ return BaseGame::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::scSetProperty(const char *name, ScValue *value) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // SelectedItem
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SelectedItem") == 0) {
+ if (value->isNULL()) {
+ _selectedItem = NULL;
+ } else {
+ if (value->isNative()) {
+ _selectedItem = NULL;
+ for (uint32 i = 0; i < _items.size(); i++) {
+ if (_items[i] == value->getNative()) {
+ _selectedItem = (AdItem *)value->getNative();
+ break;
+ }
+ }
+ } else {
+ // try to get by name
+ _selectedItem = getItemByName(value->getString());
+ }
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SmartItemCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SmartItemCursor") == 0) {
+ _smartItemCursor = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryVisible
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryVisible") == 0) {
+ if (_inventoryBox) {
+ _inventoryBox->_visible = value->getBool();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryObject") == 0) {
+ if (_inventoryOwner && _inventoryBox) {
+ _inventoryOwner->getInventory()->_scrollOffset = _inventoryBox->_scrollOffset;
+ }
+
+ if (value->isNULL()) {
+ _inventoryOwner = _invObject;
+ } else {
+ BaseObject *obj = (BaseObject *)value->getNative();
+ if (obj == this) {
+ _inventoryOwner = _invObject;
+ } else if (_gameRef->validObject(obj)) {
+ _inventoryOwner = (AdObject *)obj;
+ }
+ }
+
+ if (_inventoryOwner && _inventoryBox) {
+ _inventoryBox->_scrollOffset = _inventoryOwner->getInventory()->_scrollOffset;
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InventoryScrollOffset
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InventoryScrollOffset") == 0) {
+ if (_inventoryBox) {
+ _inventoryBox->_scrollOffset = value->getInt();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TalkSkipButton
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TalkSkipButton") == 0) {
+ int val = value->getInt();
+ if (val < 0) {
+ val = 0;
+ }
+ if (val > TALK_SKIP_NONE) {
+ val = TALK_SKIP_NONE;
+ }
+ _talkSkipButton = (TTalkSkipButton)val;
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StartupScene
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StartupScene") == 0) {
+ if (value == NULL) {
+ delete[] _startupScene;
+ _startupScene = NULL;
+ } else {
+ BaseUtils::setString(&_startupScene, value->getString());
+ }
+
+ return STATUS_OK;
+ }
+
+ else {
+ return BaseGame::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name) {
+ ScValue *thisObj;
+
+ //////////////////////////////////////////////////////////////////////////
+ // Actor
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Actor") == 0) {
+ stack->correctParams(0);
+ thisObj = thisStack->getTop();
+
+ thisObj->setNative(new AdActor(_gameRef));
+ stack->pushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Entity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Entity") == 0) {
+ stack->correctParams(0);
+ thisObj = thisStack->getTop();
+
+ thisObj->setNative(new AdEntity(_gameRef));
+ stack->pushNULL();
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // call parent
+ else {
+ return BaseGame::externalCall(script, stack, thisStack, name);
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::showCursor() {
+ if (_cursorHidden) {
+ return STATUS_OK;
+ }
+
+ if (_selectedItem && _gameRef->_state == GAME_RUNNING && _stateEx == GAME_NORMAL && _interactive) {
+ if (_selectedItem->_cursorCombined) {
+ BaseSprite *origLastCursor = _lastCursor;
+ BaseGame::showCursor();
+ _lastCursor = origLastCursor;
+ }
+ if (_activeObject && _selectedItem->_cursorHover && _activeObject->getExtendedFlag("usable")) {
+ if (!_smartItemCursor || _activeObject->canHandleEvent(_selectedItem->getName())) {
+ return drawCursor(_selectedItem->_cursorHover);
+ } else {
+ return drawCursor(_selectedItem->_cursorNormal);
+ }
+ } else {
+ return drawCursor(_selectedItem->_cursorNormal);
+ }
+ } else {
+ return BaseGame::showCursor();
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdGame::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing GAME file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(GAME)
+TOKEN_DEF(AD_GAME)
+TOKEN_DEF(RESPONSE_BOX)
+TOKEN_DEF(INVENTORY_BOX)
+TOKEN_DEF(ITEMS)
+TOKEN_DEF(ITEM)
+TOKEN_DEF(TALK_SKIP_BUTTON)
+TOKEN_DEF(SCENE_VIEWPORT)
+TOKEN_DEF(ENTITY_CONTAINER)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(STARTUP_SCENE)
+TOKEN_DEF(DEBUG_STARTUP_SCENE)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(GAME)
+ TOKEN_TABLE(AD_GAME)
+ TOKEN_TABLE(RESPONSE_BOX)
+ TOKEN_TABLE(INVENTORY_BOX)
+ TOKEN_TABLE(ITEMS)
+ TOKEN_TABLE(TALK_SKIP_BUTTON)
+ TOKEN_TABLE(SCENE_VIEWPORT)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(STARTUP_SCENE)
+ TOKEN_TABLE(DEBUG_STARTUP_SCENE)
+ TOKEN_TABLE_END
+
+ byte *params;
+ byte *params2;
+ int cmd = 1;
+ BaseParser parser;
+
+ bool itemFound = false, itemsFound = false;
+
+ while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_GAME:
+ if (DID_FAIL(BaseGame::loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_AD_GAME:
+ while (cmd > 0 && (cmd = parser.getCommand((char **)&params, commands, (char **)&params2)) > 0) {
+ switch (cmd) {
+ case TOKEN_RESPONSE_BOX:
+ delete _responseBox;
+ _responseBox = new AdResponseBox(_gameRef);
+ if (_responseBox && !DID_FAIL(_responseBox->loadFile((char *)params2))) {
+ registerObject(_responseBox);
+ } else {
+ delete _responseBox;
+ _responseBox = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_INVENTORY_BOX:
+ delete _inventoryBox;
+ _inventoryBox = new AdInventoryBox(_gameRef);
+ if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile((char *)params2))) {
+ registerObject(_inventoryBox);
+ } else {
+ delete _inventoryBox;
+ _inventoryBox = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_ITEMS:
+ itemsFound = true;
+ BaseUtils::setString(&_itemsFile, (char *)params2);
+ if (DID_FAIL(loadItemsFile(_itemsFile))) {
+ delete[] _itemsFile;
+ _itemsFile = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_TALK_SKIP_BUTTON:
+ if (scumm_stricmp((char *)params2, "right") == 0) {
+ _talkSkipButton = TALK_SKIP_RIGHT;
+ } else if (scumm_stricmp((char *)params2, "both") == 0) {
+ _talkSkipButton = TALK_SKIP_BOTH;
+ } else {
+ _talkSkipButton = TALK_SKIP_LEFT;
+ }
+ break;
+
+ case TOKEN_SCENE_VIEWPORT: {
+ Rect32 rc;
+ parser.scanStr((char *)params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ if (!_sceneViewport) {
+ _sceneViewport = new BaseViewport(_gameRef);
+ }
+ if (_sceneViewport) {
+ _sceneViewport->setRect(rc.left, rc.top, rc.right, rc.bottom);
+ }
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params2, false);
+ break;
+
+ case TOKEN_STARTUP_SCENE:
+ BaseUtils::setString(&_startupScene, (char *)params2);
+ break;
+
+ case TOKEN_DEBUG_STARTUP_SCENE:
+ BaseUtils::setString(&_debugStartupScene, (char *)params2);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in GAME definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading GAME definition");
+ return STATUS_FAILED;
+ }
+
+ if (itemFound && !itemsFound) {
+ _gameRef->LOG(0, "**Warning** Please put the items definition to a separate file.");
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::persist(BasePersistenceManager *persistMgr) {
+ if (!persistMgr->getIsSaving()) {
+ cleanup();
+ }
+ BaseGame::persist(persistMgr);
+
+ _dlgPendingBranches.persist(persistMgr);
+
+ _inventories.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_inventoryBox));
+
+ _objects.persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_prevSceneName));
+ persistMgr->transfer(TMEMBER(_prevSceneFilename));
+
+ persistMgr->transfer(TMEMBER(_responseBox));
+ _responsesBranch.persist(persistMgr);
+ _responsesGame.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_scene));
+ _sceneStates.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_scheduledFadeIn));
+ persistMgr->transfer(TMEMBER(_scheduledScene));
+ persistMgr->transfer(TMEMBER(_selectedItem));
+ persistMgr->transfer(TMEMBER_INT(_talkSkipButton));
+
+ _sentences.persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_sceneViewport));
+ persistMgr->transfer(TMEMBER_INT(_stateEx));
+ persistMgr->transfer(TMEMBER(_initialScene));
+ persistMgr->transfer(TMEMBER(_debugStartupScene));
+
+ persistMgr->transfer(TMEMBER(_invObject));
+ persistMgr->transfer(TMEMBER(_inventoryOwner));
+ persistMgr->transfer(TMEMBER(_tempDisableSaveState));
+ _items.persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_itemsFile));
+
+ _speechDirs.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_smartItemCursor));
+
+ if (!persistMgr->getIsSaving()) {
+ _initialScene = false;
+ }
+
+ persistMgr->transfer(TMEMBER(_startupScene));
+
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AdGame::setPrevSceneName(const char *name) {
+ delete[] _prevSceneName;
+ _prevSceneName = NULL;
+ if (name) {
+ _prevSceneName = new char[strlen(name) + 1];
+ if (_prevSceneName) {
+ strcpy(_prevSceneName, name);
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdGame::setPrevSceneFilename(const char *name) {
+ delete[] _prevSceneFilename;
+ _prevSceneFilename = NULL;
+ if (name) {
+ _prevSceneFilename = new char[strlen(name) + 1];
+ if (_prevSceneFilename) {
+ strcpy(_prevSceneFilename, name);
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::scheduleChangeScene(const char *filename, bool fadeIn) {
+ delete[] _scheduledScene;
+ _scheduledScene = NULL;
+
+ if (_scene && !_scene->_initialized) {
+ return changeScene(filename, fadeIn);
+ } else {
+ _scheduledScene = new char [strlen(filename) + 1];
+ strcpy(_scheduledScene, filename);
+
+ _scheduledFadeIn = fadeIn;
+
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor) {
+ BaseGame::getVersion(verMajor, verMinor, NULL, NULL);
+
+ if (extMajor) {
+ *extMajor = 0;
+ }
+ if (extMinor) {
+ *extMinor = 0;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::loadItemsFile(const char *filename, bool merge) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdGame::LoadItemsFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ //_filename = new char [strlen(filename)+1];
+ //strcpy(_filename, filename);
+
+ if (DID_FAIL(ret = loadItemsBuffer(buffer, merge))) {
+ _gameRef->LOG(0, "Error parsing ITEMS file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ITEM)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (!merge) {
+ while (_items.size() > 0) {
+ deleteItem(_items[0]);
+ }
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_ITEM: {
+ AdItem *item = new AdItem(_gameRef);
+ if (item && !DID_FAIL(item->loadBuffer(params, false))) {
+ // delete item with the same name, if exists
+ if (merge) {
+ AdItem *prevItem = getItemByName(item->getName());
+ if (prevItem) {
+ deleteItem(prevItem);
+ }
+ }
+ addItem(item);
+ } else {
+ delete item;
+ item = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ }
+ break;
+ }
+ }
+
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ITEMS definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading ITEMS definition");
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSceneState *AdGame::getSceneState(const char *filename, bool saving) {
+ char *filenameCor = new char[strlen(filename) + 1];
+ strcpy(filenameCor, filename);
+ for (uint32 i = 0; i < strlen(filenameCor); i++) {
+ if (filenameCor[i] == '/') {
+ filenameCor[i] = '\\';
+ }
+ }
+
+ for (uint32 i = 0; i < _sceneStates.size(); i++) {
+ if (scumm_stricmp(_sceneStates[i]->_filename, filenameCor) == 0) {
+ delete[] filenameCor;
+ return _sceneStates[i];
+ }
+ }
+
+ if (saving) {
+ AdSceneState *ret = new AdSceneState(_gameRef);
+ ret->setFilename(filenameCor);
+
+ _sceneStates.add(ret);
+
+ delete[] filenameCor;
+ return ret;
+ } else {
+ delete[] filenameCor;
+ return NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::windowLoadHook(UIWindow *win, char **buffer, char **params) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ENTITY_CONTAINER)
+ TOKEN_TABLE_END
+
+ int cmd = PARSERR_GENERIC;
+ BaseParser parser;
+
+ cmd = parser.getCommand(buffer, commands, params);
+ switch (cmd) {
+ case TOKEN_ENTITY_CONTAINER: {
+ UIEntity *ent = new UIEntity(_gameRef);
+ if (!ent || DID_FAIL(ent->loadBuffer((byte *)*params, false))) {
+ delete ent;
+ ent = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ ent->_parent = win;
+ win->_widgets.add(ent);
+ }
+ }
+ break;
+ }
+
+ if (cmd == PARSERR_TOKENNOTFOUND || cmd == PARSERR_GENERIC) {
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name) {
+ if (strcmp(name, "CreateEntityContainer") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ UIEntity *ent = new UIEntity(_gameRef);
+ if (!val->isNULL()) {
+ ent->setName(val->getString());
+ }
+ stack->pushNative(ent, true);
+
+ ent->_parent = win;
+ win->_widgets.add(ent);
+
+ return STATUS_OK;
+ } else {
+ return STATUS_FAILED;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::startDlgBranch(const char *branchName, const char *scriptName, const char *eventName) {
+ char *name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
+ if (name) {
+ sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
+ _dlgPendingBranches.add(name);
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::endDlgBranch(const char *branchName, const char *scriptName, const char *eventName) {
+ char *name = NULL;
+ bool deleteName = false;
+ if (branchName == NULL && _dlgPendingBranches.size() > 0) {
+ name = _dlgPendingBranches[_dlgPendingBranches.size() - 1];
+ } else {
+ if (branchName != NULL) {
+ name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
+ if (name) {
+ sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
+ deleteName = true;
+ }
+ }
+ }
+
+ if (name == NULL) {
+ return STATUS_OK;
+ }
+
+
+ int startIndex = -1;
+ for (int i = _dlgPendingBranches.size() - 1; i >= 0; i--) {
+ if (scumm_stricmp(name, _dlgPendingBranches[i]) == 0) {
+ startIndex = i;
+ break;
+ }
+ }
+ if (startIndex >= 0) {
+ for (uint32 i = startIndex; i < _dlgPendingBranches.size(); i++) {
+ //ClearBranchResponses(_dlgPendingBranches[i]);
+ delete[] _dlgPendingBranches[i];
+ _dlgPendingBranches[i] = NULL;
+ }
+ _dlgPendingBranches.remove_at(startIndex, _dlgPendingBranches.size() - startIndex);
+ }
+
+ // dialogue is over, forget selected responses
+ if (_dlgPendingBranches.size() == 0) {
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ delete _responsesBranch[i];
+ }
+ _responsesBranch.clear();
+ }
+
+ if (deleteName) {
+ delete[] name;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::clearBranchResponses(char *name) {
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ if (scumm_stricmp(name, _responsesBranch[i]->_context) == 0) {
+ delete _responsesBranch[i];
+ _responsesBranch.remove_at(i);
+ i--;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::addBranchResponse(int id) {
+ if (branchResponseUsed(id)) {
+ return STATUS_OK;
+ }
+ AdResponseContext *r = new AdResponseContext(_gameRef);
+ r->_id = id;
+ r->setContext(_dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL);
+ _responsesBranch.add(r);
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::branchResponseUsed(int id) {
+ char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ if (_responsesBranch[i]->_id == id) {
+ if ((context == NULL && _responsesBranch[i]->_context == NULL) || scumm_stricmp(context, _responsesBranch[i]->_context) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::addGameResponse(int id) {
+ if (gameResponseUsed(id)) {
+ return STATUS_OK;
+ }
+ AdResponseContext *r = new AdResponseContext(_gameRef);
+ r->_id = id;
+ r->setContext(_dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL);
+ _responsesGame.add(r);
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::gameResponseUsed(int id) {
+ char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
+ for (uint32 i = 0; i < _responsesGame.size(); i++) {
+ AdResponseContext *respContext = _responsesGame[i];
+ if (respContext->_id == id) {
+ if ((context == NULL && respContext->_context == NULL) || ((context != NULL && respContext->_context != NULL) && scumm_stricmp(context, respContext->_context) == 0)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::resetResponse(int id) {
+ char *context = _dlgPendingBranches.size() > 0 ? _dlgPendingBranches[_dlgPendingBranches.size() - 1] : NULL;
+
+ for (uint32 i = 0; i < _responsesGame.size(); i++) {
+ if (_responsesGame[i]->_id == id) {
+ if ((context == NULL && _responsesGame[i]->_context == NULL) || scumm_stricmp(context, _responsesGame[i]->_context) == 0) {
+ delete _responsesGame[i];
+ _responsesGame.remove_at(i);
+ break;
+ }
+ }
+ }
+
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ if (_responsesBranch[i]->_id == id) {
+ if ((context == NULL && _responsesBranch[i]->_context == NULL) || scumm_stricmp(context, _responsesBranch[i]->_context) == 0) {
+ delete _responsesBranch[i];
+ _responsesBranch.remove_at(i);
+ break;
+ }
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::displayContent(bool doUpdate, bool displayAll) {
+ // init
+ if (doUpdate) {
+ initLoop();
+ }
+
+ // fill black
+ _renderer->fill(0, 0, 0);
+ if (!_editorMode) {
+ _renderer->setScreenViewport();
+ }
+
+ // playing exclusive video?
+ if (_videoPlayer->isPlaying()) {
+ if (doUpdate) {
+ _videoPlayer->update();
+ }
+ _videoPlayer->display();
+ } else if (_theoraPlayer) {
+ if (_theoraPlayer->isPlaying()) {
+ if (doUpdate) {
+ _theoraPlayer->update();
+ }
+ _theoraPlayer->display();
+ }
+ if (_theoraPlayer->isFinished()) {
+ delete _theoraPlayer;
+ _theoraPlayer = NULL;
+ }
+ } else {
+
+ // process scripts
+ if (doUpdate) {
+ _scEngine->tick();
+ }
+
+ Point32 p;
+ getMousePos(&p);
+
+ _scene->update();
+ _scene->display();
+
+
+ // display in-game windows
+ displayWindows(true);
+ if (_inventoryBox) {
+ _inventoryBox->display();
+ }
+ if (_stateEx == GAME_WAITING_RESPONSE) {
+ _responseBox->display();
+ }
+ _renderer->displayIndicator();
+
+
+ if (doUpdate || displayAll) {
+ // display normal windows
+ displayWindows(false);
+
+ setActiveObject(_gameRef->_renderer->getObjectAt(p.x, p.y));
+
+ // textual info
+ displaySentences(_state == GAME_FROZEN);
+
+ showCursor();
+
+ if (_fader) {
+ _fader->display();
+ }
+ _transMgr->update();
+ }
+
+ }
+ if (_loadingIcon) {
+ _loadingIcon->display(_loadingIconX, _loadingIconY);
+ if (!_loadingIconPersistent) {
+ delete _loadingIcon;
+ _loadingIcon = NULL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::registerInventory(AdInventory *inv) {
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ if (_inventories[i] == inv) {
+ return STATUS_OK;
+ }
+ }
+ registerObject(inv);
+ _inventories.add(inv);
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::unregisterInventory(AdInventory *inv) {
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ if (_inventories[i] == inv) {
+ unregisterObject(_inventories[i]);
+ _inventories.remove_at(i);
+ return STATUS_OK;
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::isItemTaken(char *itemName) {
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ AdInventory *inv = _inventories[i];
+
+ for (uint32 j = 0; j < inv->_takenItems.size(); j++) {
+ if (scumm_stricmp(itemName, inv->_takenItems[j]->getName()) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AdItem *AdGame::getItemByName(const char *name) {
+ for (uint32 i = 0; i < _items.size(); i++) {
+ if (scumm_stricmp(_items[i]->getName(), name) == 0) {
+ return _items[i];
+ }
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::addItem(AdItem *item) {
+ _items.add(item);
+ return _gameRef->registerObject(item);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::resetContent() {
+ // clear pending dialogs
+ for (uint32 i = 0; i < _dlgPendingBranches.size(); i++) {
+ delete[] _dlgPendingBranches[i];
+ }
+ _dlgPendingBranches.clear();
+
+
+ // clear inventories
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ _inventories[i]->_takenItems.clear();
+ }
+
+ // clear scene states
+ for (uint32 i = 0; i < _sceneStates.size(); i++) {
+ delete _sceneStates[i];
+ }
+ _sceneStates.clear();
+
+ // clear once responses
+ for (uint32 i = 0; i < _responsesBranch.size(); i++) {
+ delete _responsesBranch[i];
+ }
+ _responsesBranch.clear();
+
+ // clear once game responses
+ for (uint32 i = 0; i < _responsesGame.size(); i++) {
+ delete _responsesGame[i];
+ }
+ _responsesGame.clear();
+
+ // reload inventory items
+ if (_itemsFile) {
+ loadItemsFile(_itemsFile);
+ }
+
+ _tempDisableSaveState = true;
+
+ return BaseGame::resetContent();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::deleteItem(AdItem *item) {
+ if (!item) {
+ return STATUS_FAILED;
+ }
+
+ if (_selectedItem == item) {
+ _selectedItem = NULL;
+ }
+ _scene->handleItemAssociations(item->getName(), false);
+
+ // remove from all inventories
+ for (uint32 i = 0; i < _inventories.size(); i++) {
+ _inventories[i]->removeItem(item);
+ }
+
+ // remove object
+ for (uint32 i = 0; i < _items.size(); i++) {
+ if (_items[i] == item) {
+ unregisterObject(_items[i]);
+ _items.remove_at(i);
+ break;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::addSpeechDir(const char *dir) {
+ if (!dir || dir[0] == '\0') {
+ return STATUS_FAILED;
+ }
+
+ char *temp = new char[strlen(dir) + 2];
+ strcpy(temp, dir);
+ if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
+ strcat(temp, "\\");
+ }
+
+ for (uint32 i = 0; i < _speechDirs.size(); i++) {
+ if (scumm_stricmp(_speechDirs[i], temp) == 0) {
+ delete[] temp;
+ return STATUS_OK;
+ }
+ }
+ _speechDirs.add(temp);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::removeSpeechDir(const char *dir) {
+ if (!dir || dir[0] == '\0') {
+ return STATUS_FAILED;
+ }
+
+ char *temp = new char[strlen(dir) + 2];
+ strcpy(temp, dir);
+ if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
+ strcat(temp, "\\");
+ }
+
+ bool found = false;
+ for (uint32 i = 0; i < _speechDirs.size(); i++) {
+ if (scumm_stricmp(_speechDirs[i], temp) == 0) {
+ delete[] _speechDirs[i];
+ _speechDirs.remove_at(i);
+ found = true;
+ break;
+ }
+ }
+ delete[] temp;
+
+ return found;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *AdGame::findSpeechFile(char *stringID) {
+ char *ret = new char[MAX_PATH_LENGTH];
+
+ for (uint32 i = 0; i < _speechDirs.size(); i++) {
+ sprintf(ret, "%s%s.ogg", _speechDirs[i], stringID);
+ if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
+ return ret;
+ }
+
+ sprintf(ret, "%s%s.wav", _speechDirs[i], stringID);
+ if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
+ return ret;
+ }
+ }
+ delete[] ret;
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::validMouse() {
+ Point32 pos;
+ BasePlatform::getCursorPos(&pos);
+
+ return _renderer->pointInViewport(&pos);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onMouseLeftDown() {
+ if (!validMouse()) {
+ return STATUS_OK;
+ }
+ if (_state == GAME_RUNNING && !_interactive) {
+ if (_talkSkipButton == TALK_SKIP_LEFT || _talkSkipButton == TALK_SKIP_BOTH) {
+ finishSentences();
+ }
+ return STATUS_OK;
+ }
+
+ if (_activeObject) {
+ _activeObject->handleMouse(MOUSE_CLICK, MOUSE_BUTTON_LEFT);
+ }
+
+ bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("LeftClick"));
+ if (!handled) {
+ if (_activeObject != NULL) {
+ _activeObject->applyEvent("LeftClick");
+ } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
+ _scene->applyEvent("LeftClick");
+ }
+ }
+
+ if (_activeObject != NULL) {
+ _gameRef->_capturedObject = _gameRef->_activeObject;
+ }
+ _mouseLeftDown = true;
+ BasePlatform::setCapture(/*_renderer->_window*/);
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onMouseLeftUp() {
+ if (_activeObject) {
+ _activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
+ }
+
+ BasePlatform::releaseCapture();
+ _capturedObject = NULL;
+ _mouseLeftDown = false;
+
+ bool handled = /*_state==GAME_RUNNING &&*/ DID_SUCCEED(applyEvent("LeftRelease"));
+ if (!handled) {
+ if (_activeObject != NULL) {
+ _activeObject->applyEvent("LeftRelease");
+ } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
+ _scene->applyEvent("LeftRelease");
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onMouseLeftDblClick() {
+ if (!validMouse()) {
+ return STATUS_OK;
+ }
+
+ if (_state == GAME_RUNNING && !_interactive) {
+ return STATUS_OK;
+ }
+
+ if (_activeObject) {
+ _activeObject->handleMouse(MOUSE_DBLCLICK, MOUSE_BUTTON_LEFT);
+ }
+
+ bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("LeftDoubleClick"));
+ if (!handled) {
+ if (_activeObject != NULL) {
+ _activeObject->applyEvent("LeftDoubleClick");
+ } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
+ _scene->applyEvent("LeftDoubleClick");
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onMouseRightDown() {
+ if (!validMouse()) {
+ return STATUS_OK;
+ }
+ if (_state == GAME_RUNNING && !_interactive) {
+ if (_talkSkipButton == TALK_SKIP_RIGHT || _talkSkipButton == TALK_SKIP_BOTH) {
+ finishSentences();
+ }
+ return STATUS_OK;
+ }
+
+ if ((_state == GAME_RUNNING && !_interactive) || _stateEx == GAME_WAITING_RESPONSE) {
+ return STATUS_OK;
+ }
+
+ if (_activeObject) {
+ _activeObject->handleMouse(MOUSE_CLICK, MOUSE_BUTTON_RIGHT);
+ }
+
+ bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("RightClick"));
+ if (!handled) {
+ if (_activeObject != NULL) {
+ _activeObject->applyEvent("RightClick");
+ } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
+ _scene->applyEvent("RightClick");
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onMouseRightUp() {
+ if (_activeObject) {
+ _activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_RIGHT);
+ }
+
+ bool handled = _state == GAME_RUNNING && DID_SUCCEED(applyEvent("RightRelease"));
+ if (!handled) {
+ if (_activeObject != NULL) {
+ _activeObject->applyEvent("RightRelease");
+ } else if (_state == GAME_RUNNING && _scene && _scene->pointInViewport(_mousePos.x, _mousePos.y)) {
+ _scene->applyEvent("RightRelease");
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::displayDebugInfo() {
+ char str[100];
+ if (_gameRef->_debugDebugMode) {
+ sprintf(str, "Mouse: %d, %d (scene: %d, %d)", _mousePos.x, _mousePos.y, _mousePos.x + _scene->getOffsetLeft(), _mousePos.y + _scene->getOffsetTop());
+ _systemFont->drawText((byte *)str, 0, 90, _renderer->_width, TAL_RIGHT);
+
+ sprintf(str, "Scene: %s (prev: %s)", (_scene && _scene->getName()) ? _scene->getName() : "???", _prevSceneName ? _prevSceneName : "???");
+ _systemFont->drawText((byte *)str, 0, 110, _renderer->_width, TAL_RIGHT);
+ }
+ return BaseGame::displayDebugInfo();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdGame::onScriptShutdown(ScScript *script) {
+ if (_responseBox && _responseBox->_waitingScript == script) {
+ _responseBox->_waitingScript = NULL;
+ }
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_game.h b/engines/wintermute/ad/ad_game.h
index 5707ec48fd..46427331bf 100644
--- a/engines/wintermute/ad/ad_game.h
+++ b/engines/wintermute/ad/ad_game.h
@@ -1,163 +1,163 @@
-/* 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_ADGAME_H
-#define WINTERMUTE_ADGAME_H
-
-#include "engines/wintermute/ad/ad_types.h"
-#include "engines/wintermute/base/base_game.h"
-
-namespace Wintermute {
-class AdItem;
-class AdInventory;
-class AdSceneState;
-class AdScene;
-class AdItem;
-class AdObject;
-class AdSentence;
-class AdInventoryBox;
-class AdResponseContext;
-class AdResponseBox;
-class AdGame : public BaseGame {
-public:
- virtual bool onScriptShutdown(ScScript *script);
-
- virtual bool onMouseLeftDown();
- virtual bool onMouseLeftUp();
- virtual bool onMouseLeftDblClick();
- virtual bool onMouseRightDown();
- virtual bool onMouseRightUp();
-
- virtual bool displayDebugInfo();
-
- bool addSpeechDir(const char *dir);
- bool removeSpeechDir(const char *dir);
- char *findSpeechFile(char *StringID);
-
- bool deleteItem(AdItem *Item);
- char *_itemsFile;
- bool _tempDisableSaveState;
- virtual bool resetContent();
- bool addItem(AdItem *item);
- AdItem *getItemByName(const char *name);
-
- AdObject *_inventoryOwner;
- bool isItemTaken(char *itemName);
- bool registerInventory(AdInventory *inv);
- bool unregisterInventory(AdInventory *inv);
- virtual bool displayContent(bool update = true, bool displayAll = false);
-
- bool gameResponseUsed(int ID);
- bool addGameResponse(int ID);
- bool resetResponse(int ID);
-
- bool branchResponseUsed(int ID);
- bool addBranchResponse(int ID);
- bool clearBranchResponses(char *name);
- bool startDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
- bool endDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
- virtual bool windowLoadHook(UIWindow *win, char **buf, char **params);
- virtual bool windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name);
-
- AdSceneState *getSceneState(const char *filename, bool saving);
- BaseViewport *_sceneViewport;
-
- int _texItemLifeTime;
- int _texWalkLifeTime;
- int _texStandLifeTime;
- int _texTalkLifeTime;
-
- TTalkSkipButton _talkSkipButton;
-
- virtual bool getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor);
- bool scheduleChangeScene(const char *filename, bool fadeIn);
- void setPrevSceneName(const char *name);
- void setPrevSceneFilename(const char *name);
-
- AdItem *_selectedItem;
- bool cleanup();
- DECLARE_PERSISTENT(AdGame, BaseGame)
-
- void finishSentences();
- bool showCursor();
-
- TGameStateEx _stateEx;
-
- bool displaySentences(bool frozen);
- void addSentence(AdSentence *sentence);
- bool changeScene(const char *filename, bool fadeIn);
- bool removeObject(AdObject *object);
- bool addObject(AdObject *object);
- AdScene *_scene;
- bool initLoop();
- AdGame(const Common::String &gameId);
- virtual ~AdGame();
-
- BaseArray<AdObject *> _objects;
-
- virtual bool loadFile(const char *filename);
- virtual bool loadBuffer(byte *buffer, bool complete = true);
-
- bool loadItemsFile(const char *filename, bool merge = false);
- bool loadItemsBuffer(byte *buffer, bool merge = false);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- bool validMouse();
-private:
- virtual bool externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name);
-
- AdObject *_invObject;
- BaseArray<AdInventory *> _inventories;
- char *_scheduledScene;
- bool _scheduledFadeIn;
- char *_prevSceneName;
- char *_prevSceneFilename;
- char *_debugStartupScene;
- char *_startupScene;
- bool _initialScene;
- bool _smartItemCursor;
- BaseArray<char *> _speechDirs;
- BaseArray<AdItem *> _items;
-
- BaseArray<AdSentence *> _sentences;
-
- BaseArray<AdSceneState *> _sceneStates;
- BaseArray<char *> _dlgPendingBranches;
-
- BaseArray<AdResponseContext *> _responsesBranch;
- BaseArray<AdResponseContext *> _responsesGame;
-
- AdResponseBox *_responseBox;
- AdInventoryBox *_inventoryBox;
-};
-
-} // 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_ADGAME_H
+#define WINTERMUTE_ADGAME_H
+
+#include "engines/wintermute/ad/ad_types.h"
+#include "engines/wintermute/base/base_game.h"
+
+namespace Wintermute {
+class AdItem;
+class AdInventory;
+class AdSceneState;
+class AdScene;
+class AdItem;
+class AdObject;
+class AdSentence;
+class AdInventoryBox;
+class AdResponseContext;
+class AdResponseBox;
+class AdGame : public BaseGame {
+public:
+ virtual bool onScriptShutdown(ScScript *script);
+
+ virtual bool onMouseLeftDown();
+ virtual bool onMouseLeftUp();
+ virtual bool onMouseLeftDblClick();
+ virtual bool onMouseRightDown();
+ virtual bool onMouseRightUp();
+
+ virtual bool displayDebugInfo();
+
+ bool addSpeechDir(const char *dir);
+ bool removeSpeechDir(const char *dir);
+ char *findSpeechFile(char *StringID);
+
+ bool deleteItem(AdItem *Item);
+ char *_itemsFile;
+ bool _tempDisableSaveState;
+ virtual bool resetContent();
+ bool addItem(AdItem *item);
+ AdItem *getItemByName(const char *name);
+
+ AdObject *_inventoryOwner;
+ bool isItemTaken(char *itemName);
+ bool registerInventory(AdInventory *inv);
+ bool unregisterInventory(AdInventory *inv);
+ virtual bool displayContent(bool update = true, bool displayAll = false);
+
+ bool gameResponseUsed(int ID);
+ bool addGameResponse(int ID);
+ bool resetResponse(int ID);
+
+ bool branchResponseUsed(int ID);
+ bool addBranchResponse(int ID);
+ bool clearBranchResponses(char *name);
+ bool startDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
+ bool endDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
+ virtual bool windowLoadHook(UIWindow *win, char **buf, char **params);
+ virtual bool windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name);
+
+ AdSceneState *getSceneState(const char *filename, bool saving);
+ BaseViewport *_sceneViewport;
+
+ int _texItemLifeTime;
+ int _texWalkLifeTime;
+ int _texStandLifeTime;
+ int _texTalkLifeTime;
+
+ TTalkSkipButton _talkSkipButton;
+
+ virtual bool getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor);
+ bool scheduleChangeScene(const char *filename, bool fadeIn);
+ void setPrevSceneName(const char *name);
+ void setPrevSceneFilename(const char *name);
+
+ AdItem *_selectedItem;
+ bool cleanup();
+ DECLARE_PERSISTENT(AdGame, BaseGame)
+
+ void finishSentences();
+ bool showCursor();
+
+ TGameStateEx _stateEx;
+
+ bool displaySentences(bool frozen);
+ void addSentence(AdSentence *sentence);
+ bool changeScene(const char *filename, bool fadeIn);
+ bool removeObject(AdObject *object);
+ bool addObject(AdObject *object);
+ AdScene *_scene;
+ bool initLoop();
+ AdGame(const Common::String &gameId);
+ virtual ~AdGame();
+
+ BaseArray<AdObject *> _objects;
+
+ virtual bool loadFile(const char *filename);
+ virtual bool loadBuffer(byte *buffer, bool complete = true);
+
+ bool loadItemsFile(const char *filename, bool merge = false);
+ bool loadItemsBuffer(byte *buffer, bool merge = false);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ bool validMouse();
+private:
+ virtual bool externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name);
+
+ AdObject *_invObject;
+ BaseArray<AdInventory *> _inventories;
+ char *_scheduledScene;
+ bool _scheduledFadeIn;
+ char *_prevSceneName;
+ char *_prevSceneFilename;
+ char *_debugStartupScene;
+ char *_startupScene;
+ bool _initialScene;
+ bool _smartItemCursor;
+ BaseArray<char *> _speechDirs;
+ BaseArray<AdItem *> _items;
+
+ BaseArray<AdSentence *> _sentences;
+
+ BaseArray<AdSceneState *> _sceneStates;
+ BaseArray<char *> _dlgPendingBranches;
+
+ BaseArray<AdResponseContext *> _responsesBranch;
+ BaseArray<AdResponseContext *> _responsesGame;
+
+ AdResponseBox *_responseBox;
+ AdInventoryBox *_inventoryBox;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_inventory.cpp b/engines/wintermute/ad/ad_inventory.cpp
index 44b2dc0508..72f8fa0fb4 100644
--- a/engines/wintermute/ad/ad_inventory.cpp
+++ b/engines/wintermute/ad/ad_inventory.cpp
@@ -1,136 +1,136 @@
-/* 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/ad/ad_inventory.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_item.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdInventory, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdInventory::AdInventory(BaseGame *inGame) : BaseObject(inGame) {
- _scrollOffset = 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdInventory::~AdInventory() {
- _takenItems.clear(); // ref only
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventory::insertItem(const char *name, const char *insertAfter) {
- if (name == NULL) {
- return STATUS_FAILED;
- }
-
- AdItem *item = ((AdGame *)_gameRef)->getItemByName(name);
- if (item == NULL) {
- return STATUS_FAILED;
- }
-
- int insertIndex = -1;
- for (uint32 i = 0; i < _takenItems.size(); i++) {
- if (scumm_stricmp(_takenItems[i]->getName(), name) == 0) {
- _takenItems.remove_at(i);
- i--;
- continue;
- }
- if (insertAfter && scumm_stricmp(_takenItems[i]->getName(), insertAfter) == 0) {
- insertIndex = i + 1;
- }
- }
-
-
- if (insertIndex == -1) {
- _takenItems.add(item);
- } else {
- _takenItems.insert_at(insertIndex, item);
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventory::removeItem(const char *name) {
- if (name == NULL) {
- return STATUS_FAILED;
- }
-
- for (uint32 i = 0; i < _takenItems.size(); i++) {
- if (scumm_stricmp(_takenItems[i]->getName(), name) == 0) {
- if (((AdGame *)_gameRef)->_selectedItem == _takenItems[i]) {
- ((AdGame *)_gameRef)->_selectedItem = NULL;
- }
- _takenItems.remove_at(i);
- return STATUS_OK;
- }
- }
-
- return STATUS_FAILED;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventory::removeItem(AdItem *item) {
- if (item == NULL) {
- return STATUS_FAILED;
- }
-
- for (uint32 i = 0; i < _takenItems.size(); i++) {
- if (_takenItems[i] == item) {
- if (((AdGame *)_gameRef)->_selectedItem == _takenItems[i]) {
- ((AdGame *)_gameRef)->_selectedItem = NULL;
- }
- _takenItems.remove_at(i);
- return STATUS_OK;
- }
- }
-
- return STATUS_FAILED;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventory::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- _takenItems.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
-
- 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/ad/ad_inventory.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_item.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdInventory, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdInventory::AdInventory(BaseGame *inGame) : BaseObject(inGame) {
+ _scrollOffset = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdInventory::~AdInventory() {
+ _takenItems.clear(); // ref only
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventory::insertItem(const char *name, const char *insertAfter) {
+ if (name == NULL) {
+ return STATUS_FAILED;
+ }
+
+ AdItem *item = ((AdGame *)_gameRef)->getItemByName(name);
+ if (item == NULL) {
+ return STATUS_FAILED;
+ }
+
+ int insertIndex = -1;
+ for (uint32 i = 0; i < _takenItems.size(); i++) {
+ if (scumm_stricmp(_takenItems[i]->getName(), name) == 0) {
+ _takenItems.remove_at(i);
+ i--;
+ continue;
+ }
+ if (insertAfter && scumm_stricmp(_takenItems[i]->getName(), insertAfter) == 0) {
+ insertIndex = i + 1;
+ }
+ }
+
+
+ if (insertIndex == -1) {
+ _takenItems.add(item);
+ } else {
+ _takenItems.insert_at(insertIndex, item);
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventory::removeItem(const char *name) {
+ if (name == NULL) {
+ return STATUS_FAILED;
+ }
+
+ for (uint32 i = 0; i < _takenItems.size(); i++) {
+ if (scumm_stricmp(_takenItems[i]->getName(), name) == 0) {
+ if (((AdGame *)_gameRef)->_selectedItem == _takenItems[i]) {
+ ((AdGame *)_gameRef)->_selectedItem = NULL;
+ }
+ _takenItems.remove_at(i);
+ return STATUS_OK;
+ }
+ }
+
+ return STATUS_FAILED;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventory::removeItem(AdItem *item) {
+ if (item == NULL) {
+ return STATUS_FAILED;
+ }
+
+ for (uint32 i = 0; i < _takenItems.size(); i++) {
+ if (_takenItems[i] == item) {
+ if (((AdGame *)_gameRef)->_selectedItem == _takenItems[i]) {
+ ((AdGame *)_gameRef)->_selectedItem = NULL;
+ }
+ _takenItems.remove_at(i);
+ return STATUS_OK;
+ }
+ }
+
+ return STATUS_FAILED;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventory::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ _takenItems.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_scrollOffset));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_inventory.h b/engines/wintermute/ad/ad_inventory.h
index 9a12eb1abe..4017d914bc 100644
--- a/engines/wintermute/ad/ad_inventory.h
+++ b/engines/wintermute/ad/ad_inventory.h
@@ -1,52 +1,52 @@
-/* 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_ADINVENTORY_H
-#define WINTERMUTE_ADINVENTORY_H
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class AdItem;
-
-class AdInventory : public BaseObject {
-public:
- DECLARE_PERSISTENT(AdInventory, BaseObject)
- bool removeItem(const char *name);
- bool removeItem(AdItem *Item);
- bool insertItem(const char *name, const char *insertAfter = NULL);
- AdInventory(BaseGame *inGame);
- virtual ~AdInventory();
- BaseArray<AdItem *> _takenItems;
- int _scrollOffset;
-};
-
-} // 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_ADINVENTORY_H
+#define WINTERMUTE_ADINVENTORY_H
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class AdItem;
+
+class AdInventory : public BaseObject {
+public:
+ DECLARE_PERSISTENT(AdInventory, BaseObject)
+ bool removeItem(const char *name);
+ bool removeItem(AdItem *Item);
+ bool insertItem(const char *name, const char *insertAfter = NULL);
+ AdInventory(BaseGame *inGame);
+ virtual ~AdInventory();
+ BaseArray<AdItem *> _takenItems;
+ int _scrollOffset;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_inventory_box.cpp b/engines/wintermute/ad/ad_inventory_box.cpp
index ad679007df..16b8e01ff3 100644
--- a/engines/wintermute/ad/ad_inventory_box.cpp
+++ b/engines/wintermute/ad/ad_inventory_box.cpp
@@ -1,388 +1,388 @@
-/* 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/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_inventory_box.h"
-#include "engines/wintermute/ad/ad_inventory.h"
-#include "engines/wintermute/ad/ad_item.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/base_viewport.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/ui/ui_button.h"
-#include "engines/wintermute/ui/ui_window.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-#include "common/rect.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdInventoryBox, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdInventoryBox::AdInventoryBox(BaseGame *inGame) : BaseObject(inGame) {
- _itemsArea.setEmpty();
- _scrollOffset = 0;
- _spacing = 0;
- _itemWidth = _itemHeight = 50;
- _scrollBy = 1;
-
- _window = NULL;
- _closeButton = NULL;
-
- _hideSelected = false;
-
- _visible = false;
- _exclusive = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdInventoryBox::~AdInventoryBox() {
- _gameRef->unregisterObject(_window);
- _window = NULL;
-
- delete _closeButton;
- _closeButton = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::listen(BaseScriptHolder *param1, uint32 param2) {
- UIObject *obj = (UIObject *)param1;
-
- switch (obj->_type) {
- case UI_BUTTON:
- if (scumm_stricmp(obj->getName(), "close") == 0) {
- _visible = false;
- } else if (scumm_stricmp(obj->getName(), "prev") == 0) {
- _scrollOffset -= _scrollBy;
- _scrollOffset = MAX(_scrollOffset, 0);
- } else if (scumm_stricmp(obj->getName(), "next") == 0) {
- _scrollOffset += _scrollBy;
- } else {
- return BaseObject::listen(param1, param2);
- }
- break;
- default:
- error("AdInventoryBox::Listen - Unhandled enum");
- break;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::display() {
- AdGame *adGame = (AdGame *)_gameRef;
-
- if (!_visible) {
- return STATUS_OK;
- }
-
- int itemsX, itemsY;
- itemsX = (int)floor((float)((_itemsArea.right - _itemsArea.left + _spacing) / (_itemWidth + _spacing)));
- itemsY = (int)floor((float)((_itemsArea.bottom - _itemsArea.top + _spacing) / (_itemHeight + _spacing)));
-
- if (_window) {
- _window->enableWidget("prev", _scrollOffset > 0);
- _window->enableWidget("next", _scrollOffset + itemsX * itemsY < (int32)adGame->_inventoryOwner->getInventory()->_takenItems.size());
- }
-
-
- if (_closeButton) {
- _closeButton->_posX = _closeButton->_posY = 0;
- _closeButton->_width = _gameRef->_renderer->_width;
- _closeButton->_height = _gameRef->_renderer->_height;
-
- _closeButton->display();
- }
-
-
- // display window
- Rect32 rect = _itemsArea;
- if (_window) {
- rect.offsetRect(_window->_posX, _window->_posY);
- _window->display();
- }
-
- // display items
- if (_window && _window->_alphaColor != 0) {
- _gameRef->_renderer->_forceAlphaColor = _window->_alphaColor;
- }
- int yyy = rect.top;
- for (int j = 0; j < itemsY; j++) {
- int xxx = rect.left;
- for (int i = 0; i < itemsX; i++) {
- int itemIndex = _scrollOffset + j * itemsX + i;
- if (itemIndex >= 0 && itemIndex < (int32)adGame->_inventoryOwner->getInventory()->_takenItems.size()) {
- AdItem *item = adGame->_inventoryOwner->getInventory()->_takenItems[itemIndex];
- if (item != ((AdGame *)_gameRef)->_selectedItem || !_hideSelected) {
- item->update();
- item->display(xxx, yyy);
- }
- }
-
- xxx += (_itemWidth + _spacing);
- }
- yyy += (_itemHeight + _spacing);
- }
- if (_window && _window->_alphaColor != 0) {
- _gameRef->_renderer->_forceAlphaColor = 0;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdInventoryBox::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing INVENTORY_BOX file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(INVENTORY_BOX)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(WINDOW)
-TOKEN_DEF(EXCLUSIVE)
-TOKEN_DEF(ALWAYS_VISIBLE)
-TOKEN_DEF(AREA)
-TOKEN_DEF(SPACING)
-TOKEN_DEF(ITEM_WIDTH)
-TOKEN_DEF(ITEM_HEIGHT)
-TOKEN_DEF(SCROLL_BY)
-TOKEN_DEF(NAME)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(HIDE_SELECTED)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(INVENTORY_BOX)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(WINDOW)
- TOKEN_TABLE(EXCLUSIVE)
- TOKEN_TABLE(ALWAYS_VISIBLE)
- TOKEN_TABLE(AREA)
- TOKEN_TABLE(SPACING)
- TOKEN_TABLE(ITEM_WIDTH)
- TOKEN_TABLE(ITEM_HEIGHT)
- TOKEN_TABLE(SCROLL_BY)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(HIDE_SELECTED)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd = 2;
- BaseParser parser;
- bool alwaysVisible = false;
-
- _exclusive = false;
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_INVENTORY_BOX) {
- _gameRef->LOG(0, "'INVENTORY_BOX' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_WINDOW:
- delete _window;
- _window = new UIWindow(_gameRef);
- if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
- delete _window;
- _window = NULL;
- cmd = PARSERR_GENERIC;
- } else {
- _gameRef->registerObject(_window);
- }
- break;
-
- case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
- break;
-
- case TOKEN_EXCLUSIVE:
- parser.scanStr((char *)params, "%b", &_exclusive);
- break;
-
- case TOKEN_HIDE_SELECTED:
- parser.scanStr((char *)params, "%b", &_hideSelected);
- break;
-
- case TOKEN_ALWAYS_VISIBLE:
- parser.scanStr((char *)params, "%b", &alwaysVisible);
- break;
-
- case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
- break;
-
- case TOKEN_ITEM_WIDTH:
- parser.scanStr((char *)params, "%d", &_itemWidth);
- break;
-
- case TOKEN_ITEM_HEIGHT:
- parser.scanStr((char *)params, "%d", &_itemHeight);
- break;
-
- case TOKEN_SCROLL_BY:
- parser.scanStr((char *)params, "%d", &_scrollBy);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in INVENTORY_BOX definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading INVENTORY_BOX definition");
- return STATUS_FAILED;
- }
-
- if (_exclusive) {
- delete _closeButton;
- _closeButton = new UIButton(_gameRef);
- if (_closeButton) {
- _closeButton->setName("close");
- _closeButton->setListener(this, _closeButton, 0);
- _closeButton->_parent = _window;
- }
- }
-
- _visible = alwaysVisible;
-
- if (_window) {
- for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
- _window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
- }
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "INVENTORY_BOX\n");
- buffer->putTextIndent(indent, "{\n");
-
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
-
- buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _itemsArea.left, _itemsArea.top, _itemsArea.right, _itemsArea.bottom);
-
- buffer->putTextIndent(indent + 2, "EXCLUSIVE=%s\n", _exclusive ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "HIDE_SELECTED=%s\n", _hideSelected ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "ALWAYS_VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
- buffer->putTextIndent(indent + 2, "ITEM_WIDTH=%d\n", _itemWidth);
- buffer->putTextIndent(indent + 2, "ITEM_HEIGHT=%d\n", _itemHeight);
- buffer->putTextIndent(indent + 2, "SCROLL_BY=%d\n", _scrollBy);
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // window
- if (_window) {
- _window->saveAsText(buffer, indent + 2);
- }
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // editor properties
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n");
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_closeButton));
- persistMgr->transfer(TMEMBER(_hideSelected));
- persistMgr->transfer(TMEMBER(_itemHeight));
- persistMgr->transfer(TMEMBER(_itemsArea));
- persistMgr->transfer(TMEMBER(_itemWidth));
- persistMgr->transfer(TMEMBER(_scrollBy));
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_spacing));
- persistMgr->transfer(TMEMBER(_visible));
- persistMgr->transfer(TMEMBER(_window));
- persistMgr->transfer(TMEMBER(_exclusive));
-
- 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/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_inventory_box.h"
+#include "engines/wintermute/ad/ad_inventory.h"
+#include "engines/wintermute/ad/ad_item.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/base_viewport.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/ui/ui_button.h"
+#include "engines/wintermute/ui/ui_window.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+#include "common/rect.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdInventoryBox, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdInventoryBox::AdInventoryBox(BaseGame *inGame) : BaseObject(inGame) {
+ _itemsArea.setEmpty();
+ _scrollOffset = 0;
+ _spacing = 0;
+ _itemWidth = _itemHeight = 50;
+ _scrollBy = 1;
+
+ _window = NULL;
+ _closeButton = NULL;
+
+ _hideSelected = false;
+
+ _visible = false;
+ _exclusive = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdInventoryBox::~AdInventoryBox() {
+ _gameRef->unregisterObject(_window);
+ _window = NULL;
+
+ delete _closeButton;
+ _closeButton = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::listen(BaseScriptHolder *param1, uint32 param2) {
+ UIObject *obj = (UIObject *)param1;
+
+ switch (obj->_type) {
+ case UI_BUTTON:
+ if (scumm_stricmp(obj->getName(), "close") == 0) {
+ _visible = false;
+ } else if (scumm_stricmp(obj->getName(), "prev") == 0) {
+ _scrollOffset -= _scrollBy;
+ _scrollOffset = MAX(_scrollOffset, 0);
+ } else if (scumm_stricmp(obj->getName(), "next") == 0) {
+ _scrollOffset += _scrollBy;
+ } else {
+ return BaseObject::listen(param1, param2);
+ }
+ break;
+ default:
+ error("AdInventoryBox::Listen - Unhandled enum");
+ break;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::display() {
+ AdGame *adGame = (AdGame *)_gameRef;
+
+ if (!_visible) {
+ return STATUS_OK;
+ }
+
+ int itemsX, itemsY;
+ itemsX = (int)floor((float)((_itemsArea.right - _itemsArea.left + _spacing) / (_itemWidth + _spacing)));
+ itemsY = (int)floor((float)((_itemsArea.bottom - _itemsArea.top + _spacing) / (_itemHeight + _spacing)));
+
+ if (_window) {
+ _window->enableWidget("prev", _scrollOffset > 0);
+ _window->enableWidget("next", _scrollOffset + itemsX * itemsY < (int32)adGame->_inventoryOwner->getInventory()->_takenItems.size());
+ }
+
+
+ if (_closeButton) {
+ _closeButton->_posX = _closeButton->_posY = 0;
+ _closeButton->_width = _gameRef->_renderer->_width;
+ _closeButton->_height = _gameRef->_renderer->_height;
+
+ _closeButton->display();
+ }
+
+
+ // display window
+ Rect32 rect = _itemsArea;
+ if (_window) {
+ rect.offsetRect(_window->_posX, _window->_posY);
+ _window->display();
+ }
+
+ // display items
+ if (_window && _window->_alphaColor != 0) {
+ _gameRef->_renderer->_forceAlphaColor = _window->_alphaColor;
+ }
+ int yyy = rect.top;
+ for (int j = 0; j < itemsY; j++) {
+ int xxx = rect.left;
+ for (int i = 0; i < itemsX; i++) {
+ int itemIndex = _scrollOffset + j * itemsX + i;
+ if (itemIndex >= 0 && itemIndex < (int32)adGame->_inventoryOwner->getInventory()->_takenItems.size()) {
+ AdItem *item = adGame->_inventoryOwner->getInventory()->_takenItems[itemIndex];
+ if (item != ((AdGame *)_gameRef)->_selectedItem || !_hideSelected) {
+ item->update();
+ item->display(xxx, yyy);
+ }
+ }
+
+ xxx += (_itemWidth + _spacing);
+ }
+ yyy += (_itemHeight + _spacing);
+ }
+ if (_window && _window->_alphaColor != 0) {
+ _gameRef->_renderer->_forceAlphaColor = 0;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdInventoryBox::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing INVENTORY_BOX file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(INVENTORY_BOX)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(WINDOW)
+TOKEN_DEF(EXCLUSIVE)
+TOKEN_DEF(ALWAYS_VISIBLE)
+TOKEN_DEF(AREA)
+TOKEN_DEF(SPACING)
+TOKEN_DEF(ITEM_WIDTH)
+TOKEN_DEF(ITEM_HEIGHT)
+TOKEN_DEF(SCROLL_BY)
+TOKEN_DEF(NAME)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(HIDE_SELECTED)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(INVENTORY_BOX)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(WINDOW)
+ TOKEN_TABLE(EXCLUSIVE)
+ TOKEN_TABLE(ALWAYS_VISIBLE)
+ TOKEN_TABLE(AREA)
+ TOKEN_TABLE(SPACING)
+ TOKEN_TABLE(ITEM_WIDTH)
+ TOKEN_TABLE(ITEM_HEIGHT)
+ TOKEN_TABLE(SCROLL_BY)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(HIDE_SELECTED)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd = 2;
+ BaseParser parser;
+ bool alwaysVisible = false;
+
+ _exclusive = false;
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_INVENTORY_BOX) {
+ _gameRef->LOG(0, "'INVENTORY_BOX' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_WINDOW:
+ delete _window;
+ _window = new UIWindow(_gameRef);
+ if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
+ delete _window;
+ _window = NULL;
+ cmd = PARSERR_GENERIC;
+ } else {
+ _gameRef->registerObject(_window);
+ }
+ break;
+
+ case TOKEN_AREA:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
+ break;
+
+ case TOKEN_EXCLUSIVE:
+ parser.scanStr((char *)params, "%b", &_exclusive);
+ break;
+
+ case TOKEN_HIDE_SELECTED:
+ parser.scanStr((char *)params, "%b", &_hideSelected);
+ break;
+
+ case TOKEN_ALWAYS_VISIBLE:
+ parser.scanStr((char *)params, "%b", &alwaysVisible);
+ break;
+
+ case TOKEN_SPACING:
+ parser.scanStr((char *)params, "%d", &_spacing);
+ break;
+
+ case TOKEN_ITEM_WIDTH:
+ parser.scanStr((char *)params, "%d", &_itemWidth);
+ break;
+
+ case TOKEN_ITEM_HEIGHT:
+ parser.scanStr((char *)params, "%d", &_itemHeight);
+ break;
+
+ case TOKEN_SCROLL_BY:
+ parser.scanStr((char *)params, "%d", &_scrollBy);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in INVENTORY_BOX definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading INVENTORY_BOX definition");
+ return STATUS_FAILED;
+ }
+
+ if (_exclusive) {
+ delete _closeButton;
+ _closeButton = new UIButton(_gameRef);
+ if (_closeButton) {
+ _closeButton->setName("close");
+ _closeButton->setListener(this, _closeButton, 0);
+ _closeButton->_parent = _window;
+ }
+ }
+
+ _visible = alwaysVisible;
+
+ if (_window) {
+ for (uint32 i = 0; i < _window->_widgets.size(); i++) {
+ if (!_window->_widgets[i]->_listenerObject) {
+ _window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "INVENTORY_BOX\n");
+ buffer->putTextIndent(indent, "{\n");
+
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
+
+ buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _itemsArea.left, _itemsArea.top, _itemsArea.right, _itemsArea.bottom);
+
+ buffer->putTextIndent(indent + 2, "EXCLUSIVE=%s\n", _exclusive ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "HIDE_SELECTED=%s\n", _hideSelected ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "ALWAYS_VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
+ buffer->putTextIndent(indent + 2, "ITEM_WIDTH=%d\n", _itemWidth);
+ buffer->putTextIndent(indent + 2, "ITEM_HEIGHT=%d\n", _itemHeight);
+ buffer->putTextIndent(indent + 2, "SCROLL_BY=%d\n", _scrollBy);
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // window
+ if (_window) {
+ _window->saveAsText(buffer, indent + 2);
+ }
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // editor properties
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n");
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_closeButton));
+ persistMgr->transfer(TMEMBER(_hideSelected));
+ persistMgr->transfer(TMEMBER(_itemHeight));
+ persistMgr->transfer(TMEMBER(_itemsArea));
+ persistMgr->transfer(TMEMBER(_itemWidth));
+ persistMgr->transfer(TMEMBER(_scrollBy));
+ persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transfer(TMEMBER(_spacing));
+ persistMgr->transfer(TMEMBER(_visible));
+ persistMgr->transfer(TMEMBER(_window));
+ persistMgr->transfer(TMEMBER(_exclusive));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_inventory_box.h b/engines/wintermute/ad/ad_inventory_box.h
index 451ebf9635..cb6d084562 100644
--- a/engines/wintermute/ad/ad_inventory_box.h
+++ b/engines/wintermute/ad/ad_inventory_box.h
@@ -1,65 +1,65 @@
-/* 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_ADINVENTORYBOX_H
-#define WINTERMUTE_ADINVENTORYBOX_H
-
-#include "engines/wintermute/base/base_object.h"
-#include "common/rect.h"
-
-namespace Wintermute {
-class UIButton;
-class UIWindow;
-
-class AdInventoryBox : public BaseObject {
-public:
- bool _hideSelected;
- DECLARE_PERSISTENT(AdInventoryBox, BaseObject)
- bool _visible;
- virtual bool display();
- UIButton *_closeButton;
- int _spacing;
- int _scrollOffset;
- Rect32 _itemsArea;
- bool listen(BaseScriptHolder *param1, uint32 param2);
- UIWindow *_window;
- AdInventoryBox(BaseGame *inGame);
- virtual ~AdInventoryBox();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
-private:
- bool _exclusive;
- int _scrollBy;
- int _itemHeight;
- int _itemWidth;
-};
-
-} // 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_ADINVENTORYBOX_H
+#define WINTERMUTE_ADINVENTORYBOX_H
+
+#include "engines/wintermute/base/base_object.h"
+#include "common/rect.h"
+
+namespace Wintermute {
+class UIButton;
+class UIWindow;
+
+class AdInventoryBox : public BaseObject {
+public:
+ bool _hideSelected;
+ DECLARE_PERSISTENT(AdInventoryBox, BaseObject)
+ bool _visible;
+ virtual bool display();
+ UIButton *_closeButton;
+ int _spacing;
+ int _scrollOffset;
+ Rect32 _itemsArea;
+ bool listen(BaseScriptHolder *param1, uint32 param2);
+ UIWindow *_window;
+ AdInventoryBox(BaseGame *inGame);
+ virtual ~AdInventoryBox();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+private:
+ bool _exclusive;
+ int _scrollBy;
+ int _itemHeight;
+ int _itemWidth;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_item.cpp b/engines/wintermute/ad/ad_item.cpp
index f5c8b16308..afd813933b 100644
--- a/engines/wintermute/ad/ad_item.cpp
+++ b/engines/wintermute/ad/ad_item.cpp
@@ -1,813 +1,813 @@
-/* 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/ad/ad_item.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdItem, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdItem::AdItem(BaseGame *inGame) : AdTalkHolder(inGame) {
- _spriteHover = NULL;
- _cursorNormal = _cursorHover = NULL;
-
- _cursorCombined = true;
- _inInventory = false;
-
- _displayAmount = false;
- _amount = 0;
- _amountOffsetX = 0;
- _amountOffsetY = 0;
- _amountAlign = TAL_RIGHT;
- _amountString = NULL;
-
- _state = STATE_READY;
-
- _movable = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdItem::~AdItem() {
- delete _spriteHover;
- delete _cursorNormal;
- delete _cursorHover;
- _spriteHover = NULL;
- _cursorNormal = NULL;
- _cursorHover = NULL;
-
- delete[] _amountString;
- _amountString = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdItem::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing ITEM file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(ITEM)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(CURSOR_HOVER)
-TOKEN_DEF(CURSOR_COMBINED)
-TOKEN_DEF(CURSOR)
-TOKEN_DEF(NAME)
-TOKEN_DEF(IMAGE_HOVER)
-TOKEN_DEF(IMAGE)
-TOKEN_DEF(EVENTS)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF(FONT)
-TOKEN_DEF(ALPHA_COLOR)
-TOKEN_DEF(ALPHA)
-TOKEN_DEF(TALK_SPECIAL)
-TOKEN_DEF(TALK)
-TOKEN_DEF(SPRITE_HOVER)
-TOKEN_DEF(SPRITE)
-TOKEN_DEF(DISPLAY_AMOUNT)
-TOKEN_DEF(AMOUNT_OFFSET_X)
-TOKEN_DEF(AMOUNT_OFFSET_Y)
-TOKEN_DEF(AMOUNT_ALIGN)
-TOKEN_DEF(AMOUNT_STRING)
-TOKEN_DEF(AMOUNT)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ITEM)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(CURSOR_HOVER)
- TOKEN_TABLE(CURSOR_COMBINED)
- TOKEN_TABLE(CURSOR)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(IMAGE_HOVER)
- TOKEN_TABLE(IMAGE)
- TOKEN_TABLE(EVENTS)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(ALPHA_COLOR)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE(TALK_SPECIAL)
- TOKEN_TABLE(TALK)
- TOKEN_TABLE(SPRITE_HOVER)
- TOKEN_TABLE(SPRITE)
- TOKEN_TABLE(DISPLAY_AMOUNT)
- TOKEN_TABLE(AMOUNT_OFFSET_X)
- TOKEN_TABLE(AMOUNT_OFFSET_Y)
- TOKEN_TABLE(AMOUNT_ALIGN)
- TOKEN_TABLE(AMOUNT_STRING)
- TOKEN_TABLE(AMOUNT)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd = 2;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ITEM) {
- _gameRef->LOG(0, "'ITEM' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- int ar = 0, ag = 0, ab = 0, alpha = 255;
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_FONT:
- setFont((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_IMAGE:
- case TOKEN_SPRITE:
- delete _sprite;
- _sprite = new BaseSprite(_gameRef, this);
- if (!_sprite || DID_FAIL(_sprite->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
- delete _sprite;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_IMAGE_HOVER:
- case TOKEN_SPRITE_HOVER:
- delete _spriteHover;
- _spriteHover = new BaseSprite(_gameRef, this);
- if (!_spriteHover || DID_FAIL(_spriteHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
- delete _spriteHover;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_AMOUNT:
- parser.scanStr((char *)params, "%d", &_amount);
- break;
-
- case TOKEN_DISPLAY_AMOUNT:
- parser.scanStr((char *)params, "%b", &_displayAmount);
- break;
-
- case TOKEN_AMOUNT_OFFSET_X:
- parser.scanStr((char *)params, "%d", &_amountOffsetX);
- break;
-
- case TOKEN_AMOUNT_OFFSET_Y:
- parser.scanStr((char *)params, "%d", &_amountOffsetY);
- break;
-
- case TOKEN_AMOUNT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
- _amountAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
- _amountAlign = TAL_RIGHT;
- } else {
- _amountAlign = TAL_CENTER;
- }
- break;
-
- case TOKEN_AMOUNT_STRING:
- BaseUtils::setString(&_amountString, (char *)params);
- break;
-
- case TOKEN_TALK: {
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSprites.add(spr);
- }
- }
- break;
-
- case TOKEN_TALK_SPECIAL: {
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
- cmd = PARSERR_GENERIC;
- } else {
- _talkSpritesEx.add(spr);
- }
- }
- break;
-
- case TOKEN_CURSOR:
- delete _cursorNormal;
- _cursorNormal = new BaseSprite(_gameRef);
- if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
- delete _cursorNormal;
- _cursorNormal = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_CURSOR_HOVER:
- delete _cursorHover;
- _cursorHover = new BaseSprite(_gameRef);
- if (!_cursorHover || DID_FAIL(_cursorHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
- delete _cursorHover;
- _cursorHover = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_CURSOR_COMBINED:
- parser.scanStr((char *)params, "%b", &_cursorCombined);
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
- break;
-
- case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ITEM definition");
- return STATUS_FAILED;
- }
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading ITEM definition");
- return STATUS_FAILED;
- }
-
- if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
- ar = ag = ab = 255;
- }
- _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::update() {
- _currentSprite = NULL;
-
- if (_state == STATE_READY && _animSprite) {
- delete _animSprite;
- _animSprite = NULL;
- }
-
- // finished playing animation?
- if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
- _state = STATE_READY;
- _currentSprite = _animSprite;
- }
-
- if (_sentence && _state != STATE_TALKING) {
- _sentence->finish();
- }
-
- // default: stand animation
- if (!_currentSprite) {
- _currentSprite = _sprite;
- }
-
- switch (_state) {
- //////////////////////////////////////////////////////////////////////////
- case STATE_PLAYING_ANIM:
- _currentSprite = _animSprite;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_READY:
- if (!_animSprite) {
- if (_gameRef->_activeObject == this && _spriteHover) {
- _currentSprite = _spriteHover;
- } else {
- _currentSprite = _sprite;
- }
- }
- break;
-
- //////////////////////////////////////////////////////////////////////////
- case STATE_TALKING: {
- _sentence->update();
- if (_sentence->_currentSprite) {
- _tempSprite2 = _sentence->_currentSprite;
- }
-
- bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
- if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
- if (timeIsUp) {
- _sentence->finish();
- _tempSprite2 = NULL;
- _state = STATE_READY;
- } else {
- _tempSprite2 = getTalkStance(_sentence->getNextStance());
- if (_tempSprite2) {
- _tempSprite2->reset();
- _currentSprite = _tempSprite2;
- }
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- } else {
- _currentSprite = _tempSprite2;
- ((AdGame *)_gameRef)->addSentence(_sentence);
- }
- }
- default:
- break;
- }
- _ready = (_state == STATE_READY);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::display(int x, int y) {
- int width = 0;
- if (_currentSprite) {
- Rect32 rc;
- _currentSprite->getBoundingRect(&rc, 0, 0);
- width = rc.width();
- }
-
- _posX = x + width / 2;
- _posY = y;
-
- bool ret;
- if (_currentSprite) {
- ret = _currentSprite->draw(x, y, this, 100, 100, _alphaColor);
- } else {
- ret = STATUS_OK;
- }
-
- if (_displayAmount) {
- int amountX = x;
- int amountY = y + _amountOffsetY;
-
- if (_amountAlign == TAL_RIGHT) {
- width -= _amountOffsetX;
- amountX -= _amountOffsetX;
- }
- amountX += _amountOffsetX;
-
- BaseFont *font = _font ? _font : _gameRef->_systemFont;
- if (font) {
- if (_amountString) {
- font->drawText((byte *)_amountString, amountX, amountY, width, _amountAlign);
- } else {
- char str[256];
- sprintf(str, "%d", _amount);
- font->drawText((byte *)str, amountX, amountY, width, _amountAlign);
- }
- }
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // SetHoverSprite
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetHoverSprite") == 0) {
- stack->correctParams(1);
-
- bool setCurrent = false;
- if (_currentSprite && _currentSprite == _spriteHover) {
- setCurrent = true;
- }
-
- const char *filename = stack->pop()->getString();
-
- delete _spriteHover;
- _spriteHover = NULL;
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- stack->pushBool(false);
- script->runtimeError("Item.SetHoverSprite failed for file '%s'", filename);
- } else {
- _spriteHover = spr;
- if (setCurrent) {
- _currentSprite = _spriteHover;
- }
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetHoverSprite
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetHoverSprite") == 0) {
- stack->correctParams(0);
-
- if (!_spriteHover || !_spriteHover->getFilename()) {
- stack->pushNULL();
- } else {
- stack->pushString(_spriteHover->getFilename());
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetHoverSpriteObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetHoverSpriteObject") == 0) {
- stack->correctParams(0);
- if (!_spriteHover) {
- stack->pushNULL();
- } else {
- stack->pushNative(_spriteHover, true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetNormalCursor
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetNormalCursor") == 0) {
- stack->correctParams(1);
-
- const char *filename = stack->pop()->getString();
-
- delete _cursorNormal;
- _cursorNormal = NULL;
- BaseSprite *spr = new BaseSprite(_gameRef);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- stack->pushBool(false);
- script->runtimeError("Item.SetNormalCursor failed for file '%s'", filename);
- } else {
- _cursorNormal = spr;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetNormalCursor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetNormalCursor") == 0) {
- stack->correctParams(0);
-
- if (!_cursorNormal || !_cursorNormal->getFilename()) {
- stack->pushNULL();
- } else {
- stack->pushString(_cursorNormal->getFilename());
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetNormalCursorObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetNormalCursorObject") == 0) {
- stack->correctParams(0);
-
- if (!_cursorNormal) {
- stack->pushNULL();
- } else {
- stack->pushNative(_cursorNormal, true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetHoverCursor
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetHoverCursor") == 0) {
- stack->correctParams(1);
-
- const char *filename = stack->pop()->getString();
-
- delete _cursorHover;
- _cursorHover = NULL;
- BaseSprite *spr = new BaseSprite(_gameRef);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- stack->pushBool(false);
- script->runtimeError("Item.SetHoverCursor failed for file '%s'", filename);
- } else {
- _cursorHover = spr;
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetHoverCursor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetHoverCursor") == 0) {
- stack->correctParams(0);
-
- if (!_cursorHover || !_cursorHover->getFilename()) {
- stack->pushNULL();
- } else {
- stack->pushString(_cursorHover->getFilename());
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetHoverCursorObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetHoverCursorObject") == 0) {
- stack->correctParams(0);
-
- if (!_cursorHover) {
- stack->pushNULL();
- } else {
- stack->pushNative(_cursorHover, true);
- }
- return STATUS_OK;
- } else {
- return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdItem::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("item");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Name") == 0) {
- _scValue->setString(getName());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DisplayAmount
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DisplayAmount") == 0) {
- _scValue->setBool(_displayAmount);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Amount
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Amount") == 0) {
- _scValue->setInt(_amount);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountOffsetX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountOffsetX") == 0) {
- _scValue->setInt(_amountOffsetX);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountOffsetY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountOffsetY") == 0) {
- _scValue->setInt(_amountOffsetY);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountAlign
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountAlign") == 0) {
- _scValue->setInt(_amountAlign);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountString") == 0) {
- if (!_amountString) {
- _scValue->setNULL();
- } else {
- _scValue->setString(_amountString);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CursorCombined
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CursorCombined") == 0) {
- _scValue->setBool(_cursorCombined);
- return _scValue;
- } else {
- return AdTalkHolder::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Name") == 0) {
- setName(value->getString());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DisplayAmount
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DisplayAmount") == 0) {
- _displayAmount = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Amount
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Amount") == 0) {
- _amount = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountOffsetX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountOffsetX") == 0) {
- _amountOffsetX = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountOffsetY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountOffsetY") == 0) {
- _amountOffsetY = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountAlign
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountAlign") == 0) {
- _amountAlign = (TTextAlign)value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AmountString
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AmountString") == 0) {
- if (value->isNULL()) {
- delete[] _amountString;
- _amountString = NULL;
- } else {
- BaseUtils::setString(&_amountString, value->getString());
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CursorCombined
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CursorCombined") == 0) {
- _cursorCombined = value->getBool();
- return STATUS_OK;
- } else {
- return AdTalkHolder::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdItem::scToString() {
- return "[item]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::persist(BasePersistenceManager *persistMgr) {
-
- AdTalkHolder::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_cursorCombined));
- persistMgr->transfer(TMEMBER(_cursorHover));
- persistMgr->transfer(TMEMBER(_cursorNormal));
- persistMgr->transfer(TMEMBER(_spriteHover));
- persistMgr->transfer(TMEMBER(_inInventory));
- persistMgr->transfer(TMEMBER(_displayAmount));
- persistMgr->transfer(TMEMBER(_amount));
- persistMgr->transfer(TMEMBER(_amountOffsetX));
- persistMgr->transfer(TMEMBER(_amountOffsetY));
- persistMgr->transfer(TMEMBER_INT(_amountAlign));
- persistMgr->transfer(TMEMBER(_amountString));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdItem::getExtendedFlag(const char *flagName) {
- if (!flagName) {
- return false;
- } else if (strcmp(flagName, "usable") == 0) {
- return true;
- } else {
- return AdObject::getExtendedFlag(flagName);
- }
-}
-
-} // 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/ad/ad_item.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdItem, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdItem::AdItem(BaseGame *inGame) : AdTalkHolder(inGame) {
+ _spriteHover = NULL;
+ _cursorNormal = _cursorHover = NULL;
+
+ _cursorCombined = true;
+ _inInventory = false;
+
+ _displayAmount = false;
+ _amount = 0;
+ _amountOffsetX = 0;
+ _amountOffsetY = 0;
+ _amountAlign = TAL_RIGHT;
+ _amountString = NULL;
+
+ _state = STATE_READY;
+
+ _movable = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdItem::~AdItem() {
+ delete _spriteHover;
+ delete _cursorNormal;
+ delete _cursorHover;
+ _spriteHover = NULL;
+ _cursorNormal = NULL;
+ _cursorHover = NULL;
+
+ delete[] _amountString;
+ _amountString = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdItem::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing ITEM file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(ITEM)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(CURSOR_HOVER)
+TOKEN_DEF(CURSOR_COMBINED)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(NAME)
+TOKEN_DEF(IMAGE_HOVER)
+TOKEN_DEF(IMAGE)
+TOKEN_DEF(EVENTS)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(FONT)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(TALK_SPECIAL)
+TOKEN_DEF(TALK)
+TOKEN_DEF(SPRITE_HOVER)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(DISPLAY_AMOUNT)
+TOKEN_DEF(AMOUNT_OFFSET_X)
+TOKEN_DEF(AMOUNT_OFFSET_Y)
+TOKEN_DEF(AMOUNT_ALIGN)
+TOKEN_DEF(AMOUNT_STRING)
+TOKEN_DEF(AMOUNT)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ITEM)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(CURSOR_HOVER)
+ TOKEN_TABLE(CURSOR_COMBINED)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(IMAGE_HOVER)
+ TOKEN_TABLE(IMAGE)
+ TOKEN_TABLE(EVENTS)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(TALK_SPECIAL)
+ TOKEN_TABLE(TALK)
+ TOKEN_TABLE(SPRITE_HOVER)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(DISPLAY_AMOUNT)
+ TOKEN_TABLE(AMOUNT_OFFSET_X)
+ TOKEN_TABLE(AMOUNT_OFFSET_Y)
+ TOKEN_TABLE(AMOUNT_ALIGN)
+ TOKEN_TABLE(AMOUNT_STRING)
+ TOKEN_TABLE(AMOUNT)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd = 2;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ITEM) {
+ _gameRef->LOG(0, "'ITEM' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ int ar = 0, ag = 0, ab = 0, alpha = 255;
+ while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_FONT:
+ setFont((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_IMAGE:
+ case TOKEN_SPRITE:
+ delete _sprite;
+ _sprite = new BaseSprite(_gameRef, this);
+ if (!_sprite || DID_FAIL(_sprite->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ delete _sprite;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_IMAGE_HOVER:
+ case TOKEN_SPRITE_HOVER:
+ delete _spriteHover;
+ _spriteHover = new BaseSprite(_gameRef, this);
+ if (!_spriteHover || DID_FAIL(_spriteHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ delete _spriteHover;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_AMOUNT:
+ parser.scanStr((char *)params, "%d", &_amount);
+ break;
+
+ case TOKEN_DISPLAY_AMOUNT:
+ parser.scanStr((char *)params, "%b", &_displayAmount);
+ break;
+
+ case TOKEN_AMOUNT_OFFSET_X:
+ parser.scanStr((char *)params, "%d", &_amountOffsetX);
+ break;
+
+ case TOKEN_AMOUNT_OFFSET_Y:
+ parser.scanStr((char *)params, "%d", &_amountOffsetY);
+ break;
+
+ case TOKEN_AMOUNT_ALIGN:
+ if (scumm_stricmp((char *)params, "left") == 0) {
+ _amountAlign = TAL_LEFT;
+ } else if (scumm_stricmp((char *)params, "right") == 0) {
+ _amountAlign = TAL_RIGHT;
+ } else {
+ _amountAlign = TAL_CENTER;
+ }
+ break;
+
+ case TOKEN_AMOUNT_STRING:
+ BaseUtils::setString(&_amountString, (char *)params);
+ break;
+
+ case TOKEN_TALK: {
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSprites.add(spr);
+ }
+ }
+ break;
+
+ case TOKEN_TALK_SPECIAL: {
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _talkSpritesEx.add(spr);
+ }
+ }
+ break;
+
+ case TOKEN_CURSOR:
+ delete _cursorNormal;
+ _cursorNormal = new BaseSprite(_gameRef);
+ if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ delete _cursorNormal;
+ _cursorNormal = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_CURSOR_HOVER:
+ delete _cursorHover;
+ _cursorHover = new BaseSprite(_gameRef);
+ if (!_cursorHover || DID_FAIL(_cursorHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ delete _cursorHover;
+ _cursorHover = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_CURSOR_COMBINED:
+ parser.scanStr((char *)params, "%b", &_cursorCombined);
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.scanStr((char *)params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ITEM definition");
+ return STATUS_FAILED;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading ITEM definition");
+ return STATUS_FAILED;
+ }
+
+ if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
+ ar = ag = ab = 255;
+ }
+ _alphaColor = BYTETORGBA(ar, ag, ab, alpha);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::update() {
+ _currentSprite = NULL;
+
+ if (_state == STATE_READY && _animSprite) {
+ delete _animSprite;
+ _animSprite = NULL;
+ }
+
+ // finished playing animation?
+ if (_state == STATE_PLAYING_ANIM && _animSprite != NULL && _animSprite->_finished) {
+ _state = STATE_READY;
+ _currentSprite = _animSprite;
+ }
+
+ if (_sentence && _state != STATE_TALKING) {
+ _sentence->finish();
+ }
+
+ // default: stand animation
+ if (!_currentSprite) {
+ _currentSprite = _sprite;
+ }
+
+ switch (_state) {
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_PLAYING_ANIM:
+ _currentSprite = _animSprite;
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_READY:
+ if (!_animSprite) {
+ if (_gameRef->_activeObject == this && _spriteHover) {
+ _currentSprite = _spriteHover;
+ } else {
+ _currentSprite = _sprite;
+ }
+ }
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ case STATE_TALKING: {
+ _sentence->update();
+ if (_sentence->_currentSprite) {
+ _tempSprite2 = _sentence->_currentSprite;
+ }
+
+ bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->_timer - _sentence->_startTime);
+ if (_tempSprite2 == NULL || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
+ if (timeIsUp) {
+ _sentence->finish();
+ _tempSprite2 = NULL;
+ _state = STATE_READY;
+ } else {
+ _tempSprite2 = getTalkStance(_sentence->getNextStance());
+ if (_tempSprite2) {
+ _tempSprite2->reset();
+ _currentSprite = _tempSprite2;
+ }
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ } else {
+ _currentSprite = _tempSprite2;
+ ((AdGame *)_gameRef)->addSentence(_sentence);
+ }
+ }
+ default:
+ break;
+ }
+ _ready = (_state == STATE_READY);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::display(int x, int y) {
+ int width = 0;
+ if (_currentSprite) {
+ Rect32 rc;
+ _currentSprite->getBoundingRect(&rc, 0, 0);
+ width = rc.width();
+ }
+
+ _posX = x + width / 2;
+ _posY = y;
+
+ bool ret;
+ if (_currentSprite) {
+ ret = _currentSprite->draw(x, y, this, 100, 100, _alphaColor);
+ } else {
+ ret = STATUS_OK;
+ }
+
+ if (_displayAmount) {
+ int amountX = x;
+ int amountY = y + _amountOffsetY;
+
+ if (_amountAlign == TAL_RIGHT) {
+ width -= _amountOffsetX;
+ amountX -= _amountOffsetX;
+ }
+ amountX += _amountOffsetX;
+
+ BaseFont *font = _font ? _font : _gameRef->_systemFont;
+ if (font) {
+ if (_amountString) {
+ font->drawText((byte *)_amountString, amountX, amountY, width, _amountAlign);
+ } else {
+ char str[256];
+ sprintf(str, "%d", _amount);
+ font->drawText((byte *)str, amountX, amountY, width, _amountAlign);
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // SetHoverSprite
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetHoverSprite") == 0) {
+ stack->correctParams(1);
+
+ bool setCurrent = false;
+ if (_currentSprite && _currentSprite == _spriteHover) {
+ setCurrent = true;
+ }
+
+ const char *filename = stack->pop()->getString();
+
+ delete _spriteHover;
+ _spriteHover = NULL;
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ stack->pushBool(false);
+ script->runtimeError("Item.SetHoverSprite failed for file '%s'", filename);
+ } else {
+ _spriteHover = spr;
+ if (setCurrent) {
+ _currentSprite = _spriteHover;
+ }
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetHoverSprite
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetHoverSprite") == 0) {
+ stack->correctParams(0);
+
+ if (!_spriteHover || !_spriteHover->getFilename()) {
+ stack->pushNULL();
+ } else {
+ stack->pushString(_spriteHover->getFilename());
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetHoverSpriteObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetHoverSpriteObject") == 0) {
+ stack->correctParams(0);
+ if (!_spriteHover) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_spriteHover, true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetNormalCursor
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetNormalCursor") == 0) {
+ stack->correctParams(1);
+
+ const char *filename = stack->pop()->getString();
+
+ delete _cursorNormal;
+ _cursorNormal = NULL;
+ BaseSprite *spr = new BaseSprite(_gameRef);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ stack->pushBool(false);
+ script->runtimeError("Item.SetNormalCursor failed for file '%s'", filename);
+ } else {
+ _cursorNormal = spr;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetNormalCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetNormalCursor") == 0) {
+ stack->correctParams(0);
+
+ if (!_cursorNormal || !_cursorNormal->getFilename()) {
+ stack->pushNULL();
+ } else {
+ stack->pushString(_cursorNormal->getFilename());
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetNormalCursorObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetNormalCursorObject") == 0) {
+ stack->correctParams(0);
+
+ if (!_cursorNormal) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_cursorNormal, true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetHoverCursor
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetHoverCursor") == 0) {
+ stack->correctParams(1);
+
+ const char *filename = stack->pop()->getString();
+
+ delete _cursorHover;
+ _cursorHover = NULL;
+ BaseSprite *spr = new BaseSprite(_gameRef);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ stack->pushBool(false);
+ script->runtimeError("Item.SetHoverCursor failed for file '%s'", filename);
+ } else {
+ _cursorHover = spr;
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetHoverCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetHoverCursor") == 0) {
+ stack->correctParams(0);
+
+ if (!_cursorHover || !_cursorHover->getFilename()) {
+ stack->pushNULL();
+ } else {
+ stack->pushString(_cursorHover->getFilename());
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetHoverCursorObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetHoverCursorObject") == 0) {
+ stack->correctParams(0);
+
+ if (!_cursorHover) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_cursorHover, true);
+ }
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdItem::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("item");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Name") == 0) {
+ _scValue->setString(getName());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DisplayAmount
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DisplayAmount") == 0) {
+ _scValue->setBool(_displayAmount);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Amount
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Amount") == 0) {
+ _scValue->setInt(_amount);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountOffsetX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountOffsetX") == 0) {
+ _scValue->setInt(_amountOffsetX);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountOffsetY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountOffsetY") == 0) {
+ _scValue->setInt(_amountOffsetY);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountAlign
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountAlign") == 0) {
+ _scValue->setInt(_amountAlign);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountString") == 0) {
+ if (!_amountString) {
+ _scValue->setNULL();
+ } else {
+ _scValue->setString(_amountString);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CursorCombined
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CursorCombined") == 0) {
+ _scValue->setBool(_cursorCombined);
+ return _scValue;
+ } else {
+ return AdTalkHolder::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Name") == 0) {
+ setName(value->getString());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DisplayAmount
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DisplayAmount") == 0) {
+ _displayAmount = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Amount
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Amount") == 0) {
+ _amount = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountOffsetX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountOffsetX") == 0) {
+ _amountOffsetX = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountOffsetY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountOffsetY") == 0) {
+ _amountOffsetY = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountAlign
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountAlign") == 0) {
+ _amountAlign = (TTextAlign)value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AmountString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AmountString") == 0) {
+ if (value->isNULL()) {
+ delete[] _amountString;
+ _amountString = NULL;
+ } else {
+ BaseUtils::setString(&_amountString, value->getString());
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CursorCombined
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CursorCombined") == 0) {
+ _cursorCombined = value->getBool();
+ return STATUS_OK;
+ } else {
+ return AdTalkHolder::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdItem::scToString() {
+ return "[item]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::persist(BasePersistenceManager *persistMgr) {
+
+ AdTalkHolder::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_cursorCombined));
+ persistMgr->transfer(TMEMBER(_cursorHover));
+ persistMgr->transfer(TMEMBER(_cursorNormal));
+ persistMgr->transfer(TMEMBER(_spriteHover));
+ persistMgr->transfer(TMEMBER(_inInventory));
+ persistMgr->transfer(TMEMBER(_displayAmount));
+ persistMgr->transfer(TMEMBER(_amount));
+ persistMgr->transfer(TMEMBER(_amountOffsetX));
+ persistMgr->transfer(TMEMBER(_amountOffsetY));
+ persistMgr->transfer(TMEMBER_INT(_amountAlign));
+ persistMgr->transfer(TMEMBER(_amountString));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdItem::getExtendedFlag(const char *flagName) {
+ if (!flagName) {
+ return false;
+ } else if (strcmp(flagName, "usable") == 0) {
+ return true;
+ } else {
+ return AdObject::getExtendedFlag(flagName);
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_item.h b/engines/wintermute/ad/ad_item.h
index e06266f8b7..6047c542c1 100644
--- a/engines/wintermute/ad/ad_item.h
+++ b/engines/wintermute/ad/ad_item.h
@@ -1,69 +1,69 @@
-/* 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_ADITEM_H
-#define WINTERMUTE_ADITEM_H
-
-
-#include "engines/wintermute/ad/ad_talk_holder.h"
-
-namespace Wintermute {
-
-class AdItem : public AdTalkHolder {
-public:
- bool update();
- DECLARE_PERSISTENT(AdItem, AdTalkHolder)
- bool display(int x, int y);
- bool getExtendedFlag(const char *flagName);
- bool _inInventory;
- bool _cursorCombined;
- BaseSprite *_spriteHover;
- BaseSprite *_cursorNormal;
- BaseSprite *_cursorHover;
- AdItem(BaseGame *inGame);
- virtual ~AdItem();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-private:
- bool _displayAmount;
- int _amount;
- int _amountOffsetX;
- int _amountOffsetY;
- TTextAlign _amountAlign;
- char *_amountString;
-};
-
-} // 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_ADITEM_H
+#define WINTERMUTE_ADITEM_H
+
+
+#include "engines/wintermute/ad/ad_talk_holder.h"
+
+namespace Wintermute {
+
+class AdItem : public AdTalkHolder {
+public:
+ bool update();
+ DECLARE_PERSISTENT(AdItem, AdTalkHolder)
+ bool display(int x, int y);
+ bool getExtendedFlag(const char *flagName);
+ bool _inInventory;
+ bool _cursorCombined;
+ BaseSprite *_spriteHover;
+ BaseSprite *_cursorNormal;
+ BaseSprite *_cursorHover;
+ AdItem(BaseGame *inGame);
+ virtual ~AdItem();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+private:
+ bool _displayAmount;
+ int _amount;
+ int _amountOffsetX;
+ int _amountOffsetY;
+ TTextAlign _amountAlign;
+ char *_amountString;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_layer.cpp b/engines/wintermute/ad/ad_layer.cpp
index 709ab50b58..46b75b8b21 100644
--- a/engines/wintermute/ad/ad_layer.cpp
+++ b/engines/wintermute/ad/ad_layer.cpp
@@ -1,564 +1,564 @@
-/* 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/ad/ad_layer.h"
-#include "engines/wintermute/ad/ad_scene_node.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.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/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdLayer, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdLayer::AdLayer(BaseGame *inGame) : BaseObject(inGame) {
- _main = false;
- _width = _height = 0;
- _active = true;
- _closeUp = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdLayer::~AdLayer() {
- for (uint32 i = 0; i < _nodes.size(); i++) {
- delete _nodes[i];
- }
- _nodes.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdLayer::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing LAYER file '%s'", filename);
- }
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(LAYER)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(WIDTH)
-TOKEN_DEF(HEIGHT)
-TOKEN_DEF(MAIN)
-TOKEN_DEF(ENTITY)
-TOKEN_DEF(REGION)
-TOKEN_DEF(ACTIVE)
-TOKEN_DEF(EDITOR_SELECTED)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(CLOSE_UP)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(LAYER)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(WIDTH)
- TOKEN_TABLE(HEIGHT)
- TOKEN_TABLE(MAIN)
- TOKEN_TABLE(ENTITY)
- TOKEN_TABLE(REGION)
- TOKEN_TABLE(ACTIVE)
- TOKEN_TABLE(EDITOR_SELECTED)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(CLOSE_UP)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_LAYER) {
- _gameRef->LOG(0, "'LAYER' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_MAIN:
- parser.scanStr((char *)params, "%b", &_main);
- break;
-
- case TOKEN_CLOSE_UP:
- parser.scanStr((char *)params, "%b", &_closeUp);
- break;
-
- case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
- break;
-
- case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
- break;
-
- case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
- break;
-
- case TOKEN_REGION: {
- AdRegion *region = new AdRegion(_gameRef);
- AdSceneNode *node = new AdSceneNode(_gameRef);
- if (!region || !node || DID_FAIL(region->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete region;
- delete node;
- region = NULL;
- node = NULL;
- } else {
- node->setRegion(region);
- _nodes.add(node);
- }
- }
- break;
-
- case TOKEN_ENTITY: {
- AdEntity *entity = new AdEntity(_gameRef);
- AdSceneNode *node = new AdSceneNode(_gameRef);
- if (entity) {
- entity->_zoomable = false; // scene entites default to NOT zoom
- }
- if (!entity || !node || DID_FAIL(entity->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete entity;
- delete node;
- entity = NULL;
- node = NULL;
- } else {
- node->setEntity(entity);
- _nodes.add(node);
- }
- }
- break;
-
- case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in LAYER definition");
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // GetNode
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "GetNode") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- int node = -1;
-
- if (val->_type == VAL_INT) {
- node = val->getInt();
- } else { // get by name
- for (uint32 i = 0; i < _nodes.size(); i++) {
- if ((_nodes[i]->_type == OBJECT_ENTITY && scumm_stricmp(_nodes[i]->_entity->getName(), val->getString()) == 0) ||
- (_nodes[i]->_type == OBJECT_REGION && scumm_stricmp(_nodes[i]->_region->getName(), val->getString()) == 0)) {
- node = i;
- break;
- }
- }
- }
-
- if (node < 0 || node >= (int32)_nodes.size()) {
- stack->pushNULL();
- } else {
- switch (_nodes[node]->_type) {
- case OBJECT_ENTITY:
- stack->pushNative(_nodes[node]->_entity, true);
- break;
- case OBJECT_REGION:
- stack->pushNative(_nodes[node]->_region, true);
- break;
- default:
- stack->pushNULL();
- }
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AddRegion / AddEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddRegion") == 0 || strcmp(name, "AddEntity") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdSceneNode *node = new AdSceneNode(_gameRef);
- if (strcmp(name, "AddRegion") == 0) {
- AdRegion *region = new AdRegion(_gameRef);
- if (!val->isNULL()) {
- region->setName(val->getString());
- }
- node->setRegion(region);
- stack->pushNative(region, true);
- } else {
- AdEntity *entity = new AdEntity(_gameRef);
- if (!val->isNULL()) {
- entity->setName(val->getString());
- }
- node->setEntity(entity);
- stack->pushNative(entity, true);
- }
- _nodes.add(node);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InsertRegion / InsertEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InsertRegion") == 0 || strcmp(name, "InsertEntity") == 0) {
- stack->correctParams(2);
- int index = stack->pop()->getInt();
- ScValue *val = stack->pop();
-
- AdSceneNode *node = new AdSceneNode(_gameRef);
- if (strcmp(name, "InsertRegion") == 0) {
- AdRegion *region = new AdRegion(_gameRef);
- if (!val->isNULL()) {
- region->setName(val->getString());
- }
- node->setRegion(region);
- stack->pushNative(region, true);
- } else {
- AdEntity *entity = new AdEntity(_gameRef);
- if (!val->isNULL()) {
- entity->setName(val->getString());
- }
- node->setEntity(entity);
- stack->pushNative(entity, true);
- }
- if (index < 0) {
- index = 0;
- }
- if (index <= (int32)_nodes.size() - 1) {
- _nodes.insert_at(index, node);
- } else {
- _nodes.add(node);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DeleteNode
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DeleteNode") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdSceneNode *toDelete = NULL;
- if (val->isNative()) {
- BaseScriptable *temp = val->getNative();
- for (uint32 i = 0; i < _nodes.size(); i++) {
- if (_nodes[i]->_region == temp || _nodes[i]->_entity == temp) {
- toDelete = _nodes[i];
- break;
- }
- }
- } else {
- int index = val->getInt();
- if (index >= 0 && index < (int32)_nodes.size()) {
- toDelete = _nodes[index];
- }
- }
- if (toDelete == NULL) {
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- for (uint32 i = 0; i < _nodes.size(); i++) {
- if (_nodes[i] == toDelete) {
- delete _nodes[i];
- _nodes[i] = NULL;
- _nodes.remove_at(i);
- break;
- }
- }
- stack->pushBool(true);
- return STATUS_OK;
- } else {
- return BaseObject::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdLayer::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("layer");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumNodes (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumNodes") == 0) {
- _scValue->setInt(_nodes.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Width
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Width") == 0) {
- _scValue->setInt(_width);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Height
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Height") == 0) {
- _scValue->setInt(_height);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Main (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Main") == 0) {
- _scValue->setBool(_main);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CloseUp
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CloseUp") == 0) {
- _scValue->setBool(_closeUp);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Active") == 0) {
- _scValue->setBool(_active);
- return _scValue;
- } else {
- return BaseObject::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Name") == 0) {
- setName(value->getString());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CloseUp
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CloseUp") == 0) {
- _closeUp = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Width
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Width") == 0) {
- _width = value->getInt();
- if (_width < 0) {
- _width = 0;
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Height
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Height") == 0) {
- _height = value->getInt();
- if (_height < 0) {
- _height = 0;
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Active") == 0) {
- bool b = value->getBool();
- if (b == false && _main) {
- _gameRef->LOG(0, "Warning: cannot deactivate scene's main layer");
- } else {
- _active = b;
- }
- return STATUS_OK;
- } else {
- return BaseObject::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdLayer::scToString() {
- return "[layer]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "LAYER {\n");
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
- buffer->putTextIndent(indent + 2, "MAIN=%s\n", _main ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "WIDTH=%d\n", _width);
- buffer->putTextIndent(indent + 2, "HEIGHT=%d\n", _height);
- buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
- if (_closeUp) {
- buffer->putTextIndent(indent + 2, "CLOSE_UP=%s\n", _closeUp ? "TRUE" : "FALSE");
- }
-
- for (uint32 i = 0; i < _scripts.size(); i++) {
- buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
- }
-
- if (_scProp) {
- _scProp->saveAsText(buffer, indent + 2);
- }
-
- for (uint32 i = 0; i < _nodes.size(); i++) {
- switch (_nodes[i]->_type) {
- case OBJECT_ENTITY:
- _nodes[i]->_entity->saveAsText(buffer, indent + 2);
- break;
- case OBJECT_REGION:
- _nodes[i]->_region->saveAsText(buffer, indent + 2);
- break;
- default:
- error("AdLayer::SaveAsText - Unhandled enum");
- break;
- }
- }
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdLayer::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_closeUp));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_main));
- _nodes.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_width));
-
- 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/base_game.h"
+#include "engines/wintermute/ad/ad_layer.h"
+#include "engines/wintermute/ad/ad_scene_node.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.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/base_file_manager.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdLayer, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdLayer::AdLayer(BaseGame *inGame) : BaseObject(inGame) {
+ _main = false;
+ _width = _height = 0;
+ _active = true;
+ _closeUp = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdLayer::~AdLayer() {
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ delete _nodes[i];
+ }
+ _nodes.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdLayer::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing LAYER file '%s'", filename);
+ }
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(LAYER)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(WIDTH)
+TOKEN_DEF(HEIGHT)
+TOKEN_DEF(MAIN)
+TOKEN_DEF(ENTITY)
+TOKEN_DEF(REGION)
+TOKEN_DEF(ACTIVE)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(CLOSE_UP)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(LAYER)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(WIDTH)
+ TOKEN_TABLE(HEIGHT)
+ TOKEN_TABLE(MAIN)
+ TOKEN_TABLE(ENTITY)
+ TOKEN_TABLE(REGION)
+ TOKEN_TABLE(ACTIVE)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(CLOSE_UP)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_LAYER) {
+ _gameRef->LOG(0, "'LAYER' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_MAIN:
+ parser.scanStr((char *)params, "%b", &_main);
+ break;
+
+ case TOKEN_CLOSE_UP:
+ parser.scanStr((char *)params, "%b", &_closeUp);
+ break;
+
+ case TOKEN_WIDTH:
+ parser.scanStr((char *)params, "%d", &_width);
+ break;
+
+ case TOKEN_HEIGHT:
+ parser.scanStr((char *)params, "%d", &_height);
+ break;
+
+ case TOKEN_ACTIVE:
+ parser.scanStr((char *)params, "%b", &_active);
+ break;
+
+ case TOKEN_REGION: {
+ AdRegion *region = new AdRegion(_gameRef);
+ AdSceneNode *node = new AdSceneNode(_gameRef);
+ if (!region || !node || DID_FAIL(region->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete region;
+ delete node;
+ region = NULL;
+ node = NULL;
+ } else {
+ node->setRegion(region);
+ _nodes.add(node);
+ }
+ }
+ break;
+
+ case TOKEN_ENTITY: {
+ AdEntity *entity = new AdEntity(_gameRef);
+ AdSceneNode *node = new AdSceneNode(_gameRef);
+ if (entity) {
+ entity->_zoomable = false; // scene entites default to NOT zoom
+ }
+ if (!entity || !node || DID_FAIL(entity->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete entity;
+ delete node;
+ entity = NULL;
+ node = NULL;
+ } else {
+ node->setEntity(entity);
+ _nodes.add(node);
+ }
+ }
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.scanStr((char *)params, "%b", &_editorSelected);
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in LAYER definition");
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // GetNode
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "GetNode") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ int node = -1;
+
+ if (val->_type == VAL_INT) {
+ node = val->getInt();
+ } else { // get by name
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ if ((_nodes[i]->_type == OBJECT_ENTITY && scumm_stricmp(_nodes[i]->_entity->getName(), val->getString()) == 0) ||
+ (_nodes[i]->_type == OBJECT_REGION && scumm_stricmp(_nodes[i]->_region->getName(), val->getString()) == 0)) {
+ node = i;
+ break;
+ }
+ }
+ }
+
+ if (node < 0 || node >= (int32)_nodes.size()) {
+ stack->pushNULL();
+ } else {
+ switch (_nodes[node]->_type) {
+ case OBJECT_ENTITY:
+ stack->pushNative(_nodes[node]->_entity, true);
+ break;
+ case OBJECT_REGION:
+ stack->pushNative(_nodes[node]->_region, true);
+ break;
+ default:
+ stack->pushNULL();
+ }
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddRegion / AddEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddRegion") == 0 || strcmp(name, "AddEntity") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdSceneNode *node = new AdSceneNode(_gameRef);
+ if (strcmp(name, "AddRegion") == 0) {
+ AdRegion *region = new AdRegion(_gameRef);
+ if (!val->isNULL()) {
+ region->setName(val->getString());
+ }
+ node->setRegion(region);
+ stack->pushNative(region, true);
+ } else {
+ AdEntity *entity = new AdEntity(_gameRef);
+ if (!val->isNULL()) {
+ entity->setName(val->getString());
+ }
+ node->setEntity(entity);
+ stack->pushNative(entity, true);
+ }
+ _nodes.add(node);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InsertRegion / InsertEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InsertRegion") == 0 || strcmp(name, "InsertEntity") == 0) {
+ stack->correctParams(2);
+ int index = stack->pop()->getInt();
+ ScValue *val = stack->pop();
+
+ AdSceneNode *node = new AdSceneNode(_gameRef);
+ if (strcmp(name, "InsertRegion") == 0) {
+ AdRegion *region = new AdRegion(_gameRef);
+ if (!val->isNULL()) {
+ region->setName(val->getString());
+ }
+ node->setRegion(region);
+ stack->pushNative(region, true);
+ } else {
+ AdEntity *entity = new AdEntity(_gameRef);
+ if (!val->isNULL()) {
+ entity->setName(val->getString());
+ }
+ node->setEntity(entity);
+ stack->pushNative(entity, true);
+ }
+ if (index < 0) {
+ index = 0;
+ }
+ if (index <= (int32)_nodes.size() - 1) {
+ _nodes.insert_at(index, node);
+ } else {
+ _nodes.add(node);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteNode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DeleteNode") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdSceneNode *toDelete = NULL;
+ if (val->isNative()) {
+ BaseScriptable *temp = val->getNative();
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ if (_nodes[i]->_region == temp || _nodes[i]->_entity == temp) {
+ toDelete = _nodes[i];
+ break;
+ }
+ }
+ } else {
+ int index = val->getInt();
+ if (index >= 0 && index < (int32)_nodes.size()) {
+ toDelete = _nodes[index];
+ }
+ }
+ if (toDelete == NULL) {
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ if (_nodes[i] == toDelete) {
+ delete _nodes[i];
+ _nodes[i] = NULL;
+ _nodes.remove_at(i);
+ break;
+ }
+ }
+ stack->pushBool(true);
+ return STATUS_OK;
+ } else {
+ return BaseObject::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdLayer::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("layer");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumNodes (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumNodes") == 0) {
+ _scValue->setInt(_nodes.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Width
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Width") == 0) {
+ _scValue->setInt(_width);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Height
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Height") == 0) {
+ _scValue->setInt(_height);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Main (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Main") == 0) {
+ _scValue->setBool(_main);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CloseUp
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CloseUp") == 0) {
+ _scValue->setBool(_closeUp);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Active") == 0) {
+ _scValue->setBool(_active);
+ return _scValue;
+ } else {
+ return BaseObject::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Name") == 0) {
+ setName(value->getString());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CloseUp
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CloseUp") == 0) {
+ _closeUp = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Width
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Width") == 0) {
+ _width = value->getInt();
+ if (_width < 0) {
+ _width = 0;
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Height
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Height") == 0) {
+ _height = value->getInt();
+ if (_height < 0) {
+ _height = 0;
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Active") == 0) {
+ bool b = value->getBool();
+ if (b == false && _main) {
+ _gameRef->LOG(0, "Warning: cannot deactivate scene's main layer");
+ } else {
+ _active = b;
+ }
+ return STATUS_OK;
+ } else {
+ return BaseObject::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdLayer::scToString() {
+ return "[layer]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "LAYER {\n");
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
+ buffer->putTextIndent(indent + 2, "MAIN=%s\n", _main ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "WIDTH=%d\n", _width);
+ buffer->putTextIndent(indent + 2, "HEIGHT=%d\n", _height);
+ buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
+ if (_closeUp) {
+ buffer->putTextIndent(indent + 2, "CLOSE_UP=%s\n", _closeUp ? "TRUE" : "FALSE");
+ }
+
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
+ }
+
+ if (_scProp) {
+ _scProp->saveAsText(buffer, indent + 2);
+ }
+
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ switch (_nodes[i]->_type) {
+ case OBJECT_ENTITY:
+ _nodes[i]->_entity->saveAsText(buffer, indent + 2);
+ break;
+ case OBJECT_REGION:
+ _nodes[i]->_region->saveAsText(buffer, indent + 2);
+ break;
+ default:
+ error("AdLayer::SaveAsText - Unhandled enum");
+ break;
+ }
+ }
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdLayer::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transfer(TMEMBER(_closeUp));
+ persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transfer(TMEMBER(_main));
+ _nodes.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_width));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_layer.h b/engines/wintermute/ad/ad_layer.h
index b01079c091..bb5f73b13a 100644
--- a/engines/wintermute/ad/ad_layer.h
+++ b/engines/wintermute/ad/ad_layer.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_ADLAYER_H
-#define WINTERMUTE_ADLAYER_H
-
-namespace Wintermute {
-class AdSceneNode;
-class AdLayer : public BaseObject {
-public:
- bool _closeUp;
- DECLARE_PERSISTENT(AdLayer, BaseObject)
- bool _active;
- int _height;
- int _width;
- bool _main;
- AdLayer(BaseGame *inGame);
- virtual ~AdLayer();
- BaseArray<AdSceneNode *> _nodes;
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-};
-
-} // 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_ADLAYER_H
+#define WINTERMUTE_ADLAYER_H
+
+namespace Wintermute {
+class AdSceneNode;
+class AdLayer : public BaseObject {
+public:
+ bool _closeUp;
+ DECLARE_PERSISTENT(AdLayer, BaseObject)
+ bool _active;
+ int _height;
+ int _width;
+ bool _main;
+ AdLayer(BaseGame *inGame);
+ virtual ~AdLayer();
+ BaseArray<AdSceneNode *> _nodes;
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_node_state.cpp b/engines/wintermute/ad/ad_node_state.cpp
index fb2dfed0f5..493156c750 100644
--- a/engines/wintermute/ad/ad_node_state.cpp
+++ b/engines/wintermute/ad/ad_node_state.cpp
@@ -1,196 +1,196 @@
-/* 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/ad/ad_node_state.h"
-#include "engines/wintermute/ad/ad_entity.h"
-#include "engines/wintermute/base/base_string_table.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdNodeState, false)
-
-
-//////////////////////////////////////////////////////////////////////////
-AdNodeState::AdNodeState(BaseGame *inGame) : BaseClass(inGame) {
- _name = NULL;
- _active = false;
- for (int i = 0; i < 7; i++) {
- _caption[i] = NULL;
- }
- _alphaColor = 0;
- _filename = NULL;
- _cursor = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdNodeState::~AdNodeState() {
- delete[] _name;
- delete[] _filename;
- delete[] _cursor;
- _name = NULL;
- _filename = NULL;
- _cursor = NULL;
- for (int i = 0; i < 7; i++) {
- delete[] _caption[i];
- _caption[i] = NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdNodeState::setName(const char *name) {
- delete[] _name;
- _name = NULL;
- BaseUtils::setString(&_name, name);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdNodeState::setFilename(const char *filename) {
- delete[] _filename;
- _filename = NULL;
- BaseUtils::setString(&_filename, filename);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdNodeState::setCursor(const char *filename) {
- delete[] _cursor;
- _cursor = NULL;
- BaseUtils::setString(&_cursor, filename);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdNodeState::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_gameRef));
-
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_name));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_cursor));
- persistMgr->transfer(TMEMBER(_alphaColor));
- for (int i = 0; i < 7; i++) {
- persistMgr->transfer(TMEMBER(_caption[i]));
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdNodeState::setCaption(const char *caption, int caseVal) {
- if (caseVal == 0) {
- caseVal = 1;
- }
- if (caseVal < 1 || caseVal > 7) {
- return;
- }
-
- delete[] _caption[caseVal - 1];
- _caption[caseVal - 1] = new char[strlen(caption) + 1];
- if (_caption[caseVal - 1]) {
- strcpy(_caption[caseVal - 1], caption);
- _gameRef->_stringTable->expand(&_caption[caseVal - 1]);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdNodeState::getCaption(int caseVal) {
- if (caseVal == 0) {
- caseVal = 1;
- }
- if (caseVal < 1 || caseVal > 7 || _caption[caseVal - 1] == NULL) {
- return "";
- } else {
- return _caption[caseVal - 1];
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdNodeState::transferEntity(AdEntity *entity, bool includingSprites, bool saving) {
- if (!entity) {
- return STATUS_FAILED;
- }
-
- // HACK!
- if (this->_gameRef != entity->_gameRef) {
- this->_gameRef = entity->_gameRef;
- }
-
- if (saving) {
- for (int i = 0; i < 7; i++) {
- if (entity->_caption[i]) {
- setCaption(entity->_caption[i], i);
- }
- }
- if (!entity->_region && entity->_sprite && entity->_sprite->getFilename()) {
- if (includingSprites) {
- setFilename(entity->_sprite->getFilename());
- } else {
- setFilename("");
- }
- }
- if (entity->_cursor && entity->_cursor->getFilename()) {
- setCursor(entity->_cursor->getFilename());
- }
- _alphaColor = entity->_alphaColor;
- _active = entity->_active;
- } else {
- for (int i = 0; i < 7; i++) {
- if (_caption[i]) {
- entity->setCaption(_caption[i], i);
- }
- }
- if (_filename && !entity->_region && includingSprites && strcmp(_filename, "") != 0) {
- if (!entity->_sprite || !entity->_sprite->getFilename() || scumm_stricmp(entity->_sprite->getFilename(), _filename) != 0) {
- entity->setSprite(_filename);
- }
- }
- if (_cursor) {
- if (!entity->_cursor || !entity->_cursor->getFilename() || scumm_stricmp(entity->_cursor->getFilename(), _cursor) != 0) {
- entity->setCursor(_cursor);
- }
- }
-
- entity->_active = _active;
- entity->_alphaColor = _alphaColor;
- }
-
- 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/base_game.h"
+#include "engines/wintermute/ad/ad_node_state.h"
+#include "engines/wintermute/ad/ad_entity.h"
+#include "engines/wintermute/base/base_string_table.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdNodeState, false)
+
+
+//////////////////////////////////////////////////////////////////////////
+AdNodeState::AdNodeState(BaseGame *inGame) : BaseClass(inGame) {
+ _name = NULL;
+ _active = false;
+ for (int i = 0; i < 7; i++) {
+ _caption[i] = NULL;
+ }
+ _alphaColor = 0;
+ _filename = NULL;
+ _cursor = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdNodeState::~AdNodeState() {
+ delete[] _name;
+ delete[] _filename;
+ delete[] _cursor;
+ _name = NULL;
+ _filename = NULL;
+ _cursor = NULL;
+ for (int i = 0; i < 7; i++) {
+ delete[] _caption[i];
+ _caption[i] = NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdNodeState::setName(const char *name) {
+ delete[] _name;
+ _name = NULL;
+ BaseUtils::setString(&_name, name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdNodeState::setFilename(const char *filename) {
+ delete[] _filename;
+ _filename = NULL;
+ BaseUtils::setString(&_filename, filename);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdNodeState::setCursor(const char *filename) {
+ delete[] _cursor;
+ _cursor = NULL;
+ BaseUtils::setString(&_cursor, filename);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdNodeState::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transfer(TMEMBER(_name));
+ persistMgr->transfer(TMEMBER(_filename));
+ persistMgr->transfer(TMEMBER(_cursor));
+ persistMgr->transfer(TMEMBER(_alphaColor));
+ for (int i = 0; i < 7; i++) {
+ persistMgr->transfer(TMEMBER(_caption[i]));
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdNodeState::setCaption(const char *caption, int caseVal) {
+ if (caseVal == 0) {
+ caseVal = 1;
+ }
+ if (caseVal < 1 || caseVal > 7) {
+ return;
+ }
+
+ delete[] _caption[caseVal - 1];
+ _caption[caseVal - 1] = new char[strlen(caption) + 1];
+ if (_caption[caseVal - 1]) {
+ strcpy(_caption[caseVal - 1], caption);
+ _gameRef->_stringTable->expand(&_caption[caseVal - 1]);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdNodeState::getCaption(int caseVal) {
+ if (caseVal == 0) {
+ caseVal = 1;
+ }
+ if (caseVal < 1 || caseVal > 7 || _caption[caseVal - 1] == NULL) {
+ return "";
+ } else {
+ return _caption[caseVal - 1];
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdNodeState::transferEntity(AdEntity *entity, bool includingSprites, bool saving) {
+ if (!entity) {
+ return STATUS_FAILED;
+ }
+
+ // HACK!
+ if (this->_gameRef != entity->_gameRef) {
+ this->_gameRef = entity->_gameRef;
+ }
+
+ if (saving) {
+ for (int i = 0; i < 7; i++) {
+ if (entity->_caption[i]) {
+ setCaption(entity->_caption[i], i);
+ }
+ }
+ if (!entity->_region && entity->_sprite && entity->_sprite->getFilename()) {
+ if (includingSprites) {
+ setFilename(entity->_sprite->getFilename());
+ } else {
+ setFilename("");
+ }
+ }
+ if (entity->_cursor && entity->_cursor->getFilename()) {
+ setCursor(entity->_cursor->getFilename());
+ }
+ _alphaColor = entity->_alphaColor;
+ _active = entity->_active;
+ } else {
+ for (int i = 0; i < 7; i++) {
+ if (_caption[i]) {
+ entity->setCaption(_caption[i], i);
+ }
+ }
+ if (_filename && !entity->_region && includingSprites && strcmp(_filename, "") != 0) {
+ if (!entity->_sprite || !entity->_sprite->getFilename() || scumm_stricmp(entity->_sprite->getFilename(), _filename) != 0) {
+ entity->setSprite(_filename);
+ }
+ }
+ if (_cursor) {
+ if (!entity->_cursor || !entity->_cursor->getFilename() || scumm_stricmp(entity->_cursor->getFilename(), _cursor) != 0) {
+ entity->setCursor(_cursor);
+ }
+ }
+
+ entity->_active = _active;
+ entity->_alphaColor = _alphaColor;
+ }
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_node_state.h b/engines/wintermute/ad/ad_node_state.h
index 0008d4b3ee..e2050815a7 100644
--- a/engines/wintermute/ad/ad_node_state.h
+++ b/engines/wintermute/ad/ad_node_state.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_ADNODESTATE_H
-#define WINTERMUTE_ADNODESTATE_H
-
-namespace Wintermute {
-
-class AdEntity;
-
-class AdNodeState : public BaseClass {
-public:
- bool _active;
- bool transferEntity(AdEntity *entity, bool includingSprites, bool saving);
- void setName(const char *name);
- void setFilename(const char *filename);
- void setCursor(const char *filename);
- DECLARE_PERSISTENT(AdNodeState, BaseClass)
- AdNodeState(BaseGame *inGame);
- virtual ~AdNodeState();
- const char *getName() const { return _name; }
-private:
- char *_name;
- char *_caption[7];
- void setCaption(const char *caption, int caseVal);
- const char *getCaption(int caseVal);
- uint32 _alphaColor;
- char *_filename;
- char *_cursor;
-
-};
-
-} // 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_ADNODESTATE_H
+#define WINTERMUTE_ADNODESTATE_H
+
+namespace Wintermute {
+
+class AdEntity;
+
+class AdNodeState : public BaseClass {
+public:
+ bool _active;
+ bool transferEntity(AdEntity *entity, bool includingSprites, bool saving);
+ void setName(const char *name);
+ void setFilename(const char *filename);
+ void setCursor(const char *filename);
+ DECLARE_PERSISTENT(AdNodeState, BaseClass)
+ AdNodeState(BaseGame *inGame);
+ virtual ~AdNodeState();
+ const char *getName() const { return _name; }
+private:
+ char *_name;
+ char *_caption[7];
+ void setCaption(const char *caption, int caseVal);
+ const char *getCaption(int caseVal);
+ uint32 _alphaColor;
+ char *_filename;
+ char *_cursor;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_object.cpp b/engines/wintermute/ad/ad_object.cpp
index a02decebdb..6c77917979 100644
--- a/engines/wintermute/ad/ad_object.cpp
+++ b/engines/wintermute/ad/ad_object.cpp
@@ -1,1299 +1,1299 @@
-/* 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/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_item.h"
-#include "engines/wintermute/ad/ad_object.h"
-#include "engines/wintermute/ad/ad_inventory.h"
-#include "engines/wintermute/ad/ad_layer.h"
-#include "engines/wintermute/ad/ad_scene.h"
-#include "engines/wintermute/ad/ad_scene_node.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/ad/ad_waypoint_group.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_frame.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/base/base_surface_storage.h"
-#include "engines/wintermute/base/base_sub_frame.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_string_table.h"
-#include "engines/wintermute/base/scriptables/script_engine.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/particles/part_emitter.h"
-#include "common/str.h"
-#include "common/util.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdObject, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdObject::AdObject(BaseGame *inGame) : BaseObject(inGame) {
- _type = OBJECT_NONE;
- _state = _nextState = STATE_NONE;
-
- _active = true;
- _drawn = false;
-
- _currentSprite = NULL;
- _animSprite = NULL;
- _tempSprite2 = NULL;
-
- _font = NULL;
-
- _sentence = NULL;
-
- _forcedTalkAnimName = NULL;
- _forcedTalkAnimUsed = false;
-
- _blockRegion = NULL;
- _wptGroup = NULL;
-
- _currentBlockRegion = NULL;
- _currentWptGroup = NULL;
-
- _ignoreItems = false;
- _sceneIndependent = false;
-
- _stickRegion = NULL;
-
- _subtitlesModRelative = true;
- _subtitlesModX = 0;
- _subtitlesModY = 0;
- _subtitlesWidth = 0;
- _subtitlesModXCenter = true;
-
- _inventory = NULL;
-
- for (int i = 0; i < MAX_NUM_REGIONS; i++) {
- _currentRegions[i] = NULL;
- }
-
- _partEmitter = NULL;
- _partFollowParent = false;
- _partOffsetX = _partOffsetY = 0;
-
- _registerAlias = this;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdObject::~AdObject() {
- _currentSprite = NULL; // reference only, don't delete
- delete _animSprite;
- _animSprite = NULL;
- delete _sentence;
- _sentence = NULL;
- delete[] _forcedTalkAnimName;
- _forcedTalkAnimName = NULL;
-
- delete _blockRegion;
- _blockRegion = NULL;
- delete _wptGroup;
- _wptGroup = NULL;
-
- delete _currentBlockRegion;
- _currentBlockRegion = NULL;
- delete _currentWptGroup;
- _currentWptGroup = NULL;
-
- _tempSprite2 = NULL; // reference only
- _stickRegion = NULL;
-
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
-
- if (_inventory) {
- ((AdGame *)_gameRef)->unregisterInventory(_inventory);
- _inventory = NULL;
- }
-
- if (_partEmitter) {
- _gameRef->unregisterObject(_partEmitter);
- }
-
-
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- _gameRef->unregisterObject(_attachmentsPre[i]);
- }
- _attachmentsPre.clear();
-
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- _gameRef->unregisterObject(_attachmentsPost[i]);
- }
- _attachmentsPost.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::playAnim(const char *filename) {
- delete _animSprite;
- _animSprite = NULL;
- _animSprite = new BaseSprite(_gameRef, this);
- if (!_animSprite) {
- _gameRef->LOG(0, "AdObject::PlayAnim: error creating temp sprite (object:\"%s\" sprite:\"%s\")", getName(), filename);
- return STATUS_FAILED;
- }
- bool res = _animSprite->loadFile(filename);
- if (DID_FAIL(res)) {
- _gameRef->LOG(res, "AdObject::PlayAnim: error loading temp sprite (object:\"%s\" sprite:\"%s\")", getName(), filename);
- delete _animSprite;
- _animSprite = NULL;
- return res;
- }
- _state = STATE_PLAYING_ANIM;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::display() {
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::update() {
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
-
- //////////////////////////////////////////////////////////////////////////
- // PlayAnim / PlayAnimAsync
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "PlayAnim") == 0 || strcmp(name, "PlayAnimAsync") == 0) {
- stack->correctParams(1);
- if (DID_FAIL(playAnim(stack->pop()->getString()))) {
- stack->pushBool(false);
- } else {
- if (strcmp(name, "PlayAnimAsync") != 0) {
- script->waitFor(this);
- }
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Reset
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Reset") == 0) {
- stack->correctParams(0);
- reset();
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsTalking
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsTalking") == 0) {
- stack->correctParams(0);
- stack->pushBool(_state == STATE_TALKING);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // StopTalk / StopTalking
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StopTalk") == 0 || strcmp(name, "StopTalking") == 0) {
- stack->correctParams(0);
- if (_sentence) {
- _sentence->finish();
- }
- if (_state == STATE_TALKING) {
- _state = _nextState;
- _nextState = STATE_READY;
- stack->pushBool(true);
- } else {
- stack->pushBool(false);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ForceTalkAnim
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ForceTalkAnim") == 0) {
- stack->correctParams(1);
- const char *animName = stack->pop()->getString();
- delete[] _forcedTalkAnimName;
- _forcedTalkAnimName = new char[strlen(animName) + 1];
- strcpy(_forcedTalkAnimName, animName);
- _forcedTalkAnimUsed = false;
- stack->pushBool(true);
- return STATUS_OK;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // Talk / TalkAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Talk") == 0 || strcmp(name, "TalkAsync") == 0) {
- stack->correctParams(5);
-
- const char *text = stack->pop()->getString();
- ScValue *soundVal = stack->pop();
- int duration = stack->pop()->getInt();
- ScValue *valStances = stack->pop();
-
- const char *stances = valStances->isNULL() ? NULL : valStances->getString();
-
- int align = 0;
- ScValue *val = stack->pop();
- if (val->isNULL()) {
- align = TAL_CENTER;
- } else {
- align = val->getInt();
- }
-
- align = MIN(MAX(0, align), NUM_TEXT_ALIGN - 1);
-
- const char *sound = soundVal->isNULL() ? NULL : soundVal->getString();
-
- talk(text, sound, duration, stances, (TTextAlign)align);
- if (strcmp(name, "TalkAsync") != 0) {
- script->waitForExclusive(this);
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // StickToRegion
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "StickToRegion") == 0) {
- stack->correctParams(1);
-
- AdLayer *main = ((AdGame *)_gameRef)->_scene->_mainLayer;
- bool regFound = false;
-
- uint32 i;
- ScValue *val = stack->pop();
- if (val->isNULL() || !main) {
- _stickRegion = NULL;
- regFound = true;
- } else if (val->isString()) {
- const char *regionName = val->getString();
- for (i = 0; i < main->_nodes.size(); i++) {
- if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region->getName() && scumm_stricmp(main->_nodes[i]->_region->getName(), regionName) == 0) {
- _stickRegion = main->_nodes[i]->_region;
- regFound = true;
- break;
- }
- }
- } else if (val->isNative()) {
- BaseScriptable *obj = val->getNative();
-
- for (i = 0; i < main->_nodes.size(); i++) {
- if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region == obj) {
- _stickRegion = main->_nodes[i]->_region;
- regFound = true;
- break;
- }
- }
-
- }
-
- if (!regFound) {
- _stickRegion = NULL;
- }
- stack->pushBool(regFound);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetFont
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetFont") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- if (val->isNULL()) {
- setFont(NULL);
- } else {
- setFont(val->getString());
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetFont
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetFont") == 0) {
- stack->correctParams(0);
- if (_font && _font->getFilename()) {
- stack->pushString(_font->getFilename());
- } else {
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // TakeItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "TakeItem") == 0) {
- stack->correctParams(2);
-
- if (!_inventory) {
- _inventory = new AdInventory(_gameRef);
- ((AdGame *)_gameRef)->registerInventory(_inventory);
- }
-
- ScValue *val = stack->pop();
- if (!val->isNULL()) {
- const char *itemName = val->getString();
- val = stack->pop();
- const char *insertAfter = val->isNULL() ? NULL : val->getString();
- if (DID_FAIL(_inventory->insertItem(itemName, insertAfter))) {
- script->runtimeError("Cannot add item '%s' to inventory", itemName);
- } else {
- // hide associated entities
- ((AdGame *)_gameRef)->_scene->handleItemAssociations(itemName, false);
- }
-
- } else {
- script->runtimeError("TakeItem: item name expected");
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DropItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DropItem") == 0) {
- stack->correctParams(1);
-
- if (!_inventory) {
- _inventory = new AdInventory(_gameRef);
- ((AdGame *)_gameRef)->registerInventory(_inventory);
- }
-
- ScValue *val = stack->pop();
- if (!val->isNULL()) {
- if (DID_FAIL(_inventory->removeItem(val->getString()))) {
- script->runtimeError("Cannot remove item '%s' from inventory", val->getString());
- } else {
- // show associated entities
- ((AdGame *)_gameRef)->_scene->handleItemAssociations(val->getString(), true);
- }
- } else {
- script->runtimeError("DropItem: item name expected");
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetItem") == 0) {
- stack->correctParams(1);
-
- if (!_inventory) {
- _inventory = new AdInventory(_gameRef);
- ((AdGame *)_gameRef)->registerInventory(_inventory);
- }
-
- ScValue *val = stack->pop();
- if (val->_type == VAL_STRING) {
- AdItem *item = ((AdGame *)_gameRef)->getItemByName(val->getString());
- if (item) {
- stack->pushNative(item, true);
- } else {
- stack->pushNULL();
- }
- } else if (val->isNULL() || val->getInt() < 0 || val->getInt() >= (int32)_inventory->_takenItems.size()) {
- stack->pushNULL();
- } else {
- stack->pushNative(_inventory->_takenItems[val->getInt()], true);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // HasItem
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "HasItem") == 0) {
- stack->correctParams(1);
-
- if (!_inventory) {
- _inventory = new AdInventory(_gameRef);
- ((AdGame *)_gameRef)->registerInventory(_inventory);
- }
-
- ScValue *val = stack->pop();
- if (!val->isNULL()) {
- for (uint32 i = 0; i < _inventory->_takenItems.size(); i++) {
- if (val->getNative() == _inventory->_takenItems[i]) {
- stack->pushBool(true);
- return STATUS_OK;
- } else if (scumm_stricmp(val->getString(), _inventory->_takenItems[i]->getName()) == 0) {
- stack->pushBool(true);
- return STATUS_OK;
- }
- }
- } else {
- script->runtimeError("HasItem: item name expected");
- }
-
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CreateParticleEmitter
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CreateParticleEmitter") == 0) {
- stack->correctParams(3);
- bool followParent = stack->pop()->getBool();
- int offsetX = stack->pop()->getInt();
- int offsetY = stack->pop()->getInt();
-
- PartEmitter *emitter = createParticleEmitter(followParent, offsetX, offsetY);
- if (emitter) {
- stack->pushNative(_partEmitter, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DeleteParticleEmitter
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DeleteParticleEmitter") == 0) {
- stack->correctParams(0);
- if (_partEmitter) {
- _gameRef->unregisterObject(_partEmitter);
- _partEmitter = NULL;
- }
- stack->pushNULL();
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AddAttachment
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddAttachment") == 0) {
- stack->correctParams(4);
- const char *filename = stack->pop()->getString();
- bool preDisplay = stack->pop()->getBool(true);
- int offsetX = stack->pop()->getInt();
- int offsetY = stack->pop()->getInt();
-
- bool res;
- AdEntity *ent = new AdEntity(_gameRef);
- if (DID_FAIL(res = ent->loadFile(filename))) {
- delete ent;
- ent = NULL;
- script->runtimeError("AddAttachment() failed loading entity '%s'", filename);
- stack->pushBool(false);
- } else {
- _gameRef->registerObject(ent);
-
- ent->_posX = offsetX;
- ent->_posY = offsetY;
- ent->_active = true;
-
- if (preDisplay) {
- _attachmentsPre.add(ent);
- } else {
- _attachmentsPost.add(ent);
- }
-
- stack->pushBool(true);
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // RemoveAttachment
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "RemoveAttachment") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- bool found = false;
- if (val->isNative()) {
- BaseScriptable *obj = val->getNative();
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- if (_attachmentsPre[i] == obj) {
- found = true;
- _gameRef->unregisterObject(_attachmentsPre[i]);
- _attachmentsPre.remove_at(i);
- i--;
- }
- }
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- if (_attachmentsPost[i] == obj) {
- found = true;
- _gameRef->unregisterObject(_attachmentsPost[i]);
- _attachmentsPost.remove_at(i);
- i--;
- }
- }
- } else {
- const char *attachmentName = val->getString();
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
- found = true;
- _gameRef->unregisterObject(_attachmentsPre[i]);
- _attachmentsPre.remove_at(i);
- i--;
- }
- }
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
- found = true;
- _gameRef->unregisterObject(_attachmentsPost[i]);
- _attachmentsPost.remove_at(i);
- i--;
- }
- }
- }
- stack->pushBool(found);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetAttachment
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetAttachment") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdObject *ret = NULL;
- if (val->isInt()) {
- int index = val->getInt();
- int currIndex = 0;
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- if (currIndex == index) {
- ret = _attachmentsPre[i];
- }
- currIndex++;
- }
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- if (currIndex == index) {
- ret = _attachmentsPost[i];
- }
- currIndex++;
- }
- } else {
- const char *attachmentName = val->getString();
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
- ret = _attachmentsPre[i];
- break;
- }
- }
- if (!ret) {
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
- ret = _attachmentsPre[i];
- break;
- }
- }
- }
- }
-
- if (ret != NULL) {
- stack->pushNative(ret, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- } else {
- return BaseObject::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdObject::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("object");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Active") == 0) {
- _scValue->setBool(_active);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IgnoreItems
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IgnoreItems") == 0) {
- _scValue->setBool(_ignoreItems);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SceneIndependent
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SceneIndependent") == 0) {
- _scValue->setBool(_sceneIndependent);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesWidth
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesWidth") == 0) {
- _scValue->setInt(_subtitlesWidth);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosRelative
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosRelative") == 0) {
- _scValue->setBool(_subtitlesModRelative);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosX") == 0) {
- _scValue->setInt(_subtitlesModX);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosY") == 0) {
- _scValue->setInt(_subtitlesModY);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosXCenter
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosXCenter") == 0) {
- _scValue->setBool(_subtitlesModXCenter);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumItems (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumItems") == 0) {
- _scValue->setInt(getInventory()->_takenItems.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ParticleEmitter (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ParticleEmitter") == 0) {
- if (_partEmitter) {
- _scValue->setNative(_partEmitter, true);
- } else {
- _scValue->setNULL();
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumAttachments (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumAttachments") == 0) {
- _scValue->setInt(_attachmentsPre.size() + _attachmentsPost.size());
- return _scValue;
- } else {
- return BaseObject::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::scSetProperty(const char *name, ScValue *value) {
-
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Active") == 0) {
- _active = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IgnoreItems
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IgnoreItems") == 0) {
- _ignoreItems = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SceneIndependent
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SceneIndependent") == 0) {
- _sceneIndependent = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesWidth
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesWidth") == 0) {
- _subtitlesWidth = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosRelative
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosRelative") == 0) {
- _subtitlesModRelative = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosX") == 0) {
- _subtitlesModX = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosY") == 0) {
- _subtitlesModY = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SubtitlesPosXCenter
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SubtitlesPosXCenter") == 0) {
- _subtitlesModXCenter = value->getBool();
- return STATUS_OK;
- } else {
- return BaseObject::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdObject::scToString() {
- return "[ad object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::setFont(const char *filename) {
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
- if (filename) {
- _font = _gameRef->_fontStorage->addFont(filename);
- return _font == NULL ? STATUS_FAILED : STATUS_OK;
- } else {
- _font = NULL;
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdObject::getHeight() {
- if (!_currentSprite) {
- return 0;
- } else {
- BaseFrame *frame = _currentSprite->_frames[_currentSprite->_currentFrame];
- int ret = 0;
- for (uint32 i = 0; i < frame->_subframes.size(); i++) {
- ret = MAX(ret, frame->_subframes[i]->_hotspotY);
- }
-
- if (_zoomable) {
- float zoom = ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY);
- ret = (int)(ret * zoom / 100);
- }
- return ret;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdObject::talk(const char *text, const char *sound, uint32 duration, const char *stances, TTextAlign Align) {
- if (!_sentence) {
- _sentence = new AdSentence(_gameRef);
- }
- if (!_sentence) {
- return;
- }
-
- if (_forcedTalkAnimName && _forcedTalkAnimUsed) {
- delete[] _forcedTalkAnimName;
- _forcedTalkAnimName = NULL;
- _forcedTalkAnimUsed = false;
- }
-
- delete(_sentence->_sound);
- _sentence->_sound = NULL;
-
- _sentence->setText(text);
- _gameRef->_stringTable->expand(&_sentence->_text);
- _sentence->setStances(stances);
- _sentence->_duration = duration;
- _sentence->_align = Align;
- _sentence->_startTime = _gameRef->_timer;
- _sentence->_currentStance = -1;
- _sentence->_font = _font == NULL ? _gameRef->_systemFont : _font;
- _sentence->_freezable = _freezable;
-
- // try to locate speech file automatically
- bool deleteSound = false;
- if (!sound) {
- char *key = _gameRef->_stringTable->getKey(text);
- if (key) {
- sound = ((AdGame *)_gameRef)->findSpeechFile(key);
- delete[] key;
-
- if (sound) {
- deleteSound = true;
- }
- }
- }
-
- // load sound and set duration appropriately
- if (sound) {
- BaseSound *snd = new BaseSound(_gameRef);
- if (snd && DID_SUCCEED(snd->setSound(sound, Audio::Mixer::kSpeechSoundType, true))) {
- _sentence->setSound(snd);
- if (_sentence->_duration <= 0) {
- uint32 length = snd->getLength();
- if (length != 0) {
- _sentence->_duration = length;
- }
- }
- } else {
- delete snd;
- }
- }
-
- // set duration by text length
- if (_sentence->_duration <= 0) {// TODO: Avoid longs.
- _sentence->_duration = MAX((size_t)1000, _gameRef->_subtitlesSpeed * strlen(_sentence->_text));
- }
-
-
- int x, y, width, height;
-
- x = _posX;
- y = _posY;
-
- if (!_sceneIndependent && _subtitlesModRelative) {
- x -= ((AdGame *)_gameRef)->_scene->getOffsetLeft();
- y -= ((AdGame *)_gameRef)->_scene->getOffsetTop();
- }
-
-
- if (_subtitlesWidth > 0) {
- width = _subtitlesWidth;
- } else {
- if ((x < _gameRef->_renderer->_width / 4 || x > _gameRef->_renderer->_width * 0.75) && !_gameRef->_touchInterface) {
- width = MAX(_gameRef->_renderer->_width / 4, MIN(x * 2, (_gameRef->_renderer->_width - x) * 2));
- } else {
- width = _gameRef->_renderer->_width / 2;
- }
- }
-
- height = _sentence->_font->getTextHeight((byte *)_sentence->_text, width);
-
- y = y - height - getHeight() - 5;
- if (_subtitlesModRelative) {
- x += _subtitlesModX;
- y += _subtitlesModY;
- } else {
- x = _subtitlesModX;
- y = _subtitlesModY;
- }
- if (_subtitlesModXCenter) {
- x = x - width / 2;
- }
-
-
- x = MIN(MAX(0, x), _gameRef->_renderer->_width - width);
- y = MIN(MAX(0, y), _gameRef->_renderer->_height - height);
-
- _sentence->_width = width;
-
-
- _sentence->_pos.x = x;
- _sentence->_pos.y = y;
-
-
- if (_subtitlesModRelative) {
- _sentence->_pos.x += ((AdGame *)_gameRef)->_scene->getOffsetLeft();
- _sentence->_pos.y += ((AdGame *)_gameRef)->_scene->getOffsetTop();
- }
-
- _sentence->_fixedPos = !_subtitlesModRelative;
-
-
- _sentence->setupTalkFile(sound);
-
- _state = STATE_TALKING;
-
- if (deleteSound) {
- delete[] sound;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::reset() {
- if (_state == STATE_PLAYING_ANIM && _animSprite != NULL) {
- delete _animSprite;
- _animSprite = NULL;
- } else if (_state == STATE_TALKING && _sentence) {
- _sentence->finish();
- }
-
- _state = _nextState = STATE_READY;
-
- _gameRef->_scEngine->resetObject(this);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::persist(BasePersistenceManager *persistMgr) {
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_blockRegion));
- persistMgr->transfer(TMEMBER(_currentBlockRegion));
- persistMgr->transfer(TMEMBER(_currentWptGroup));
- persistMgr->transfer(TMEMBER(_currentSprite));
- persistMgr->transfer(TMEMBER(_drawn));
- persistMgr->transfer(TMEMBER(_font));
- persistMgr->transfer(TMEMBER(_ignoreItems));
- persistMgr->transfer(TMEMBER_INT(_nextState));
- persistMgr->transfer(TMEMBER(_sentence));
- persistMgr->transfer(TMEMBER_INT(_state));
- persistMgr->transfer(TMEMBER(_animSprite));
- persistMgr->transfer(TMEMBER(_sceneIndependent));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimName));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimUsed));
- persistMgr->transfer(TMEMBER(_tempSprite2));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_wptGroup));
- persistMgr->transfer(TMEMBER(_stickRegion));
- persistMgr->transfer(TMEMBER(_subtitlesModRelative));
- persistMgr->transfer(TMEMBER(_subtitlesModX));
- persistMgr->transfer(TMEMBER(_subtitlesModY));
- persistMgr->transfer(TMEMBER(_subtitlesModXCenter));
- persistMgr->transfer(TMEMBER(_subtitlesWidth));
- persistMgr->transfer(TMEMBER(_inventory));
- persistMgr->transfer(TMEMBER(_partEmitter));
-
- for (int i = 0; i < MAX_NUM_REGIONS; i++) {
- persistMgr->transfer(TMEMBER(_currentRegions[i]));
- }
-
- _attachmentsPre.persist(persistMgr);
- _attachmentsPost.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_registerAlias));
-
- persistMgr->transfer(TMEMBER(_partFollowParent));
- persistMgr->transfer(TMEMBER(_partOffsetX));
- persistMgr->transfer(TMEMBER(_partOffsetY));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::updateSounds() {
- if (_sentence && _sentence->_sound) {
- updateOneSound(_sentence->_sound);
- }
-
- return BaseObject::updateSounds();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::resetSoundPan() {
- if (_sentence && _sentence->_sound) {
- _sentence->_sound->setPan(0.0f);
- }
- return BaseObject::resetSoundPan();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::getExtendedFlag(const char *flagName) {
- if (!flagName) {
- return false;
- } else if (strcmp(flagName, "usable") == 0) {
- return true;
- } else {
- return BaseObject::getExtendedFlag(flagName);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- if (_blockRegion) {
- _blockRegion->saveAsText(buffer, indent + 2, "BLOCKED_REGION");
- }
- if (_wptGroup) {
- _wptGroup->saveAsText(buffer, indent + 2);
- }
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::updateBlockRegion() {
- AdGame *adGame = (AdGame *)_gameRef;
- if (adGame->_scene) {
- if (_blockRegion && _currentBlockRegion) {
- _currentBlockRegion->mimic(_blockRegion, _zoomable ? adGame->_scene->getScaleAt(_posY) : 100.0f, _posX, _posY);
- }
-
- if (_wptGroup && _currentWptGroup) {
- _currentWptGroup->mimic(_wptGroup, _zoomable ? adGame->_scene->getScaleAt(_posY) : 100.0f, _posX, _posY);
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-AdInventory *AdObject::getInventory() {
- if (!_inventory) {
- _inventory = new AdInventory(_gameRef);
- ((AdGame *)_gameRef)->registerInventory(_inventory);
- }
- return _inventory;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::afterMove() {
- AdRegion *newRegions[MAX_NUM_REGIONS];
-
- ((AdGame *)_gameRef)->_scene->getRegionsAt(_posX, _posY, newRegions, MAX_NUM_REGIONS);
- for (int i = 0; i < MAX_NUM_REGIONS; i++) {
- if (!newRegions[i]) {
- break;
- }
- bool regFound = false;
- for (int j = 0; j < MAX_NUM_REGIONS; j++) {
- if (_currentRegions[j] == newRegions[i]) {
- _currentRegions[j] = NULL;
- regFound = true;
- break;
- }
- }
- if (!regFound) {
- newRegions[i]->applyEvent("ActorEntry");
- }
- }
-
- for (int i = 0; i < MAX_NUM_REGIONS; i++) {
- if (_currentRegions[i] && _gameRef->validObject(_currentRegions[i])) {
- _currentRegions[i]->applyEvent("ActorLeave");
- }
- _currentRegions[i] = newRegions[i];
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::invalidateCurrRegions() {
- for (int i = 0; i < MAX_NUM_REGIONS; i++) {
- _currentRegions[i] = NULL;
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::getScale(float *scaleX, float *scaleY) {
- if (_zoomable) {
- if (_scaleX >= 0 || _scaleY >= 0) {
- *scaleX = _scaleX < 0 ? 100 : _scaleX;
- *scaleY = _scaleY < 0 ? 100 : _scaleY;
- } else if (_scale >= 0) {
- *scaleX = *scaleY = _scale;
- } else {
- *scaleX = *scaleY = ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) + _relativeScale;
- }
- } else {
- *scaleX = *scaleY = 100;
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::updateSpriteAttachments() {
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- _attachmentsPre[i]->update();
- }
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- _attachmentsPost[i]->update();
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::displaySpriteAttachments(bool preDisplay) {
- if (preDisplay) {
- for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
- displaySpriteAttachment(_attachmentsPre[i]);
- }
- } else {
- for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
- displaySpriteAttachment(_attachmentsPost[i]);
- }
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::displaySpriteAttachment(AdObject *attachment) {
- if (!attachment->_active) {
- return STATUS_OK;
- }
-
- float scaleX, scaleY;
- getScale(&scaleX, &scaleY);
-
- int origX = attachment->_posX;
- int origY = attachment->_posY;
-
- // inherit position from owner
- attachment->_posX = (int)(this->_posX + attachment->_posX * scaleX / 100.0f);
- attachment->_posY = (int)(this->_posY + attachment->_posY * scaleY / 100.0f);
-
- // inherit other props
- attachment->_alphaColor = this->_alphaColor;
- attachment->_blendMode = this->_blendMode;
-
- attachment->_scale = this->_scale;
- attachment->_relativeScale = this->_relativeScale;
- attachment->_scaleX = this->_scaleX;
- attachment->_scaleY = this->_scaleY;
-
- attachment->_rotate = this->_rotate;
- attachment->_relativeRotate = this->_relativeRotate;
- attachment->_rotateValid = this->_rotateValid;
-
- attachment->_registerAlias = this;
- attachment->_registrable = this->_registrable;
-
- bool ret = attachment->display();
-
- attachment->_posX = origX;
- attachment->_posY = origY;
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-PartEmitter *AdObject::createParticleEmitter(bool followParent, int offsetX, int offsetY) {
- _partFollowParent = followParent;
- _partOffsetX = offsetX;
- _partOffsetY = offsetY;
-
- if (!_partEmitter) {
- _partEmitter = new PartEmitter(_gameRef, this);
- if (_partEmitter) {
- _gameRef->registerObject(_partEmitter);
- }
- }
- updatePartEmitter();
- return _partEmitter;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdObject::updatePartEmitter() {
- if (!_partEmitter) {
- return STATUS_FAILED;
- }
-
- if (_partFollowParent) {
- float scaleX, scaleY;
- getScale(&scaleX, &scaleY);
-
- _partEmitter->_posX = (int)(_posX + (scaleX / 100.0f) * _partOffsetX);
- _partEmitter->_posY = (int)(_posY + (scaleY / 100.0f) * _partOffsetY);
- }
- return _partEmitter->update();
-}
-
-} // 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/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_item.h"
+#include "engines/wintermute/ad/ad_object.h"
+#include "engines/wintermute/ad/ad_inventory.h"
+#include "engines/wintermute/ad/ad_layer.h"
+#include "engines/wintermute/ad/ad_scene.h"
+#include "engines/wintermute/ad/ad_scene_node.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/ad/ad_waypoint_group.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_frame.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/base/base_surface_storage.h"
+#include "engines/wintermute/base/base_sub_frame.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_string_table.h"
+#include "engines/wintermute/base/scriptables/script_engine.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/particles/part_emitter.h"
+#include "common/str.h"
+#include "common/util.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdObject, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdObject::AdObject(BaseGame *inGame) : BaseObject(inGame) {
+ _type = OBJECT_NONE;
+ _state = _nextState = STATE_NONE;
+
+ _active = true;
+ _drawn = false;
+
+ _currentSprite = NULL;
+ _animSprite = NULL;
+ _tempSprite2 = NULL;
+
+ _font = NULL;
+
+ _sentence = NULL;
+
+ _forcedTalkAnimName = NULL;
+ _forcedTalkAnimUsed = false;
+
+ _blockRegion = NULL;
+ _wptGroup = NULL;
+
+ _currentBlockRegion = NULL;
+ _currentWptGroup = NULL;
+
+ _ignoreItems = false;
+ _sceneIndependent = false;
+
+ _stickRegion = NULL;
+
+ _subtitlesModRelative = true;
+ _subtitlesModX = 0;
+ _subtitlesModY = 0;
+ _subtitlesWidth = 0;
+ _subtitlesModXCenter = true;
+
+ _inventory = NULL;
+
+ for (int i = 0; i < MAX_NUM_REGIONS; i++) {
+ _currentRegions[i] = NULL;
+ }
+
+ _partEmitter = NULL;
+ _partFollowParent = false;
+ _partOffsetX = _partOffsetY = 0;
+
+ _registerAlias = this;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdObject::~AdObject() {
+ _currentSprite = NULL; // reference only, don't delete
+ delete _animSprite;
+ _animSprite = NULL;
+ delete _sentence;
+ _sentence = NULL;
+ delete[] _forcedTalkAnimName;
+ _forcedTalkAnimName = NULL;
+
+ delete _blockRegion;
+ _blockRegion = NULL;
+ delete _wptGroup;
+ _wptGroup = NULL;
+
+ delete _currentBlockRegion;
+ _currentBlockRegion = NULL;
+ delete _currentWptGroup;
+ _currentWptGroup = NULL;
+
+ _tempSprite2 = NULL; // reference only
+ _stickRegion = NULL;
+
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+
+ if (_inventory) {
+ ((AdGame *)_gameRef)->unregisterInventory(_inventory);
+ _inventory = NULL;
+ }
+
+ if (_partEmitter) {
+ _gameRef->unregisterObject(_partEmitter);
+ }
+
+
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ _gameRef->unregisterObject(_attachmentsPre[i]);
+ }
+ _attachmentsPre.clear();
+
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ _gameRef->unregisterObject(_attachmentsPost[i]);
+ }
+ _attachmentsPost.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::playAnim(const char *filename) {
+ delete _animSprite;
+ _animSprite = NULL;
+ _animSprite = new BaseSprite(_gameRef, this);
+ if (!_animSprite) {
+ _gameRef->LOG(0, "AdObject::PlayAnim: error creating temp sprite (object:\"%s\" sprite:\"%s\")", getName(), filename);
+ return STATUS_FAILED;
+ }
+ bool res = _animSprite->loadFile(filename);
+ if (DID_FAIL(res)) {
+ _gameRef->LOG(res, "AdObject::PlayAnim: error loading temp sprite (object:\"%s\" sprite:\"%s\")", getName(), filename);
+ delete _animSprite;
+ _animSprite = NULL;
+ return res;
+ }
+ _state = STATE_PLAYING_ANIM;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::display() {
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::update() {
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlayAnim / PlayAnimAsync
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "PlayAnim") == 0 || strcmp(name, "PlayAnimAsync") == 0) {
+ stack->correctParams(1);
+ if (DID_FAIL(playAnim(stack->pop()->getString()))) {
+ stack->pushBool(false);
+ } else {
+ if (strcmp(name, "PlayAnimAsync") != 0) {
+ script->waitFor(this);
+ }
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Reset
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Reset") == 0) {
+ stack->correctParams(0);
+ reset();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsTalking
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsTalking") == 0) {
+ stack->correctParams(0);
+ stack->pushBool(_state == STATE_TALKING);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StopTalk / StopTalking
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StopTalk") == 0 || strcmp(name, "StopTalking") == 0) {
+ stack->correctParams(0);
+ if (_sentence) {
+ _sentence->finish();
+ }
+ if (_state == STATE_TALKING) {
+ _state = _nextState;
+ _nextState = STATE_READY;
+ stack->pushBool(true);
+ } else {
+ stack->pushBool(false);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ForceTalkAnim
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ForceTalkAnim") == 0) {
+ stack->correctParams(1);
+ const char *animName = stack->pop()->getString();
+ delete[] _forcedTalkAnimName;
+ _forcedTalkAnimName = new char[strlen(animName) + 1];
+ strcpy(_forcedTalkAnimName, animName);
+ _forcedTalkAnimUsed = false;
+ stack->pushBool(true);
+ return STATUS_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Talk / TalkAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Talk") == 0 || strcmp(name, "TalkAsync") == 0) {
+ stack->correctParams(5);
+
+ const char *text = stack->pop()->getString();
+ ScValue *soundVal = stack->pop();
+ int duration = stack->pop()->getInt();
+ ScValue *valStances = stack->pop();
+
+ const char *stances = valStances->isNULL() ? NULL : valStances->getString();
+
+ int align = 0;
+ ScValue *val = stack->pop();
+ if (val->isNULL()) {
+ align = TAL_CENTER;
+ } else {
+ align = val->getInt();
+ }
+
+ align = MIN(MAX(0, align), NUM_TEXT_ALIGN - 1);
+
+ const char *sound = soundVal->isNULL() ? NULL : soundVal->getString();
+
+ talk(text, sound, duration, stances, (TTextAlign)align);
+ if (strcmp(name, "TalkAsync") != 0) {
+ script->waitForExclusive(this);
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StickToRegion
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "StickToRegion") == 0) {
+ stack->correctParams(1);
+
+ AdLayer *main = ((AdGame *)_gameRef)->_scene->_mainLayer;
+ bool regFound = false;
+
+ uint32 i;
+ ScValue *val = stack->pop();
+ if (val->isNULL() || !main) {
+ _stickRegion = NULL;
+ regFound = true;
+ } else if (val->isString()) {
+ const char *regionName = val->getString();
+ for (i = 0; i < main->_nodes.size(); i++) {
+ if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region->getName() && scumm_stricmp(main->_nodes[i]->_region->getName(), regionName) == 0) {
+ _stickRegion = main->_nodes[i]->_region;
+ regFound = true;
+ break;
+ }
+ }
+ } else if (val->isNative()) {
+ BaseScriptable *obj = val->getNative();
+
+ for (i = 0; i < main->_nodes.size(); i++) {
+ if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region == obj) {
+ _stickRegion = main->_nodes[i]->_region;
+ regFound = true;
+ break;
+ }
+ }
+
+ }
+
+ if (!regFound) {
+ _stickRegion = NULL;
+ }
+ stack->pushBool(regFound);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetFont
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetFont") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ if (val->isNULL()) {
+ setFont(NULL);
+ } else {
+ setFont(val->getString());
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFont
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetFont") == 0) {
+ stack->correctParams(0);
+ if (_font && _font->getFilename()) {
+ stack->pushString(_font->getFilename());
+ } else {
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TakeItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "TakeItem") == 0) {
+ stack->correctParams(2);
+
+ if (!_inventory) {
+ _inventory = new AdInventory(_gameRef);
+ ((AdGame *)_gameRef)->registerInventory(_inventory);
+ }
+
+ ScValue *val = stack->pop();
+ if (!val->isNULL()) {
+ const char *itemName = val->getString();
+ val = stack->pop();
+ const char *insertAfter = val->isNULL() ? NULL : val->getString();
+ if (DID_FAIL(_inventory->insertItem(itemName, insertAfter))) {
+ script->runtimeError("Cannot add item '%s' to inventory", itemName);
+ } else {
+ // hide associated entities
+ ((AdGame *)_gameRef)->_scene->handleItemAssociations(itemName, false);
+ }
+
+ } else {
+ script->runtimeError("TakeItem: item name expected");
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DropItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DropItem") == 0) {
+ stack->correctParams(1);
+
+ if (!_inventory) {
+ _inventory = new AdInventory(_gameRef);
+ ((AdGame *)_gameRef)->registerInventory(_inventory);
+ }
+
+ ScValue *val = stack->pop();
+ if (!val->isNULL()) {
+ if (DID_FAIL(_inventory->removeItem(val->getString()))) {
+ script->runtimeError("Cannot remove item '%s' from inventory", val->getString());
+ } else {
+ // show associated entities
+ ((AdGame *)_gameRef)->_scene->handleItemAssociations(val->getString(), true);
+ }
+ } else {
+ script->runtimeError("DropItem: item name expected");
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetItem") == 0) {
+ stack->correctParams(1);
+
+ if (!_inventory) {
+ _inventory = new AdInventory(_gameRef);
+ ((AdGame *)_gameRef)->registerInventory(_inventory);
+ }
+
+ ScValue *val = stack->pop();
+ if (val->_type == VAL_STRING) {
+ AdItem *item = ((AdGame *)_gameRef)->getItemByName(val->getString());
+ if (item) {
+ stack->pushNative(item, true);
+ } else {
+ stack->pushNULL();
+ }
+ } else if (val->isNULL() || val->getInt() < 0 || val->getInt() >= (int32)_inventory->_takenItems.size()) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_inventory->_takenItems[val->getInt()], true);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HasItem
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "HasItem") == 0) {
+ stack->correctParams(1);
+
+ if (!_inventory) {
+ _inventory = new AdInventory(_gameRef);
+ ((AdGame *)_gameRef)->registerInventory(_inventory);
+ }
+
+ ScValue *val = stack->pop();
+ if (!val->isNULL()) {
+ for (uint32 i = 0; i < _inventory->_takenItems.size(); i++) {
+ if (val->getNative() == _inventory->_takenItems[i]) {
+ stack->pushBool(true);
+ return STATUS_OK;
+ } else if (scumm_stricmp(val->getString(), _inventory->_takenItems[i]->getName()) == 0) {
+ stack->pushBool(true);
+ return STATUS_OK;
+ }
+ }
+ } else {
+ script->runtimeError("HasItem: item name expected");
+ }
+
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateParticleEmitter
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CreateParticleEmitter") == 0) {
+ stack->correctParams(3);
+ bool followParent = stack->pop()->getBool();
+ int offsetX = stack->pop()->getInt();
+ int offsetY = stack->pop()->getInt();
+
+ PartEmitter *emitter = createParticleEmitter(followParent, offsetX, offsetY);
+ if (emitter) {
+ stack->pushNative(_partEmitter, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteParticleEmitter
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DeleteParticleEmitter") == 0) {
+ stack->correctParams(0);
+ if (_partEmitter) {
+ _gameRef->unregisterObject(_partEmitter);
+ _partEmitter = NULL;
+ }
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddAttachment
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddAttachment") == 0) {
+ stack->correctParams(4);
+ const char *filename = stack->pop()->getString();
+ bool preDisplay = stack->pop()->getBool(true);
+ int offsetX = stack->pop()->getInt();
+ int offsetY = stack->pop()->getInt();
+
+ bool res;
+ AdEntity *ent = new AdEntity(_gameRef);
+ if (DID_FAIL(res = ent->loadFile(filename))) {
+ delete ent;
+ ent = NULL;
+ script->runtimeError("AddAttachment() failed loading entity '%s'", filename);
+ stack->pushBool(false);
+ } else {
+ _gameRef->registerObject(ent);
+
+ ent->_posX = offsetX;
+ ent->_posY = offsetY;
+ ent->_active = true;
+
+ if (preDisplay) {
+ _attachmentsPre.add(ent);
+ } else {
+ _attachmentsPost.add(ent);
+ }
+
+ stack->pushBool(true);
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveAttachment
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RemoveAttachment") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ bool found = false;
+ if (val->isNative()) {
+ BaseScriptable *obj = val->getNative();
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ if (_attachmentsPre[i] == obj) {
+ found = true;
+ _gameRef->unregisterObject(_attachmentsPre[i]);
+ _attachmentsPre.remove_at(i);
+ i--;
+ }
+ }
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ if (_attachmentsPost[i] == obj) {
+ found = true;
+ _gameRef->unregisterObject(_attachmentsPost[i]);
+ _attachmentsPost.remove_at(i);
+ i--;
+ }
+ }
+ } else {
+ const char *attachmentName = val->getString();
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
+ found = true;
+ _gameRef->unregisterObject(_attachmentsPre[i]);
+ _attachmentsPre.remove_at(i);
+ i--;
+ }
+ }
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
+ found = true;
+ _gameRef->unregisterObject(_attachmentsPost[i]);
+ _attachmentsPost.remove_at(i);
+ i--;
+ }
+ }
+ }
+ stack->pushBool(found);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetAttachment
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetAttachment") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdObject *ret = NULL;
+ if (val->isInt()) {
+ int index = val->getInt();
+ int currIndex = 0;
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ if (currIndex == index) {
+ ret = _attachmentsPre[i];
+ }
+ currIndex++;
+ }
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ if (currIndex == index) {
+ ret = _attachmentsPost[i];
+ }
+ currIndex++;
+ }
+ } else {
+ const char *attachmentName = val->getString();
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
+ ret = _attachmentsPre[i];
+ break;
+ }
+ }
+ if (!ret) {
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
+ ret = _attachmentsPre[i];
+ break;
+ }
+ }
+ }
+ }
+
+ if (ret != NULL) {
+ stack->pushNative(ret, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ } else {
+ return BaseObject::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdObject::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("object");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Active") == 0) {
+ _scValue->setBool(_active);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IgnoreItems
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IgnoreItems") == 0) {
+ _scValue->setBool(_ignoreItems);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SceneIndependent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SceneIndependent") == 0) {
+ _scValue->setBool(_sceneIndependent);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesWidth
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesWidth") == 0) {
+ _scValue->setInt(_subtitlesWidth);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosRelative
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosRelative") == 0) {
+ _scValue->setBool(_subtitlesModRelative);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosX") == 0) {
+ _scValue->setInt(_subtitlesModX);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosY") == 0) {
+ _scValue->setInt(_subtitlesModY);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosXCenter
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosXCenter") == 0) {
+ _scValue->setBool(_subtitlesModXCenter);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumItems (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumItems") == 0) {
+ _scValue->setInt(getInventory()->_takenItems.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ParticleEmitter (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ParticleEmitter") == 0) {
+ if (_partEmitter) {
+ _scValue->setNative(_partEmitter, true);
+ } else {
+ _scValue->setNULL();
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumAttachments (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumAttachments") == 0) {
+ _scValue->setInt(_attachmentsPre.size() + _attachmentsPost.size());
+ return _scValue;
+ } else {
+ return BaseObject::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::scSetProperty(const char *name, ScValue *value) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Active") == 0) {
+ _active = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IgnoreItems
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IgnoreItems") == 0) {
+ _ignoreItems = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SceneIndependent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SceneIndependent") == 0) {
+ _sceneIndependent = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesWidth
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesWidth") == 0) {
+ _subtitlesWidth = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosRelative
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosRelative") == 0) {
+ _subtitlesModRelative = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosX") == 0) {
+ _subtitlesModX = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosY") == 0) {
+ _subtitlesModY = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesPosXCenter
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SubtitlesPosXCenter") == 0) {
+ _subtitlesModXCenter = value->getBool();
+ return STATUS_OK;
+ } else {
+ return BaseObject::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdObject::scToString() {
+ return "[ad object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::setFont(const char *filename) {
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+ if (filename) {
+ _font = _gameRef->_fontStorage->addFont(filename);
+ return _font == NULL ? STATUS_FAILED : STATUS_OK;
+ } else {
+ _font = NULL;
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdObject::getHeight() {
+ if (!_currentSprite) {
+ return 0;
+ } else {
+ BaseFrame *frame = _currentSprite->_frames[_currentSprite->_currentFrame];
+ int ret = 0;
+ for (uint32 i = 0; i < frame->_subframes.size(); i++) {
+ ret = MAX(ret, frame->_subframes[i]->_hotspotY);
+ }
+
+ if (_zoomable) {
+ float zoom = ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY);
+ ret = (int)(ret * zoom / 100);
+ }
+ return ret;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdObject::talk(const char *text, const char *sound, uint32 duration, const char *stances, TTextAlign Align) {
+ if (!_sentence) {
+ _sentence = new AdSentence(_gameRef);
+ }
+ if (!_sentence) {
+ return;
+ }
+
+ if (_forcedTalkAnimName && _forcedTalkAnimUsed) {
+ delete[] _forcedTalkAnimName;
+ _forcedTalkAnimName = NULL;
+ _forcedTalkAnimUsed = false;
+ }
+
+ delete(_sentence->_sound);
+ _sentence->_sound = NULL;
+
+ _sentence->setText(text);
+ _gameRef->_stringTable->expand(&_sentence->_text);
+ _sentence->setStances(stances);
+ _sentence->_duration = duration;
+ _sentence->_align = Align;
+ _sentence->_startTime = _gameRef->_timer;
+ _sentence->_currentStance = -1;
+ _sentence->_font = _font == NULL ? _gameRef->_systemFont : _font;
+ _sentence->_freezable = _freezable;
+
+ // try to locate speech file automatically
+ bool deleteSound = false;
+ if (!sound) {
+ char *key = _gameRef->_stringTable->getKey(text);
+ if (key) {
+ sound = ((AdGame *)_gameRef)->findSpeechFile(key);
+ delete[] key;
+
+ if (sound) {
+ deleteSound = true;
+ }
+ }
+ }
+
+ // load sound and set duration appropriately
+ if (sound) {
+ BaseSound *snd = new BaseSound(_gameRef);
+ if (snd && DID_SUCCEED(snd->setSound(sound, Audio::Mixer::kSpeechSoundType, true))) {
+ _sentence->setSound(snd);
+ if (_sentence->_duration <= 0) {
+ uint32 length = snd->getLength();
+ if (length != 0) {
+ _sentence->_duration = length;
+ }
+ }
+ } else {
+ delete snd;
+ }
+ }
+
+ // set duration by text length
+ if (_sentence->_duration <= 0) {// TODO: Avoid longs.
+ _sentence->_duration = MAX((size_t)1000, _gameRef->_subtitlesSpeed * strlen(_sentence->_text));
+ }
+
+
+ int x, y, width, height;
+
+ x = _posX;
+ y = _posY;
+
+ if (!_sceneIndependent && _subtitlesModRelative) {
+ x -= ((AdGame *)_gameRef)->_scene->getOffsetLeft();
+ y -= ((AdGame *)_gameRef)->_scene->getOffsetTop();
+ }
+
+
+ if (_subtitlesWidth > 0) {
+ width = _subtitlesWidth;
+ } else {
+ if ((x < _gameRef->_renderer->_width / 4 || x > _gameRef->_renderer->_width * 0.75) && !_gameRef->_touchInterface) {
+ width = MAX(_gameRef->_renderer->_width / 4, MIN(x * 2, (_gameRef->_renderer->_width - x) * 2));
+ } else {
+ width = _gameRef->_renderer->_width / 2;
+ }
+ }
+
+ height = _sentence->_font->getTextHeight((byte *)_sentence->_text, width);
+
+ y = y - height - getHeight() - 5;
+ if (_subtitlesModRelative) {
+ x += _subtitlesModX;
+ y += _subtitlesModY;
+ } else {
+ x = _subtitlesModX;
+ y = _subtitlesModY;
+ }
+ if (_subtitlesModXCenter) {
+ x = x - width / 2;
+ }
+
+
+ x = MIN(MAX(0, x), _gameRef->_renderer->_width - width);
+ y = MIN(MAX(0, y), _gameRef->_renderer->_height - height);
+
+ _sentence->_width = width;
+
+
+ _sentence->_pos.x = x;
+ _sentence->_pos.y = y;
+
+
+ if (_subtitlesModRelative) {
+ _sentence->_pos.x += ((AdGame *)_gameRef)->_scene->getOffsetLeft();
+ _sentence->_pos.y += ((AdGame *)_gameRef)->_scene->getOffsetTop();
+ }
+
+ _sentence->_fixedPos = !_subtitlesModRelative;
+
+
+ _sentence->setupTalkFile(sound);
+
+ _state = STATE_TALKING;
+
+ if (deleteSound) {
+ delete[] sound;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::reset() {
+ if (_state == STATE_PLAYING_ANIM && _animSprite != NULL) {
+ delete _animSprite;
+ _animSprite = NULL;
+ } else if (_state == STATE_TALKING && _sentence) {
+ _sentence->finish();
+ }
+
+ _state = _nextState = STATE_READY;
+
+ _gameRef->_scEngine->resetObject(this);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::persist(BasePersistenceManager *persistMgr) {
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transfer(TMEMBER(_blockRegion));
+ persistMgr->transfer(TMEMBER(_currentBlockRegion));
+ persistMgr->transfer(TMEMBER(_currentWptGroup));
+ persistMgr->transfer(TMEMBER(_currentSprite));
+ persistMgr->transfer(TMEMBER(_drawn));
+ persistMgr->transfer(TMEMBER(_font));
+ persistMgr->transfer(TMEMBER(_ignoreItems));
+ persistMgr->transfer(TMEMBER_INT(_nextState));
+ persistMgr->transfer(TMEMBER(_sentence));
+ persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transfer(TMEMBER(_animSprite));
+ persistMgr->transfer(TMEMBER(_sceneIndependent));
+ persistMgr->transfer(TMEMBER(_forcedTalkAnimName));
+ persistMgr->transfer(TMEMBER(_forcedTalkAnimUsed));
+ persistMgr->transfer(TMEMBER(_tempSprite2));
+ persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transfer(TMEMBER(_wptGroup));
+ persistMgr->transfer(TMEMBER(_stickRegion));
+ persistMgr->transfer(TMEMBER(_subtitlesModRelative));
+ persistMgr->transfer(TMEMBER(_subtitlesModX));
+ persistMgr->transfer(TMEMBER(_subtitlesModY));
+ persistMgr->transfer(TMEMBER(_subtitlesModXCenter));
+ persistMgr->transfer(TMEMBER(_subtitlesWidth));
+ persistMgr->transfer(TMEMBER(_inventory));
+ persistMgr->transfer(TMEMBER(_partEmitter));
+
+ for (int i = 0; i < MAX_NUM_REGIONS; i++) {
+ persistMgr->transfer(TMEMBER(_currentRegions[i]));
+ }
+
+ _attachmentsPre.persist(persistMgr);
+ _attachmentsPost.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_registerAlias));
+
+ persistMgr->transfer(TMEMBER(_partFollowParent));
+ persistMgr->transfer(TMEMBER(_partOffsetX));
+ persistMgr->transfer(TMEMBER(_partOffsetY));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::updateSounds() {
+ if (_sentence && _sentence->_sound) {
+ updateOneSound(_sentence->_sound);
+ }
+
+ return BaseObject::updateSounds();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::resetSoundPan() {
+ if (_sentence && _sentence->_sound) {
+ _sentence->_sound->setPan(0.0f);
+ }
+ return BaseObject::resetSoundPan();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::getExtendedFlag(const char *flagName) {
+ if (!flagName) {
+ return false;
+ } else if (strcmp(flagName, "usable") == 0) {
+ return true;
+ } else {
+ return BaseObject::getExtendedFlag(flagName);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ if (_blockRegion) {
+ _blockRegion->saveAsText(buffer, indent + 2, "BLOCKED_REGION");
+ }
+ if (_wptGroup) {
+ _wptGroup->saveAsText(buffer, indent + 2);
+ }
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::updateBlockRegion() {
+ AdGame *adGame = (AdGame *)_gameRef;
+ if (adGame->_scene) {
+ if (_blockRegion && _currentBlockRegion) {
+ _currentBlockRegion->mimic(_blockRegion, _zoomable ? adGame->_scene->getScaleAt(_posY) : 100.0f, _posX, _posY);
+ }
+
+ if (_wptGroup && _currentWptGroup) {
+ _currentWptGroup->mimic(_wptGroup, _zoomable ? adGame->_scene->getScaleAt(_posY) : 100.0f, _posX, _posY);
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AdInventory *AdObject::getInventory() {
+ if (!_inventory) {
+ _inventory = new AdInventory(_gameRef);
+ ((AdGame *)_gameRef)->registerInventory(_inventory);
+ }
+ return _inventory;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::afterMove() {
+ AdRegion *newRegions[MAX_NUM_REGIONS];
+
+ ((AdGame *)_gameRef)->_scene->getRegionsAt(_posX, _posY, newRegions, MAX_NUM_REGIONS);
+ for (int i = 0; i < MAX_NUM_REGIONS; i++) {
+ if (!newRegions[i]) {
+ break;
+ }
+ bool regFound = false;
+ for (int j = 0; j < MAX_NUM_REGIONS; j++) {
+ if (_currentRegions[j] == newRegions[i]) {
+ _currentRegions[j] = NULL;
+ regFound = true;
+ break;
+ }
+ }
+ if (!regFound) {
+ newRegions[i]->applyEvent("ActorEntry");
+ }
+ }
+
+ for (int i = 0; i < MAX_NUM_REGIONS; i++) {
+ if (_currentRegions[i] && _gameRef->validObject(_currentRegions[i])) {
+ _currentRegions[i]->applyEvent("ActorLeave");
+ }
+ _currentRegions[i] = newRegions[i];
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::invalidateCurrRegions() {
+ for (int i = 0; i < MAX_NUM_REGIONS; i++) {
+ _currentRegions[i] = NULL;
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::getScale(float *scaleX, float *scaleY) {
+ if (_zoomable) {
+ if (_scaleX >= 0 || _scaleY >= 0) {
+ *scaleX = _scaleX < 0 ? 100 : _scaleX;
+ *scaleY = _scaleY < 0 ? 100 : _scaleY;
+ } else if (_scale >= 0) {
+ *scaleX = *scaleY = _scale;
+ } else {
+ *scaleX = *scaleY = ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) + _relativeScale;
+ }
+ } else {
+ *scaleX = *scaleY = 100;
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::updateSpriteAttachments() {
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ _attachmentsPre[i]->update();
+ }
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ _attachmentsPost[i]->update();
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::displaySpriteAttachments(bool preDisplay) {
+ if (preDisplay) {
+ for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
+ displaySpriteAttachment(_attachmentsPre[i]);
+ }
+ } else {
+ for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
+ displaySpriteAttachment(_attachmentsPost[i]);
+ }
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::displaySpriteAttachment(AdObject *attachment) {
+ if (!attachment->_active) {
+ return STATUS_OK;
+ }
+
+ float scaleX, scaleY;
+ getScale(&scaleX, &scaleY);
+
+ int origX = attachment->_posX;
+ int origY = attachment->_posY;
+
+ // inherit position from owner
+ attachment->_posX = (int)(this->_posX + attachment->_posX * scaleX / 100.0f);
+ attachment->_posY = (int)(this->_posY + attachment->_posY * scaleY / 100.0f);
+
+ // inherit other props
+ attachment->_alphaColor = this->_alphaColor;
+ attachment->_blendMode = this->_blendMode;
+
+ attachment->_scale = this->_scale;
+ attachment->_relativeScale = this->_relativeScale;
+ attachment->_scaleX = this->_scaleX;
+ attachment->_scaleY = this->_scaleY;
+
+ attachment->_rotate = this->_rotate;
+ attachment->_relativeRotate = this->_relativeRotate;
+ attachment->_rotateValid = this->_rotateValid;
+
+ attachment->_registerAlias = this;
+ attachment->_registrable = this->_registrable;
+
+ bool ret = attachment->display();
+
+ attachment->_posX = origX;
+ attachment->_posY = origY;
+
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+PartEmitter *AdObject::createParticleEmitter(bool followParent, int offsetX, int offsetY) {
+ _partFollowParent = followParent;
+ _partOffsetX = offsetX;
+ _partOffsetY = offsetY;
+
+ if (!_partEmitter) {
+ _partEmitter = new PartEmitter(_gameRef, this);
+ if (_partEmitter) {
+ _gameRef->registerObject(_partEmitter);
+ }
+ }
+ updatePartEmitter();
+ return _partEmitter;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdObject::updatePartEmitter() {
+ if (!_partEmitter) {
+ return STATUS_FAILED;
+ }
+
+ if (_partFollowParent) {
+ float scaleX, scaleY;
+ getScale(&scaleX, &scaleY);
+
+ _partEmitter->_posX = (int)(_posX + (scaleX / 100.0f) * _partOffsetX);
+ _partEmitter->_posY = (int)(_posY + (scaleY / 100.0f) * _partOffsetY);
+ }
+ return _partEmitter->update();
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_object.h b/engines/wintermute/ad/ad_object.h
index 9451707445..8395f58cff 100644
--- a/engines/wintermute/ad/ad_object.h
+++ b/engines/wintermute/ad/ad_object.h
@@ -1,124 +1,124 @@
-/* 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_ADOBJECT_H
-#define WINTERMUTE_ADOBJECT_H
-
-#include "engines/wintermute/ad/ad_types.h"
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class AdWaypointGroup;
-class AdRegion;
-class AdSentence;
-class BaseFont;
-class BaseRegion;
-class AdInventory;
-class PartEmitter;
-
-#define MAX_NUM_REGIONS 10
-
-class AdObject : public BaseObject {
-public:
- PartEmitter *_partEmitter;
- virtual PartEmitter *createParticleEmitter(bool followParent = false, int offsetX = 0, int offsetY = 0);
- virtual bool updatePartEmitter();
- bool _partFollowParent;
- int _partOffsetX;
- int _partOffsetY;
-
- bool invalidateCurrRegions();
- bool _subtitlesModRelative;
- bool _subtitlesModXCenter;
- int _subtitlesModX;
- int _subtitlesModY;
- int _subtitlesWidth;
- AdRegion *_stickRegion;
- bool _sceneIndependent;
- bool _ignoreItems;
- bool updateBlockRegion();
- bool _forcedTalkAnimUsed;
- char *_forcedTalkAnimName;
- virtual bool getExtendedFlag(const char *flagName);
- virtual bool resetSoundPan();
- virtual bool updateSounds();
- bool reset();
- DECLARE_PERSISTENT(AdObject, BaseObject)
- virtual void talk(const char *text, const char *sound = NULL, uint32 duration = 0, const char *stances = NULL, TTextAlign align = TAL_CENTER);
- virtual int getHeight();
- AdSentence *_sentence;
- bool setFont(const char *filename);
- virtual bool update();
- virtual bool display();
- bool _drawn;
- bool _active;
- virtual bool playAnim(const char *filename);
- BaseSprite *_animSprite;
- BaseSprite *_currentSprite;
- TObjectState _state;
- TObjectState _nextState;
- TObjectType _type;
- AdObject(BaseGame *inGame);
- virtual ~AdObject();
- BaseFont *_font;
- BaseSprite *_tempSprite2;
- BaseRegion *_blockRegion;
- AdWaypointGroup *_wptGroup;
- BaseRegion *_currentBlockRegion;
- AdWaypointGroup *_currentWptGroup;
- AdInventory *getInventory();
-
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
-
- virtual bool afterMove();
- AdRegion *_currentRegions[MAX_NUM_REGIONS];
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-
- BaseArray<AdObject *> _attachmentsPre;
- BaseArray<AdObject *> _attachmentsPost;
-
- bool updateSpriteAttachments();
- bool displaySpriteAttachments(bool preDisplay);
- AdObject *_registerAlias;
-private:
- bool displaySpriteAttachment(AdObject *attachment);
- AdInventory *_inventory;
-
-protected:
- bool getScale(float *scaleX, float *scaleY);
-};
-
-} // 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_ADOBJECT_H
+#define WINTERMUTE_ADOBJECT_H
+
+#include "engines/wintermute/ad/ad_types.h"
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class AdWaypointGroup;
+class AdRegion;
+class AdSentence;
+class BaseFont;
+class BaseRegion;
+class AdInventory;
+class PartEmitter;
+
+#define MAX_NUM_REGIONS 10
+
+class AdObject : public BaseObject {
+public:
+ PartEmitter *_partEmitter;
+ virtual PartEmitter *createParticleEmitter(bool followParent = false, int offsetX = 0, int offsetY = 0);
+ virtual bool updatePartEmitter();
+ bool _partFollowParent;
+ int _partOffsetX;
+ int _partOffsetY;
+
+ bool invalidateCurrRegions();
+ bool _subtitlesModRelative;
+ bool _subtitlesModXCenter;
+ int _subtitlesModX;
+ int _subtitlesModY;
+ int _subtitlesWidth;
+ AdRegion *_stickRegion;
+ bool _sceneIndependent;
+ bool _ignoreItems;
+ bool updateBlockRegion();
+ bool _forcedTalkAnimUsed;
+ char *_forcedTalkAnimName;
+ virtual bool getExtendedFlag(const char *flagName);
+ virtual bool resetSoundPan();
+ virtual bool updateSounds();
+ bool reset();
+ DECLARE_PERSISTENT(AdObject, BaseObject)
+ virtual void talk(const char *text, const char *sound = NULL, uint32 duration = 0, const char *stances = NULL, TTextAlign align = TAL_CENTER);
+ virtual int getHeight();
+ AdSentence *_sentence;
+ bool setFont(const char *filename);
+ virtual bool update();
+ virtual bool display();
+ bool _drawn;
+ bool _active;
+ virtual bool playAnim(const char *filename);
+ BaseSprite *_animSprite;
+ BaseSprite *_currentSprite;
+ TObjectState _state;
+ TObjectState _nextState;
+ TObjectType _type;
+ AdObject(BaseGame *inGame);
+ virtual ~AdObject();
+ BaseFont *_font;
+ BaseSprite *_tempSprite2;
+ BaseRegion *_blockRegion;
+ AdWaypointGroup *_wptGroup;
+ BaseRegion *_currentBlockRegion;
+ AdWaypointGroup *_currentWptGroup;
+ AdInventory *getInventory();
+
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+
+ virtual bool afterMove();
+ AdRegion *_currentRegions[MAX_NUM_REGIONS];
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+
+ BaseArray<AdObject *> _attachmentsPre;
+ BaseArray<AdObject *> _attachmentsPost;
+
+ bool updateSpriteAttachments();
+ bool displaySpriteAttachments(bool preDisplay);
+ AdObject *_registerAlias;
+private:
+ bool displaySpriteAttachment(AdObject *attachment);
+ AdInventory *_inventory;
+
+protected:
+ bool getScale(float *scaleX, float *scaleY);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_path.cpp b/engines/wintermute/ad/ad_path.cpp
index 21b68f4d48..c931213456 100644
--- a/engines/wintermute/ad/ad_path.cpp
+++ b/engines/wintermute/ad/ad_path.cpp
@@ -1,120 +1,120 @@
-/* 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/ad/ad_path.h"
-#include "engines/wintermute/base/base_point.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdPath, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdPath::AdPath(BaseGame *inGame) : BaseClass(inGame) {
- _currIndex = -1;
- _ready = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdPath::~AdPath() {
- reset();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdPath::reset() {
- for (uint32 i = 0; i < _points.size(); i++) {
- delete _points[i];
- }
-
- _points.clear();
- _currIndex = -1;
- _ready = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BasePoint *AdPath::getFirst() {
- if (_points.size() > 0) {
- _currIndex = 0;
- return _points[_currIndex];
- } else {
- return NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BasePoint *AdPath::getNext() {
- _currIndex++;
- if (_currIndex < (int32)_points.size()) {
- return _points[_currIndex];
- } else {
- return NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BasePoint *AdPath::getCurrent() {
- if (_currIndex >= 0 && _currIndex < (int32)_points.size()) {
- return _points[_currIndex];
- } else {
- return NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdPath::addPoint(BasePoint *point) {
- _points.add(point);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdPath::setReady(bool ready) {
- bool orig = _ready;
- _ready = ready;
-
- return orig;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdPath::persist(BasePersistenceManager *persistMgr) {
-
- persistMgr->transfer(TMEMBER(_gameRef));
-
- persistMgr->transfer(TMEMBER(_currIndex));
- _points.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_ready));
-
- 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/ad/ad_path.h"
+#include "engines/wintermute/base/base_point.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdPath, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdPath::AdPath(BaseGame *inGame) : BaseClass(inGame) {
+ _currIndex = -1;
+ _ready = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdPath::~AdPath() {
+ reset();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdPath::reset() {
+ for (uint32 i = 0; i < _points.size(); i++) {
+ delete _points[i];
+ }
+
+ _points.clear();
+ _currIndex = -1;
+ _ready = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BasePoint *AdPath::getFirst() {
+ if (_points.size() > 0) {
+ _currIndex = 0;
+ return _points[_currIndex];
+ } else {
+ return NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BasePoint *AdPath::getNext() {
+ _currIndex++;
+ if (_currIndex < (int32)_points.size()) {
+ return _points[_currIndex];
+ } else {
+ return NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BasePoint *AdPath::getCurrent() {
+ if (_currIndex >= 0 && _currIndex < (int32)_points.size()) {
+ return _points[_currIndex];
+ } else {
+ return NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdPath::addPoint(BasePoint *point) {
+ _points.add(point);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdPath::setReady(bool ready) {
+ bool orig = _ready;
+ _ready = ready;
+
+ return orig;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdPath::persist(BasePersistenceManager *persistMgr) {
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ persistMgr->transfer(TMEMBER(_currIndex));
+ _points.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_ready));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_path.h b/engines/wintermute/ad/ad_path.h
index de115b261a..6b043197aa 100644
--- a/engines/wintermute/ad/ad_path.h
+++ b/engines/wintermute/ad/ad_path.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_ADPATH_H
-#define WINTERMUTE_ADPATH_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/coll_templ.h"
-#include "engines/wintermute/base/base.h"
-
-namespace Wintermute {
-class BasePoint;
-class AdPath : public BaseClass {
-public:
- DECLARE_PERSISTENT(AdPath, BaseClass)
- BasePoint *getCurrent();
- bool setReady(bool ready = true);
- void addPoint(BasePoint *point);
- BasePoint *getNext();
- BasePoint *getFirst();
- void reset();
- AdPath(BaseGame *inGame);
- virtual ~AdPath();
- BaseArray<BasePoint *> _points;
- int _currIndex;
- bool _ready;
-};
-
-} // 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_ADPATH_H
+#define WINTERMUTE_ADPATH_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/base/base.h"
+
+namespace Wintermute {
+class BasePoint;
+class AdPath : public BaseClass {
+public:
+ DECLARE_PERSISTENT(AdPath, BaseClass)
+ BasePoint *getCurrent();
+ bool setReady(bool ready = true);
+ void addPoint(BasePoint *point);
+ BasePoint *getNext();
+ BasePoint *getFirst();
+ void reset();
+ AdPath(BaseGame *inGame);
+ virtual ~AdPath();
+ BaseArray<BasePoint *> _points;
+ int _currIndex;
+ bool _ready;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_path_point.cpp b/engines/wintermute/ad/ad_path_point.cpp
index 1fb954c668..a36648eb69 100644
--- a/engines/wintermute/ad/ad_path_point.cpp
+++ b/engines/wintermute/ad/ad_path_point.cpp
@@ -1,75 +1,75 @@
-/* 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/ad/ad_path_point.h"
-#include "engines/wintermute/base/base_persistence_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdPathPoint, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdPathPoint::AdPathPoint() {
- x = y = 0;
- _distance = 0;
-
- _marked = false;
- _origin = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdPathPoint::AdPathPoint(int initX, int initY, int initDistance) {
- x = initX;
- y = initY;
- _distance = initDistance;
-
- _marked = false;
- _origin = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdPathPoint::~AdPathPoint() {
- _origin = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
-
- BasePoint::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_distance));
- persistMgr->transfer(TMEMBER(_marked));
- persistMgr->transfer(TMEMBER(_origin));
-
- 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/ad/ad_path_point.h"
+#include "engines/wintermute/base/base_persistence_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdPathPoint, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdPathPoint::AdPathPoint() {
+ x = y = 0;
+ _distance = 0;
+
+ _marked = false;
+ _origin = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdPathPoint::AdPathPoint(int initX, int initY, int initDistance) {
+ x = initX;
+ y = initY;
+ _distance = initDistance;
+
+ _marked = false;
+ _origin = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdPathPoint::~AdPathPoint() {
+ _origin = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
+
+ BasePoint::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_distance));
+ persistMgr->transfer(TMEMBER(_marked));
+ persistMgr->transfer(TMEMBER(_origin));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_path_point.h b/engines/wintermute/ad/ad_path_point.h
index 8201750cef..58457976c8 100644
--- a/engines/wintermute/ad/ad_path_point.h
+++ b/engines/wintermute/ad/ad_path_point.h
@@ -1,50 +1,50 @@
-/* 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_ADPATHPOINT_H
-#define WINTERMUTE_ADPATHPOINT_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/base/base_point.h"
-
-namespace Wintermute {
-
-class AdPathPoint : public BasePoint {
-public:
- DECLARE_PERSISTENT(AdPathPoint, BasePoint)
- AdPathPoint(int initX, int initY, int initDistance);
- AdPathPoint();
- virtual ~AdPathPoint();
- AdPathPoint *_origin;
- bool _marked;
- int _distance;
-};
-
-} // 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_ADPATHPOINT_H
+#define WINTERMUTE_ADPATHPOINT_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/base/base_point.h"
+
+namespace Wintermute {
+
+class AdPathPoint : public BasePoint {
+public:
+ DECLARE_PERSISTENT(AdPathPoint, BasePoint)
+ AdPathPoint(int initX, int initY, int initDistance);
+ AdPathPoint();
+ virtual ~AdPathPoint();
+ AdPathPoint *_origin;
+ bool _marked;
+ int _distance;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_region.cpp b/engines/wintermute/ad/ad_region.cpp
index 3e5f91524d..88bd8201a2 100644
--- a/engines/wintermute/ad/ad_region.cpp
+++ b/engines/wintermute/ad/ad_region.cpp
@@ -1,397 +1,397 @@
-/* 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/ad/ad_region.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#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/base_file_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdRegion, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdRegion::AdRegion(BaseGame *inGame) : BaseRegion(inGame) {
- _blocked = false;
- _decoration = false;
- _zoom = 0;
- _alpha = 0xFFFFFFFF;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdRegion::~AdRegion() {
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdRegion::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing REGION file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(REGION)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(ACTIVE)
-TOKEN_DEF(ZOOM)
-TOKEN_DEF(SCALE)
-TOKEN_DEF(BLOCKED)
-TOKEN_DEF(DECORATION)
-TOKEN_DEF(POINT)
-TOKEN_DEF(ALPHA_COLOR)
-TOKEN_DEF(ALPHA)
-TOKEN_DEF(EDITOR_SELECTED_POINT)
-TOKEN_DEF(EDITOR_SELECTED)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(REGION)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(ACTIVE)
- TOKEN_TABLE(ZOOM)
- TOKEN_TABLE(SCALE)
- TOKEN_TABLE(BLOCKED)
- TOKEN_TABLE(DECORATION)
- TOKEN_TABLE(POINT)
- TOKEN_TABLE(ALPHA_COLOR)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE(EDITOR_SELECTED_POINT)
- TOKEN_TABLE(EDITOR_SELECTED)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
- _gameRef->LOG(0, "'REGION' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- for (uint32 i = 0; i < _points.size(); i++) {
- delete _points[i];
- }
- _points.clear();
-
- int ar = 255, ag = 255, ab = 255, alpha = 255;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
- break;
-
- case TOKEN_BLOCKED:
- parser.scanStr((char *)params, "%b", &_blocked);
- break;
-
- case TOKEN_DECORATION:
- parser.scanStr((char *)params, "%b", &_decoration);
- break;
-
- case TOKEN_ZOOM:
- case TOKEN_SCALE: {
- int j;
- parser.scanStr((char *)params, "%d", &j);
- _zoom = (float)j;
- }
- break;
-
- case TOKEN_POINT: {
- int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
- _points.add(new BasePoint(x, y));
- }
- break;
-
- case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
- break;
-
- case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
- break;
-
- case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
- break;
-
- case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in REGION definition");
- return STATUS_FAILED;
- }
-
- createRegion();
-
- _alpha = BYTETORGBA(ar, ag, ab, alpha);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- /*
- //////////////////////////////////////////////////////////////////////////
- // SkipTo
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SkipTo")==0) {
- stack->correctParams(2);
- _posX = stack->pop()->getInt();
- _posY = stack->pop()->getInt();
- stack->pushNULL();
-
- return STATUS_OK;
- }
-
- else*/ return BaseRegion::scCallMethod(script, stack, thisStack, name);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdRegion::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("ad region");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Name") == 0) {
- _scValue->setString(getName());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Blocked
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Blocked") == 0) {
- _scValue->setBool(_blocked);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Decoration
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Decoration") == 0) {
- _scValue->setBool(_decoration);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Scale
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Scale") == 0) {
- _scValue->setFloat(_zoom);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AlphaColor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AlphaColor") == 0) {
- _scValue->setInt((int)_alpha);
- return _scValue;
- } else {
- return BaseRegion::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Name") == 0) {
- setName(value->getString());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Blocked
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Blocked") == 0) {
- _blocked = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Decoration
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Decoration") == 0) {
- _decoration = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Scale
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Scale") == 0) {
- _zoom = value->getFloat();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AlphaColor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AlphaColor") == 0) {
- _alpha = (uint32)value->getInt();
- return STATUS_OK;
- } else {
- return BaseRegion::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdRegion::scToString() {
- return "[ad region]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "REGION {\n");
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
- buffer->putTextIndent(indent + 2, "BLOCKED=%s\n", _blocked ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "DECORATION=%s\n", _decoration ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_zoom);
- buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alpha), RGBCOLGetG(_alpha), RGBCOLGetB(_alpha));
- buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alpha));
- buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
-
- for (uint32 i = 0; i < _scripts.size(); i++) {
- buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
- }
-
- if (_scProp) {
- _scProp->saveAsText(buffer, indent + 2);
- }
-
- for (uint32 i = 0; i < _points.size(); i++) {
- buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
- }
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRegion::persist(BasePersistenceManager *persistMgr) {
- BaseRegion::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_alpha));
- persistMgr->transfer(TMEMBER(_blocked));
- persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_zoom));
-
- 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/ad/ad_region.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#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/base_file_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdRegion, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdRegion::AdRegion(BaseGame *inGame) : BaseRegion(inGame) {
+ _blocked = false;
+ _decoration = false;
+ _zoom = 0;
+ _alpha = 0xFFFFFFFF;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdRegion::~AdRegion() {
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdRegion::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing REGION file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(REGION)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(ACTIVE)
+TOKEN_DEF(ZOOM)
+TOKEN_DEF(SCALE)
+TOKEN_DEF(BLOCKED)
+TOKEN_DEF(DECORATION)
+TOKEN_DEF(POINT)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(EDITOR_SELECTED_POINT)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(REGION)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(ACTIVE)
+ TOKEN_TABLE(ZOOM)
+ TOKEN_TABLE(SCALE)
+ TOKEN_TABLE(BLOCKED)
+ TOKEN_TABLE(DECORATION)
+ TOKEN_TABLE(POINT)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(EDITOR_SELECTED_POINT)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
+ _gameRef->LOG(0, "'REGION' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ for (uint32 i = 0; i < _points.size(); i++) {
+ delete _points[i];
+ }
+ _points.clear();
+
+ int ar = 255, ag = 255, ab = 255, alpha = 255;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_ACTIVE:
+ parser.scanStr((char *)params, "%b", &_active);
+ break;
+
+ case TOKEN_BLOCKED:
+ parser.scanStr((char *)params, "%b", &_blocked);
+ break;
+
+ case TOKEN_DECORATION:
+ parser.scanStr((char *)params, "%b", &_decoration);
+ break;
+
+ case TOKEN_ZOOM:
+ case TOKEN_SCALE: {
+ int j;
+ parser.scanStr((char *)params, "%d", &j);
+ _zoom = (float)j;
+ }
+ break;
+
+ case TOKEN_POINT: {
+ int x, y;
+ parser.scanStr((char *)params, "%d,%d", &x, &y);
+ _points.add(new BasePoint(x, y));
+ }
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.scanStr((char *)params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.scanStr((char *)params, "%b", &_editorSelected);
+ break;
+
+ case TOKEN_EDITOR_SELECTED_POINT:
+ parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in REGION definition");
+ return STATUS_FAILED;
+ }
+
+ createRegion();
+
+ _alpha = BYTETORGBA(ar, ag, ab, alpha);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ /*
+ //////////////////////////////////////////////////////////////////////////
+ // SkipTo
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SkipTo")==0) {
+ stack->correctParams(2);
+ _posX = stack->pop()->getInt();
+ _posY = stack->pop()->getInt();
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ else*/ return BaseRegion::scCallMethod(script, stack, thisStack, name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdRegion::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("ad region");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Name") == 0) {
+ _scValue->setString(getName());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Blocked
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Blocked") == 0) {
+ _scValue->setBool(_blocked);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Decoration
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Decoration") == 0) {
+ _scValue->setBool(_decoration);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Scale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Scale") == 0) {
+ _scValue->setFloat(_zoom);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AlphaColor") == 0) {
+ _scValue->setInt((int)_alpha);
+ return _scValue;
+ } else {
+ return BaseRegion::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Name") == 0) {
+ setName(value->getString());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Blocked
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Blocked") == 0) {
+ _blocked = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Decoration
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Decoration") == 0) {
+ _decoration = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Scale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Scale") == 0) {
+ _zoom = value->getFloat();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AlphaColor") == 0) {
+ _alpha = (uint32)value->getInt();
+ return STATUS_OK;
+ } else {
+ return BaseRegion::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdRegion::scToString() {
+ return "[ad region]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "REGION {\n");
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
+ buffer->putTextIndent(indent + 2, "BLOCKED=%s\n", _blocked ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "DECORATION=%s\n", _decoration ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_zoom);
+ buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alpha), RGBCOLGetG(_alpha), RGBCOLGetB(_alpha));
+ buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alpha));
+ buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
+
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
+ }
+
+ if (_scProp) {
+ _scProp->saveAsText(buffer, indent + 2);
+ }
+
+ for (uint32 i = 0; i < _points.size(); i++) {
+ buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
+ }
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRegion::persist(BasePersistenceManager *persistMgr) {
+ BaseRegion::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_alpha));
+ persistMgr->transfer(TMEMBER(_blocked));
+ persistMgr->transfer(TMEMBER(_decoration));
+ persistMgr->transfer(TMEMBER(_zoom));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_region.h b/engines/wintermute/ad/ad_region.h
index 5c33291a88..a60cb9a3f2 100644
--- a/engines/wintermute/ad/ad_region.h
+++ b/engines/wintermute/ad/ad_region.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_ADREGION_H
-#define WINTERMUTE_ADREGION_H
-
-#include "engines/wintermute/base/base_region.h"
-
-namespace Wintermute {
-
-class AdRegion : public BaseRegion {
-public:
- DECLARE_PERSISTENT(AdRegion, BaseRegion)
- uint32 _alpha;
- float _zoom;
- bool _blocked;
- bool _decoration;
- AdRegion(BaseGame *inGame);
- virtual ~AdRegion();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-};
-
-} // 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_ADREGION_H
+#define WINTERMUTE_ADREGION_H
+
+#include "engines/wintermute/base/base_region.h"
+
+namespace Wintermute {
+
+class AdRegion : public BaseRegion {
+public:
+ DECLARE_PERSISTENT(AdRegion, BaseRegion)
+ uint32 _alpha;
+ float _zoom;
+ bool _blocked;
+ bool _decoration;
+ AdRegion(BaseGame *inGame);
+ virtual ~AdRegion();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_response.cpp b/engines/wintermute/ad/ad_response.cpp
index f7886bba5a..37f46118bf 100644
--- a/engines/wintermute/ad/ad_response.cpp
+++ b/engines/wintermute/ad/ad_response.cpp
@@ -1,146 +1,146 @@
-/* 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/ad/ad_response.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/utils/utils.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdResponse, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdResponse::AdResponse(BaseGame *inGame) : BaseObject(inGame) {
- _text = NULL;
- _textOrig = NULL;
- _icon = _iconHover = _iconPressed = NULL;
- _font = NULL;
- _iD = 0;
- _responseType = RESPONSE_ALWAYS;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdResponse::~AdResponse() {
- delete[] _text;
- delete[] _textOrig;
- delete _icon;
- delete _iconHover;
- delete _iconPressed;
- _text = NULL;
- _textOrig = NULL;
- _icon = NULL;
- _iconHover = NULL;
- _iconPressed = NULL;
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdResponse::setText(const char *text) {
- BaseUtils::setString(&_text, text);
- BaseUtils::setString(&_textOrig, text);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponse::setIcon(const char *filename) {
- delete _icon;
- _icon = new BaseSprite(_gameRef);
- if (!_icon || DID_FAIL(_icon->loadFile(filename))) {
- _gameRef->LOG(0, "AdResponse::setIcon failed for file '%s'", filename);
- delete _icon;
- _icon = NULL;
- return STATUS_FAILED;
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponse::setFont(const char *filename) {
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
- _font = _gameRef->_fontStorage->addFont(filename);
- if (!_font) {
- _gameRef->LOG(0, "AdResponse::setFont failed for file '%s'", filename);
- return STATUS_FAILED;
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponse::setIconHover(const char *filename) {
- delete _iconHover;
- _iconHover = new BaseSprite(_gameRef);
- if (!_iconHover || DID_FAIL(_iconHover->loadFile(filename))) {
- _gameRef->LOG(0, "AdResponse::setIconHover failed for file '%s'", filename);
- delete _iconHover;
- _iconHover = NULL;
- return STATUS_FAILED;
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponse::setIconPressed(const char *filename) {
- delete _iconPressed;
- _iconPressed = new BaseSprite(_gameRef);
- if (!_iconPressed || DID_FAIL(_iconPressed->loadFile(filename))) {
- _gameRef->LOG(0, "AdResponse::setIconPressed failed for file '%s'", filename);
- delete _iconPressed;
- _iconPressed = NULL;
- return STATUS_FAILED;
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponse::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_icon));
- persistMgr->transfer(TMEMBER(_iconHover));
- persistMgr->transfer(TMEMBER(_iconPressed));
- persistMgr->transfer(TMEMBER(_iD));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_textOrig));
- persistMgr->transfer(TMEMBER_INT(_responseType));
- persistMgr->transfer(TMEMBER(_font));
-
- 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/ad/ad_response.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/utils/utils.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdResponse, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdResponse::AdResponse(BaseGame *inGame) : BaseObject(inGame) {
+ _text = NULL;
+ _textOrig = NULL;
+ _icon = _iconHover = _iconPressed = NULL;
+ _font = NULL;
+ _iD = 0;
+ _responseType = RESPONSE_ALWAYS;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdResponse::~AdResponse() {
+ delete[] _text;
+ delete[] _textOrig;
+ delete _icon;
+ delete _iconHover;
+ delete _iconPressed;
+ _text = NULL;
+ _textOrig = NULL;
+ _icon = NULL;
+ _iconHover = NULL;
+ _iconPressed = NULL;
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdResponse::setText(const char *text) {
+ BaseUtils::setString(&_text, text);
+ BaseUtils::setString(&_textOrig, text);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponse::setIcon(const char *filename) {
+ delete _icon;
+ _icon = new BaseSprite(_gameRef);
+ if (!_icon || DID_FAIL(_icon->loadFile(filename))) {
+ _gameRef->LOG(0, "AdResponse::setIcon failed for file '%s'", filename);
+ delete _icon;
+ _icon = NULL;
+ return STATUS_FAILED;
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponse::setFont(const char *filename) {
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+ _font = _gameRef->_fontStorage->addFont(filename);
+ if (!_font) {
+ _gameRef->LOG(0, "AdResponse::setFont failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponse::setIconHover(const char *filename) {
+ delete _iconHover;
+ _iconHover = new BaseSprite(_gameRef);
+ if (!_iconHover || DID_FAIL(_iconHover->loadFile(filename))) {
+ _gameRef->LOG(0, "AdResponse::setIconHover failed for file '%s'", filename);
+ delete _iconHover;
+ _iconHover = NULL;
+ return STATUS_FAILED;
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponse::setIconPressed(const char *filename) {
+ delete _iconPressed;
+ _iconPressed = new BaseSprite(_gameRef);
+ if (!_iconPressed || DID_FAIL(_iconPressed->loadFile(filename))) {
+ _gameRef->LOG(0, "AdResponse::setIconPressed failed for file '%s'", filename);
+ delete _iconPressed;
+ _iconPressed = NULL;
+ return STATUS_FAILED;
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponse::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_icon));
+ persistMgr->transfer(TMEMBER(_iconHover));
+ persistMgr->transfer(TMEMBER(_iconPressed));
+ persistMgr->transfer(TMEMBER(_iD));
+ persistMgr->transfer(TMEMBER(_text));
+ persistMgr->transfer(TMEMBER(_textOrig));
+ persistMgr->transfer(TMEMBER_INT(_responseType));
+ persistMgr->transfer(TMEMBER(_font));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response.h b/engines/wintermute/ad/ad_response.h
index 0678ef5a37..0ba88cf2e8 100644
--- a/engines/wintermute/ad/ad_response.h
+++ b/engines/wintermute/ad/ad_response.h
@@ -1,61 +1,61 @@
-/* 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_ADRESPONSE_H
-#define WINTERMUTE_ADRESPONSE_H
-
-
-#include "engines/wintermute/base/base_object.h"
-#include "engines/wintermute/ad/ad_types.h"
-
-namespace Wintermute {
-class BaseFont;
-class AdResponse : public BaseObject {
-public:
- DECLARE_PERSISTENT(AdResponse, BaseObject)
- bool setIcon(const char *filename);
- bool setFont(const char *filename);
- bool setIconHover(const char *filename);
- bool setIconPressed(const char *filename);
- void setText(const char *text);
- int _iD;
- BaseSprite *_icon;
- BaseSprite *_iconHover;
- BaseSprite *_iconPressed;
- BaseFont *_font;
- char *_text;
- char *_textOrig;
- AdResponse(BaseGame *inGame);
- virtual ~AdResponse();
- TResponseType _responseType;
-
-};
-
-} // 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_ADRESPONSE_H
+#define WINTERMUTE_ADRESPONSE_H
+
+
+#include "engines/wintermute/base/base_object.h"
+#include "engines/wintermute/ad/ad_types.h"
+
+namespace Wintermute {
+class BaseFont;
+class AdResponse : public BaseObject {
+public:
+ DECLARE_PERSISTENT(AdResponse, BaseObject)
+ bool setIcon(const char *filename);
+ bool setFont(const char *filename);
+ bool setIconHover(const char *filename);
+ bool setIconPressed(const char *filename);
+ void setText(const char *text);
+ int _iD;
+ BaseSprite *_icon;
+ BaseSprite *_iconHover;
+ BaseSprite *_iconPressed;
+ BaseFont *_font;
+ char *_text;
+ char *_textOrig;
+ AdResponse(BaseGame *inGame);
+ virtual ~AdResponse();
+ TResponseType _responseType;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_response_box.cpp b/engines/wintermute/ad/ad_response_box.cpp
index 76510e2f3e..a27f1ca54b 100644
--- a/engines/wintermute/ad/ad_response_box.cpp
+++ b/engines/wintermute/ad/ad_response_box.cpp
@@ -1,712 +1,712 @@
-/* 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/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_response_box.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_surface_storage.h"
-#include "engines/wintermute/ui/ui_button.h"
-#include "engines/wintermute/ui/ui_window.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/ad/ad_response.h"
-#include "engines/wintermute/base/scriptables/script.h"
-#include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/wintermute.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdResponseBox, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdResponseBox::AdResponseBox(BaseGame *inGame) : BaseObject(inGame) {
- _font = _fontHover = NULL;
-
- _window = NULL;
- _shieldWindow = new UIWindow(_gameRef);
-
- _horizontal = false;
- BasePlatform::setRectEmpty(&_responseArea);
- _scrollOffset = 0;
- _spacing = 0;
-
- _waitingScript = NULL;
- _lastResponseText = NULL;
- _lastResponseTextOrig = NULL;
-
- _verticalAlign = VAL_BOTTOM;
- _align = TAL_LEFT;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdResponseBox::~AdResponseBox() {
-
- delete _window;
- _window = NULL;
- delete _shieldWindow;
- _shieldWindow = NULL;
- delete[] _lastResponseText;
- _lastResponseText = NULL;
- delete[] _lastResponseTextOrig;
- _lastResponseTextOrig = NULL;
-
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
- if (_fontHover) {
- _gameRef->_fontStorage->removeFont(_fontHover);
- }
-
- clearResponses();
- clearButtons();
-
- _waitingScript = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdResponseBox::clearResponses() {
- for (uint32 i = 0; i < _responses.size(); i++) {
- delete _responses[i];
- }
- _responses.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdResponseBox::clearButtons() {
- for (uint32 i = 0; i < _respButtons.size(); i++) {
- delete _respButtons[i];
- }
- _respButtons.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::invalidateButtons() {
- for (uint32 i = 0; i < _respButtons.size(); i++) {
- _respButtons[i]->_image = NULL;
- _respButtons[i]->_cursor = NULL;
- _respButtons[i]->_font = NULL;
- _respButtons[i]->_fontHover = NULL;
- _respButtons[i]->_fontPress = NULL;
- _respButtons[i]->setText("");
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::createButtons() {
- clearButtons();
-
- _scrollOffset = 0;
- for (uint32 i = 0; i < _responses.size(); i++) {
- UIButton *btn = new UIButton(_gameRef);
- if (btn) {
- btn->_parent = _window;
- btn->_sharedFonts = btn->_sharedImages = true;
- btn->_sharedCursors = true;
- // iconic
- if (_responses[i]->_icon) {
- btn->_image = _responses[i]->_icon;
- if (_responses[i]->_iconHover) {
- btn->_imageHover = _responses[i]->_iconHover;
- }
- if (_responses[i]->_iconPressed) {
- btn->_imagePress = _responses[i]->_iconPressed;
- }
-
- btn->setCaption(_responses[i]->_text);
- if (_cursor) {
- btn->_cursor = _cursor;
- } else if (_gameRef->_activeCursor) {
- btn->_cursor = _gameRef->_activeCursor;
- }
- }
- // textual
- else {
- btn->setText(_responses[i]->_text);
- btn->_font = (_font == NULL) ? _gameRef->_systemFont : _font;
- btn->_fontHover = (_fontHover == NULL) ? _gameRef->_systemFont : _fontHover;
- btn->_fontPress = btn->_fontHover;
- btn->_align = _align;
-
- if (_gameRef->_touchInterface) {
- btn->_fontHover = btn->_font;
- }
-
-
- if (_responses[i]->_font) {
- btn->_font = _responses[i]->_font;
- }
-
- btn->_width = _responseArea.right - _responseArea.left;
- if (btn->_width <= 0) {
- btn->_width = _gameRef->_renderer->_width;
- }
- }
- btn->setName("response");
- btn->correctSize();
-
- // make the responses touchable
- if (_gameRef->_touchInterface) {
- btn->_height = MAX(btn->_height, 50);
- }
-
- //btn->SetListener(this, btn, _responses[i]->_iD);
- btn->setListener(this, btn, i);
- btn->_visible = false;
- _respButtons.add(btn);
-
- if (_responseArea.bottom - _responseArea.top < btn->_height) {
- _gameRef->LOG(0, "Warning: Response '%s' is too high to be displayed within response box. Correcting.", _responses[i]->_text);
- _responseArea.bottom += (btn->_height - (_responseArea.bottom - _responseArea.top));
- }
- }
- }
- _ready = false;
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdResponseBox::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing RESPONSE_BOX file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(RESPONSE_BOX)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(FONT_HOVER)
-TOKEN_DEF(FONT)
-TOKEN_DEF(AREA)
-TOKEN_DEF(HORIZONTAL)
-TOKEN_DEF(SPACING)
-TOKEN_DEF(WINDOW)
-TOKEN_DEF(CURSOR)
-TOKEN_DEF(TEXT_ALIGN)
-TOKEN_DEF(VERTICAL_ALIGN)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(RESPONSE_BOX)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(FONT_HOVER)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(AREA)
- TOKEN_TABLE(HORIZONTAL)
- TOKEN_TABLE(SPACING)
- TOKEN_TABLE(WINDOW)
- TOKEN_TABLE(CURSOR)
- TOKEN_TABLE(TEXT_ALIGN)
- TOKEN_TABLE(VERTICAL_ALIGN)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_RESPONSE_BOX) {
- _gameRef->LOG(0, "'RESPONSE_BOX' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_WINDOW:
- delete _window;
- _window = new UIWindow(_gameRef);
- if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
- delete _window;
- _window = NULL;
- cmd = PARSERR_GENERIC;
- } else if (_shieldWindow) {
- _shieldWindow->_parent = _window;
- }
- break;
-
- case TOKEN_FONT:
- if (_font) {
- _gameRef->_fontStorage->removeFont(_font);
- }
- _font = _gameRef->_fontStorage->addFont((char *)params);
- if (!_font) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_FONT_HOVER:
- if (_fontHover) {
- _gameRef->_fontStorage->removeFont(_fontHover);
- }
- _fontHover = _gameRef->_fontStorage->addFont((char *)params);
- if (!_fontHover) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
- break;
-
- case TOKEN_HORIZONTAL:
- parser.scanStr((char *)params, "%b", &_horizontal);
- break;
-
- case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "center") == 0) {
- _align = TAL_CENTER;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
- _align = TAL_RIGHT;
- } else {
- _align = TAL_LEFT;
- }
- break;
-
- case TOKEN_VERTICAL_ALIGN:
- if (scumm_stricmp((char *)params, "top") == 0) {
- _verticalAlign = VAL_TOP;
- } else if (scumm_stricmp((char *)params, "center") == 0) {
- _verticalAlign = VAL_CENTER;
- } else {
- _verticalAlign = VAL_BOTTOM;
- }
- break;
-
- case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
-
- case TOKEN_CURSOR:
- delete _cursor;
- _cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
- delete _cursor;
- _cursor = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in RESPONSE_BOX definition");
- return STATUS_FAILED;
- }
-
- if (_window) {
- for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
- _window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
- }
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "RESPONSE_BOX\n");
- buffer->putTextIndent(indent, "{\n");
-
- buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _responseArea.left, _responseArea.top, _responseArea.right, _responseArea.bottom);
-
- if (_font && _font->getFilename()) {
- buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename());
- }
- if (_fontHover && _fontHover->getFilename()) {
- buffer->putTextIndent(indent + 2, "FONT_HOVER=\"%s\"\n", _fontHover->getFilename());
- }
-
- if (_cursor && _cursor->getFilename()) {
- buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename());
- }
-
- buffer->putTextIndent(indent + 2, "HORIZONTAL=%s\n", _horizontal ? "TRUE" : "FALSE");
-
- switch (_align) {
- case TAL_LEFT:
- buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "left");
- break;
- case TAL_RIGHT:
- buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "right");
- break;
- case TAL_CENTER:
- buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "center");
- break;
- default:
- error("AdResponseBox::SaveAsText - Unhandled enum");
- break;
- }
-
- switch (_verticalAlign) {
- case VAL_TOP:
- buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "top");
- break;
- case VAL_BOTTOM:
- buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "bottom");
- break;
- case VAL_CENTER:
- buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "center");
- break;
- }
-
- buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // window
- if (_window) {
- _window->saveAsText(buffer, indent + 2);
- }
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // editor properties
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n");
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::display() {
- Rect32 rect = _responseArea;
- if (_window) {
- rect.offsetRect(_window->_posX, _window->_posY);
- //_window->display();
- }
-
- int xxx, yyy;
- uint32 i;
-
- xxx = rect.left;
- yyy = rect.top;
-
- // shift down if needed
- if (!_horizontal) {
- int totalHeight = 0;
- for (i = 0; i < _respButtons.size(); i++) {
- totalHeight += (_respButtons[i]->_height + _spacing);
- }
- totalHeight -= _spacing;
-
- switch (_verticalAlign) {
- case VAL_BOTTOM:
- if (yyy + totalHeight < rect.bottom) {
- yyy = rect.bottom - totalHeight;
- }
- break;
-
- case VAL_CENTER:
- if (yyy + totalHeight < rect.bottom) {
- yyy += ((rect.bottom - rect.top) - totalHeight) / 2;
- }
- break;
-
- case VAL_TOP:
- // do nothing
- break;
- }
- }
-
- // prepare response buttons
- bool scrollNeeded = false;
- for (i = _scrollOffset; i < _respButtons.size(); i++) {
- if ((_horizontal && xxx + _respButtons[i]->_width > rect.right)
- || (!_horizontal && yyy + _respButtons[i]->_height > rect.bottom)) {
-
- scrollNeeded = true;
- _respButtons[i]->_visible = false;
- break;
- }
-
- _respButtons[i]->_visible = true;
- _respButtons[i]->_posX = xxx;
- _respButtons[i]->_posY = yyy;
-
- if (_horizontal) {
- xxx += (_respButtons[i]->_width + _spacing);
- } else {
- yyy += (_respButtons[i]->_height + _spacing);
- }
- }
-
- // show appropriate scroll buttons
- if (_window) {
- _window->showWidget("prev", _scrollOffset > 0);
- _window->showWidget("next", scrollNeeded);
- }
-
- // go exclusive
- if (_shieldWindow) {
- _shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->_width;
- _shieldWindow->_height = _gameRef->_renderer->_height;
-
- _shieldWindow->display();
- }
-
- // display window
- if (_window) {
- _window->display();
- }
-
-
- // display response buttons
- for (i = _scrollOffset; i < _respButtons.size(); i++) {
- _respButtons[i]->display();
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::listen(BaseScriptHolder *param1, uint32 param2) {
- UIObject *obj = (UIObject *)param1;
-
- switch (obj->_type) {
- case UI_BUTTON:
- if (scumm_stricmp(obj->getName(), "prev") == 0) {
- _scrollOffset--;
- } else if (scumm_stricmp(obj->getName(), "next") == 0) {
- _scrollOffset++;
- } else if (scumm_stricmp(obj->getName(), "response") == 0) {
- if (_waitingScript) {
- _waitingScript->_stack->pushInt(_responses[param2]->_iD);
- }
- handleResponse(_responses[param2]);
- _waitingScript = NULL;
- _gameRef->_state = GAME_RUNNING;
- ((AdGame *)_gameRef)->_stateEx = GAME_NORMAL;
- _ready = true;
- invalidateButtons();
- clearResponses();
- } else {
- return BaseObject::listen(param1, param2);
- }
- break;
- default:
- error("AdResponseBox::Listen - Unhandled enum");
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::persist(BasePersistenceManager *persistMgr) {
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_font));
- persistMgr->transfer(TMEMBER(_fontHover));
- persistMgr->transfer(TMEMBER(_horizontal));
- persistMgr->transfer(TMEMBER(_lastResponseText));
- persistMgr->transfer(TMEMBER(_lastResponseTextOrig));
- _respButtons.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_responseArea));
- _responses.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_shieldWindow));
- persistMgr->transfer(TMEMBER(_spacing));
- persistMgr->transfer(TMEMBER(_waitingScript));
- persistMgr->transfer(TMEMBER(_window));
-
- persistMgr->transfer(TMEMBER_INT(_verticalAlign));
- persistMgr->transfer(TMEMBER_INT(_align));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::weedResponses() {
- AdGame *adGame = (AdGame *)_gameRef;
-
- for (uint32 i = 0; i < _responses.size(); i++) {
- switch (_responses[i]->_responseType) {
- case RESPONSE_ONCE:
- if (adGame->branchResponseUsed(_responses[i]->_iD)) {
- delete _responses[i];
- _responses.remove_at(i);
- i--;
- }
- break;
-
- case RESPONSE_ONCE_GAME:
- if (adGame->gameResponseUsed(_responses[i]->_iD)) {
- delete _responses[i];
- _responses.remove_at(i);
- i--;
- }
- break;
- default:
- debugC(kWintermuteDebugGeneral, "AdResponseBox::WeedResponses - Unhandled enum");
- break;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdResponseBox::setLastResponseText(const char *text, const char *textOrig) {
- BaseUtils::setString(&_lastResponseText, text);
- BaseUtils::setString(&_lastResponseTextOrig, textOrig);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::handleResponse(AdResponse *response) {
- setLastResponseText(response->_text, response->_textOrig);
-
- AdGame *adGame = (AdGame *)_gameRef;
-
- switch (response->_responseType) {
- case RESPONSE_ONCE:
- adGame->addBranchResponse(response->_iD);
- break;
-
- case RESPONSE_ONCE_GAME:
- adGame->addGameResponse(response->_iD);
- break;
- default:
- debugC(kWintermuteDebugGeneral, "AdResponseBox::HandleResponse - Unhandled enum");
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseObject *AdResponseBox::getNextAccessObject(BaseObject *currObject) {
- BaseArray<UIObject *> objects;
- getObjects(objects, true);
-
- if (objects.size() == 0) {
- return NULL;
- } else {
- if (currObject != NULL) {
- for (uint32 i = 0; i < objects.size(); i++) {
- if (objects[i] == currObject) {
- if (i < objects.size() - 1) {
- return objects[i + 1];
- } else {
- break;
- }
- }
- }
- }
- return objects[0];
- }
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseObject *AdResponseBox::getPrevAccessObject(BaseObject *currObject) {
- BaseArray<UIObject *> objects;
- getObjects(objects, true);
-
- if (objects.size() == 0) {
- return NULL;
- } else {
- if (currObject != NULL) {
- for (int i = objects.size() - 1; i >= 0; i--) {
- if (objects[i] == currObject) {
- if (i > 0) {
- return objects[i - 1];
- } else {
- break;
- }
- }
- }
- }
- return objects[objects.size() - 1];
- }
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly) {
- for (uint32 i = 0; i < _respButtons.size(); i++) {
- objects.add(_respButtons[i]);
- }
- if (_window) {
- _window->getWindowObjects(objects, interactiveOnly);
- }
-
- 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/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_response_box.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_surface_storage.h"
+#include "engines/wintermute/ui/ui_button.h"
+#include "engines/wintermute/ui/ui_window.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/ad/ad_response.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/wintermute.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdResponseBox, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdResponseBox::AdResponseBox(BaseGame *inGame) : BaseObject(inGame) {
+ _font = _fontHover = NULL;
+
+ _window = NULL;
+ _shieldWindow = new UIWindow(_gameRef);
+
+ _horizontal = false;
+ BasePlatform::setRectEmpty(&_responseArea);
+ _scrollOffset = 0;
+ _spacing = 0;
+
+ _waitingScript = NULL;
+ _lastResponseText = NULL;
+ _lastResponseTextOrig = NULL;
+
+ _verticalAlign = VAL_BOTTOM;
+ _align = TAL_LEFT;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdResponseBox::~AdResponseBox() {
+
+ delete _window;
+ _window = NULL;
+ delete _shieldWindow;
+ _shieldWindow = NULL;
+ delete[] _lastResponseText;
+ _lastResponseText = NULL;
+ delete[] _lastResponseTextOrig;
+ _lastResponseTextOrig = NULL;
+
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+ if (_fontHover) {
+ _gameRef->_fontStorage->removeFont(_fontHover);
+ }
+
+ clearResponses();
+ clearButtons();
+
+ _waitingScript = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdResponseBox::clearResponses() {
+ for (uint32 i = 0; i < _responses.size(); i++) {
+ delete _responses[i];
+ }
+ _responses.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdResponseBox::clearButtons() {
+ for (uint32 i = 0; i < _respButtons.size(); i++) {
+ delete _respButtons[i];
+ }
+ _respButtons.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::invalidateButtons() {
+ for (uint32 i = 0; i < _respButtons.size(); i++) {
+ _respButtons[i]->_image = NULL;
+ _respButtons[i]->_cursor = NULL;
+ _respButtons[i]->_font = NULL;
+ _respButtons[i]->_fontHover = NULL;
+ _respButtons[i]->_fontPress = NULL;
+ _respButtons[i]->setText("");
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::createButtons() {
+ clearButtons();
+
+ _scrollOffset = 0;
+ for (uint32 i = 0; i < _responses.size(); i++) {
+ UIButton *btn = new UIButton(_gameRef);
+ if (btn) {
+ btn->_parent = _window;
+ btn->_sharedFonts = btn->_sharedImages = true;
+ btn->_sharedCursors = true;
+ // iconic
+ if (_responses[i]->_icon) {
+ btn->_image = _responses[i]->_icon;
+ if (_responses[i]->_iconHover) {
+ btn->_imageHover = _responses[i]->_iconHover;
+ }
+ if (_responses[i]->_iconPressed) {
+ btn->_imagePress = _responses[i]->_iconPressed;
+ }
+
+ btn->setCaption(_responses[i]->_text);
+ if (_cursor) {
+ btn->_cursor = _cursor;
+ } else if (_gameRef->_activeCursor) {
+ btn->_cursor = _gameRef->_activeCursor;
+ }
+ }
+ // textual
+ else {
+ btn->setText(_responses[i]->_text);
+ btn->_font = (_font == NULL) ? _gameRef->_systemFont : _font;
+ btn->_fontHover = (_fontHover == NULL) ? _gameRef->_systemFont : _fontHover;
+ btn->_fontPress = btn->_fontHover;
+ btn->_align = _align;
+
+ if (_gameRef->_touchInterface) {
+ btn->_fontHover = btn->_font;
+ }
+
+
+ if (_responses[i]->_font) {
+ btn->_font = _responses[i]->_font;
+ }
+
+ btn->_width = _responseArea.right - _responseArea.left;
+ if (btn->_width <= 0) {
+ btn->_width = _gameRef->_renderer->_width;
+ }
+ }
+ btn->setName("response");
+ btn->correctSize();
+
+ // make the responses touchable
+ if (_gameRef->_touchInterface) {
+ btn->_height = MAX(btn->_height, 50);
+ }
+
+ //btn->SetListener(this, btn, _responses[i]->_iD);
+ btn->setListener(this, btn, i);
+ btn->_visible = false;
+ _respButtons.add(btn);
+
+ if (_responseArea.bottom - _responseArea.top < btn->_height) {
+ _gameRef->LOG(0, "Warning: Response '%s' is too high to be displayed within response box. Correcting.", _responses[i]->_text);
+ _responseArea.bottom += (btn->_height - (_responseArea.bottom - _responseArea.top));
+ }
+ }
+ }
+ _ready = false;
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdResponseBox::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing RESPONSE_BOX file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(RESPONSE_BOX)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(FONT_HOVER)
+TOKEN_DEF(FONT)
+TOKEN_DEF(AREA)
+TOKEN_DEF(HORIZONTAL)
+TOKEN_DEF(SPACING)
+TOKEN_DEF(WINDOW)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(TEXT_ALIGN)
+TOKEN_DEF(VERTICAL_ALIGN)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(RESPONSE_BOX)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(FONT_HOVER)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(AREA)
+ TOKEN_TABLE(HORIZONTAL)
+ TOKEN_TABLE(SPACING)
+ TOKEN_TABLE(WINDOW)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(TEXT_ALIGN)
+ TOKEN_TABLE(VERTICAL_ALIGN)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_RESPONSE_BOX) {
+ _gameRef->LOG(0, "'RESPONSE_BOX' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_WINDOW:
+ delete _window;
+ _window = new UIWindow(_gameRef);
+ if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
+ delete _window;
+ _window = NULL;
+ cmd = PARSERR_GENERIC;
+ } else if (_shieldWindow) {
+ _shieldWindow->_parent = _window;
+ }
+ break;
+
+ case TOKEN_FONT:
+ if (_font) {
+ _gameRef->_fontStorage->removeFont(_font);
+ }
+ _font = _gameRef->_fontStorage->addFont((char *)params);
+ if (!_font) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_FONT_HOVER:
+ if (_fontHover) {
+ _gameRef->_fontStorage->removeFont(_fontHover);
+ }
+ _fontHover = _gameRef->_fontStorage->addFont((char *)params);
+ if (!_fontHover) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_AREA:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
+ break;
+
+ case TOKEN_HORIZONTAL:
+ parser.scanStr((char *)params, "%b", &_horizontal);
+ break;
+
+ case TOKEN_TEXT_ALIGN:
+ if (scumm_stricmp((char *)params, "center") == 0) {
+ _align = TAL_CENTER;
+ } else if (scumm_stricmp((char *)params, "right") == 0) {
+ _align = TAL_RIGHT;
+ } else {
+ _align = TAL_LEFT;
+ }
+ break;
+
+ case TOKEN_VERTICAL_ALIGN:
+ if (scumm_stricmp((char *)params, "top") == 0) {
+ _verticalAlign = VAL_TOP;
+ } else if (scumm_stricmp((char *)params, "center") == 0) {
+ _verticalAlign = VAL_CENTER;
+ } else {
+ _verticalAlign = VAL_BOTTOM;
+ }
+ break;
+
+ case TOKEN_SPACING:
+ parser.scanStr((char *)params, "%d", &_spacing);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+
+ case TOKEN_CURSOR:
+ delete _cursor;
+ _cursor = new BaseSprite(_gameRef);
+ if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ delete _cursor;
+ _cursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in RESPONSE_BOX definition");
+ return STATUS_FAILED;
+ }
+
+ if (_window) {
+ for (uint32 i = 0; i < _window->_widgets.size(); i++) {
+ if (!_window->_widgets[i]->_listenerObject) {
+ _window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "RESPONSE_BOX\n");
+ buffer->putTextIndent(indent, "{\n");
+
+ buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _responseArea.left, _responseArea.top, _responseArea.right, _responseArea.bottom);
+
+ if (_font && _font->getFilename()) {
+ buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename());
+ }
+ if (_fontHover && _fontHover->getFilename()) {
+ buffer->putTextIndent(indent + 2, "FONT_HOVER=\"%s\"\n", _fontHover->getFilename());
+ }
+
+ if (_cursor && _cursor->getFilename()) {
+ buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename());
+ }
+
+ buffer->putTextIndent(indent + 2, "HORIZONTAL=%s\n", _horizontal ? "TRUE" : "FALSE");
+
+ switch (_align) {
+ case TAL_LEFT:
+ buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "left");
+ break;
+ case TAL_RIGHT:
+ buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "right");
+ break;
+ case TAL_CENTER:
+ buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "center");
+ break;
+ default:
+ error("AdResponseBox::SaveAsText - Unhandled enum");
+ break;
+ }
+
+ switch (_verticalAlign) {
+ case VAL_TOP:
+ buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "top");
+ break;
+ case VAL_BOTTOM:
+ buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "bottom");
+ break;
+ case VAL_CENTER:
+ buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "center");
+ break;
+ }
+
+ buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // window
+ if (_window) {
+ _window->saveAsText(buffer, indent + 2);
+ }
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // editor properties
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n");
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::display() {
+ Rect32 rect = _responseArea;
+ if (_window) {
+ rect.offsetRect(_window->_posX, _window->_posY);
+ //_window->display();
+ }
+
+ int xxx, yyy;
+ uint32 i;
+
+ xxx = rect.left;
+ yyy = rect.top;
+
+ // shift down if needed
+ if (!_horizontal) {
+ int totalHeight = 0;
+ for (i = 0; i < _respButtons.size(); i++) {
+ totalHeight += (_respButtons[i]->_height + _spacing);
+ }
+ totalHeight -= _spacing;
+
+ switch (_verticalAlign) {
+ case VAL_BOTTOM:
+ if (yyy + totalHeight < rect.bottom) {
+ yyy = rect.bottom - totalHeight;
+ }
+ break;
+
+ case VAL_CENTER:
+ if (yyy + totalHeight < rect.bottom) {
+ yyy += ((rect.bottom - rect.top) - totalHeight) / 2;
+ }
+ break;
+
+ case VAL_TOP:
+ // do nothing
+ break;
+ }
+ }
+
+ // prepare response buttons
+ bool scrollNeeded = false;
+ for (i = _scrollOffset; i < _respButtons.size(); i++) {
+ if ((_horizontal && xxx + _respButtons[i]->_width > rect.right)
+ || (!_horizontal && yyy + _respButtons[i]->_height > rect.bottom)) {
+
+ scrollNeeded = true;
+ _respButtons[i]->_visible = false;
+ break;
+ }
+
+ _respButtons[i]->_visible = true;
+ _respButtons[i]->_posX = xxx;
+ _respButtons[i]->_posY = yyy;
+
+ if (_horizontal) {
+ xxx += (_respButtons[i]->_width + _spacing);
+ } else {
+ yyy += (_respButtons[i]->_height + _spacing);
+ }
+ }
+
+ // show appropriate scroll buttons
+ if (_window) {
+ _window->showWidget("prev", _scrollOffset > 0);
+ _window->showWidget("next", scrollNeeded);
+ }
+
+ // go exclusive
+ if (_shieldWindow) {
+ _shieldWindow->_posX = _shieldWindow->_posY = 0;
+ _shieldWindow->_width = _gameRef->_renderer->_width;
+ _shieldWindow->_height = _gameRef->_renderer->_height;
+
+ _shieldWindow->display();
+ }
+
+ // display window
+ if (_window) {
+ _window->display();
+ }
+
+
+ // display response buttons
+ for (i = _scrollOffset; i < _respButtons.size(); i++) {
+ _respButtons[i]->display();
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::listen(BaseScriptHolder *param1, uint32 param2) {
+ UIObject *obj = (UIObject *)param1;
+
+ switch (obj->_type) {
+ case UI_BUTTON:
+ if (scumm_stricmp(obj->getName(), "prev") == 0) {
+ _scrollOffset--;
+ } else if (scumm_stricmp(obj->getName(), "next") == 0) {
+ _scrollOffset++;
+ } else if (scumm_stricmp(obj->getName(), "response") == 0) {
+ if (_waitingScript) {
+ _waitingScript->_stack->pushInt(_responses[param2]->_iD);
+ }
+ handleResponse(_responses[param2]);
+ _waitingScript = NULL;
+ _gameRef->_state = GAME_RUNNING;
+ ((AdGame *)_gameRef)->_stateEx = GAME_NORMAL;
+ _ready = true;
+ invalidateButtons();
+ clearResponses();
+ } else {
+ return BaseObject::listen(param1, param2);
+ }
+ break;
+ default:
+ error("AdResponseBox::Listen - Unhandled enum");
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::persist(BasePersistenceManager *persistMgr) {
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_font));
+ persistMgr->transfer(TMEMBER(_fontHover));
+ persistMgr->transfer(TMEMBER(_horizontal));
+ persistMgr->transfer(TMEMBER(_lastResponseText));
+ persistMgr->transfer(TMEMBER(_lastResponseTextOrig));
+ _respButtons.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_responseArea));
+ _responses.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transfer(TMEMBER(_shieldWindow));
+ persistMgr->transfer(TMEMBER(_spacing));
+ persistMgr->transfer(TMEMBER(_waitingScript));
+ persistMgr->transfer(TMEMBER(_window));
+
+ persistMgr->transfer(TMEMBER_INT(_verticalAlign));
+ persistMgr->transfer(TMEMBER_INT(_align));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::weedResponses() {
+ AdGame *adGame = (AdGame *)_gameRef;
+
+ for (uint32 i = 0; i < _responses.size(); i++) {
+ switch (_responses[i]->_responseType) {
+ case RESPONSE_ONCE:
+ if (adGame->branchResponseUsed(_responses[i]->_iD)) {
+ delete _responses[i];
+ _responses.remove_at(i);
+ i--;
+ }
+ break;
+
+ case RESPONSE_ONCE_GAME:
+ if (adGame->gameResponseUsed(_responses[i]->_iD)) {
+ delete _responses[i];
+ _responses.remove_at(i);
+ i--;
+ }
+ break;
+ default:
+ debugC(kWintermuteDebugGeneral, "AdResponseBox::WeedResponses - Unhandled enum");
+ break;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdResponseBox::setLastResponseText(const char *text, const char *textOrig) {
+ BaseUtils::setString(&_lastResponseText, text);
+ BaseUtils::setString(&_lastResponseTextOrig, textOrig);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::handleResponse(AdResponse *response) {
+ setLastResponseText(response->_text, response->_textOrig);
+
+ AdGame *adGame = (AdGame *)_gameRef;
+
+ switch (response->_responseType) {
+ case RESPONSE_ONCE:
+ adGame->addBranchResponse(response->_iD);
+ break;
+
+ case RESPONSE_ONCE_GAME:
+ adGame->addGameResponse(response->_iD);
+ break;
+ default:
+ debugC(kWintermuteDebugGeneral, "AdResponseBox::HandleResponse - Unhandled enum");
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseObject *AdResponseBox::getNextAccessObject(BaseObject *currObject) {
+ BaseArray<UIObject *> objects;
+ getObjects(objects, true);
+
+ if (objects.size() == 0) {
+ return NULL;
+ } else {
+ if (currObject != NULL) {
+ for (uint32 i = 0; i < objects.size(); i++) {
+ if (objects[i] == currObject) {
+ if (i < objects.size() - 1) {
+ return objects[i + 1];
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ return objects[0];
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseObject *AdResponseBox::getPrevAccessObject(BaseObject *currObject) {
+ BaseArray<UIObject *> objects;
+ getObjects(objects, true);
+
+ if (objects.size() == 0) {
+ return NULL;
+ } else {
+ if (currObject != NULL) {
+ for (int i = objects.size() - 1; i >= 0; i--) {
+ if (objects[i] == currObject) {
+ if (i > 0) {
+ return objects[i - 1];
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ return objects[objects.size() - 1];
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseBox::getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly) {
+ for (uint32 i = 0; i < _respButtons.size(); i++) {
+ objects.add(_respButtons[i]);
+ }
+ if (_window) {
+ _window->getWindowObjects(objects, interactiveOnly);
+ }
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response_box.h b/engines/wintermute/ad/ad_response_box.h
index 8c76b561c6..35f8cb6347 100644
--- a/engines/wintermute/ad/ad_response_box.h
+++ b/engines/wintermute/ad/ad_response_box.h
@@ -1,87 +1,87 @@
-/* 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_ADRESPONSEBOX_H
-#define WINTERMUTE_ADRESPONSEBOX_H
-
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class UIButton;
-class UIWindow;
-class UIObject;
-class AdResponse;
-class AdResponseBox : public BaseObject {
-public:
- BaseObject *getNextAccessObject(BaseObject *CurrObject);
- BaseObject *getPrevAccessObject(BaseObject *CurrObject);
- bool getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly);
-
- bool handleResponse(AdResponse *response);
- void setLastResponseText(const char *text, const char *textOrig);
- char *_lastResponseText;
- char *_lastResponseTextOrig;
- DECLARE_PERSISTENT(AdResponseBox, BaseObject)
- ScScript *_waitingScript;
- virtual bool listen(BaseScriptHolder *param1, uint32 param2);
- typedef enum {
- EVENT_PREV,
- EVENT_NEXT,
- EVENT_RESPONSE
- } TResponseEvent;
-
- bool weedResponses();
- bool display();
- int _spacing;
- int _scrollOffset;
- BaseFont *_fontHover;
- BaseFont *_font;
- bool createButtons();
- bool invalidateButtons();
- void clearButtons();
- void clearResponses();
- AdResponseBox(BaseGame *inGame);
- virtual ~AdResponseBox();
- BaseArray<AdResponse *> _responses;
- BaseArray<UIButton *> _respButtons;
- UIWindow *_window;
- UIWindow *_shieldWindow;
- bool _horizontal;
- Rect32 _responseArea;
- int _verticalAlign;
- TTextAlign _align;
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
-};
-
-} // 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_ADRESPONSEBOX_H
+#define WINTERMUTE_ADRESPONSEBOX_H
+
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class UIButton;
+class UIWindow;
+class UIObject;
+class AdResponse;
+class AdResponseBox : public BaseObject {
+public:
+ BaseObject *getNextAccessObject(BaseObject *CurrObject);
+ BaseObject *getPrevAccessObject(BaseObject *CurrObject);
+ bool getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly);
+
+ bool handleResponse(AdResponse *response);
+ void setLastResponseText(const char *text, const char *textOrig);
+ char *_lastResponseText;
+ char *_lastResponseTextOrig;
+ DECLARE_PERSISTENT(AdResponseBox, BaseObject)
+ ScScript *_waitingScript;
+ virtual bool listen(BaseScriptHolder *param1, uint32 param2);
+ typedef enum {
+ EVENT_PREV,
+ EVENT_NEXT,
+ EVENT_RESPONSE
+ } TResponseEvent;
+
+ bool weedResponses();
+ bool display();
+ int _spacing;
+ int _scrollOffset;
+ BaseFont *_fontHover;
+ BaseFont *_font;
+ bool createButtons();
+ bool invalidateButtons();
+ void clearButtons();
+ void clearResponses();
+ AdResponseBox(BaseGame *inGame);
+ virtual ~AdResponseBox();
+ BaseArray<AdResponse *> _responses;
+ BaseArray<UIButton *> _respButtons;
+ UIWindow *_window;
+ UIWindow *_shieldWindow;
+ bool _horizontal;
+ Rect32 _responseArea;
+ int _verticalAlign;
+ TTextAlign _align;
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_response_context.cpp b/engines/wintermute/ad/ad_response_context.cpp
index 0a2eff842d..ebfa03feea 100644
--- a/engines/wintermute/ad/ad_response_context.cpp
+++ b/engines/wintermute/ad/ad_response_context.cpp
@@ -1,71 +1,71 @@
-/* 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/ad/ad_response_context.h"
-#include "engines/wintermute/base/base_persistence_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdResponseContext, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdResponseContext::AdResponseContext(BaseGame *inGame) : BaseClass(inGame) {
- _id = 0;
- _context = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdResponseContext::~AdResponseContext() {
- delete[] _context;
- _context = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdResponseContext::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_gameRef));
- persistMgr->transfer(TMEMBER(_context));
- persistMgr->transfer(TMEMBER(_id));
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void AdResponseContext::setContext(const char *context) {
- delete[] _context;
- _context = NULL;
- if (context) {
- _context = new char [strlen(context) + 1];
- if (_context) {
- strcpy(_context, context);
- }
- }
-}
-
-} // 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/ad/ad_response_context.h"
+#include "engines/wintermute/base/base_persistence_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdResponseContext, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdResponseContext::AdResponseContext(BaseGame *inGame) : BaseClass(inGame) {
+ _id = 0;
+ _context = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdResponseContext::~AdResponseContext() {
+ delete[] _context;
+ _context = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdResponseContext::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_gameRef));
+ persistMgr->transfer(TMEMBER(_context));
+ persistMgr->transfer(TMEMBER(_id));
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AdResponseContext::setContext(const char *context) {
+ delete[] _context;
+ _context = NULL;
+ if (context) {
+ _context = new char [strlen(context) + 1];
+ if (_context) {
+ strcpy(_context, context);
+ }
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response_context.h b/engines/wintermute/ad/ad_response_context.h
index a630f975e4..14bc1abd93 100644
--- a/engines/wintermute/ad/ad_response_context.h
+++ b/engines/wintermute/ad/ad_response_context.h
@@ -1,50 +1,50 @@
-/* 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_ADRESPONSECONTEXT_H
-#define WINTERMUTE_ADRESPONSECONTEXT_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/base/base.h"
-
-namespace Wintermute {
-
-class AdResponseContext : public BaseClass {
-public:
- void setContext(const char *context);
- int _id;
- char *_context;
- DECLARE_PERSISTENT(AdResponseContext, BaseClass)
- AdResponseContext(BaseGame *inGame);
- virtual ~AdResponseContext();
-
-};
-
-} // 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_ADRESPONSECONTEXT_H
+#define WINTERMUTE_ADRESPONSECONTEXT_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/base/base.h"
+
+namespace Wintermute {
+
+class AdResponseContext : public BaseClass {
+public:
+ void setContext(const char *context);
+ int _id;
+ char *_context;
+ DECLARE_PERSISTENT(AdResponseContext, BaseClass)
+ AdResponseContext(BaseGame *inGame);
+ virtual ~AdResponseContext();
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_rot_level.cpp b/engines/wintermute/ad/ad_rot_level.cpp
index 487e1f7067..ca7ed693ad 100644
--- a/engines/wintermute/ad/ad_rot_level.cpp
+++ b/engines/wintermute/ad/ad_rot_level.cpp
@@ -1,161 +1,161 @@
-/* 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/ad/ad_rot_level.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_file_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdRotLevel, false)
-
-
-//////////////////////////////////////////////////////////////////////////
-AdRotLevel::AdRotLevel(BaseGame *inGame) : BaseObject(inGame) {
- _posX = 0;
- _rotation = 0.0f;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdRotLevel::~AdRotLevel() {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdRotLevel::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing ROTATION_LEVEL file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(ROTATION_LEVEL)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(X)
-TOKEN_DEF(ROTATION)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ROTATION_LEVEL)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(X)
- TOKEN_TABLE(ROTATION)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ROTATION_LEVEL) {
- _gameRef->LOG(0, "'ROTATION_LEVEL' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
- break;
-
- case TOKEN_ROTATION: {
- int i;
- parser.scanStr((char *)params, "%d", &i);
- _rotation = (float)i;
- }
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ROTATION_LEVEL definition");
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "ROTATION_LEVEL {\n");
- buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
- buffer->putTextIndent(indent + 2, "ROTATION=%d\n", (int)_rotation);
- BaseClass::saveAsText(buffer, indent + 2);
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_rotation));
-
- 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/ad/ad_rot_level.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_file_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdRotLevel, false)
+
+
+//////////////////////////////////////////////////////////////////////////
+AdRotLevel::AdRotLevel(BaseGame *inGame) : BaseObject(inGame) {
+ _posX = 0;
+ _rotation = 0.0f;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdRotLevel::~AdRotLevel() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRotLevel::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdRotLevel::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing ROTATION_LEVEL file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(ROTATION_LEVEL)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(X)
+TOKEN_DEF(ROTATION)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ROTATION_LEVEL)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(X)
+ TOKEN_TABLE(ROTATION)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ROTATION_LEVEL) {
+ _gameRef->LOG(0, "'ROTATION_LEVEL' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_X:
+ parser.scanStr((char *)params, "%d", &_posX);
+ break;
+
+ case TOKEN_ROTATION: {
+ int i;
+ parser.scanStr((char *)params, "%d", &i);
+ _rotation = (float)i;
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ROTATION_LEVEL definition");
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRotLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "ROTATION_LEVEL {\n");
+ buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
+ buffer->putTextIndent(indent + 2, "ROTATION=%d\n", (int)_rotation);
+ BaseClass::saveAsText(buffer, indent + 2);
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdRotLevel::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_rotation));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_rot_level.h b/engines/wintermute/ad/ad_rot_level.h
index 7951c7562d..d7f5f8edf0 100644
--- a/engines/wintermute/ad/ad_rot_level.h
+++ b/engines/wintermute/ad/ad_rot_level.h
@@ -1,49 +1,49 @@
-/* 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_ADROTLEVEL_H
-#define WINTERMUTE_ADROTLEVEL_H
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class AdRotLevel : public BaseObject {
-public:
- DECLARE_PERSISTENT(AdRotLevel, BaseObject)
- AdRotLevel(BaseGame *inGame);
- virtual ~AdRotLevel();
- float _rotation;
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
-};
-
-} // 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_ADROTLEVEL_H
+#define WINTERMUTE_ADROTLEVEL_H
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class AdRotLevel : public BaseObject {
+public:
+ DECLARE_PERSISTENT(AdRotLevel, BaseObject)
+ AdRotLevel(BaseGame *inGame);
+ virtual ~AdRotLevel();
+ float _rotation;
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_scale_level.cpp b/engines/wintermute/ad/ad_scale_level.cpp
index f3ec68dd64..8b68cc5d32 100644
--- a/engines/wintermute/ad/ad_scale_level.cpp
+++ b/engines/wintermute/ad/ad_scale_level.cpp
@@ -1,159 +1,159 @@
-/* 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/ad/ad_scale_level.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_file_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdScaleLevel, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdScaleLevel::AdScaleLevel(BaseGame *inGame) : BaseObject(inGame) {
- _posY = 0;
- _scale = 100;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdScaleLevel::~AdScaleLevel() {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing SCALE_LEVEL file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(SCALE_LEVEL)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(Y)
-TOKEN_DEF(SCALE)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(SCALE_LEVEL)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(Y)
- TOKEN_TABLE(SCALE)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCALE_LEVEL) {
- _gameRef->LOG(0, "'SCALE_LEVEL' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
- break;
-
- case TOKEN_SCALE: {
- int i;
- parser.scanStr((char *)params, "%d", &i);
- _scale = (float)i;
- }
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in SCALE_LEVEL definition");
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "SCALE_LEVEL {\n");
- buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
- buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_scale);
- BaseClass::saveAsText(buffer, indent + 2);
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_scale));
-
- 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/ad/ad_scale_level.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_file_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdScaleLevel, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdScaleLevel::AdScaleLevel(BaseGame *inGame) : BaseObject(inGame) {
+ _posY = 0;
+ _scale = 100;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdScaleLevel::~AdScaleLevel() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScaleLevel::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing SCALE_LEVEL file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(SCALE_LEVEL)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(Y)
+TOKEN_DEF(SCALE)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(SCALE_LEVEL)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(Y)
+ TOKEN_TABLE(SCALE)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCALE_LEVEL) {
+ _gameRef->LOG(0, "'SCALE_LEVEL' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_Y:
+ parser.scanStr((char *)params, "%d", &_posY);
+ break;
+
+ case TOKEN_SCALE: {
+ int i;
+ parser.scanStr((char *)params, "%d", &i);
+ _scale = (float)i;
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in SCALE_LEVEL definition");
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScaleLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "SCALE_LEVEL {\n");
+ buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
+ buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_scale);
+ BaseClass::saveAsText(buffer, indent + 2);
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScaleLevel::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_scale));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scale_level.h b/engines/wintermute/ad/ad_scale_level.h
index 41a2edf8c5..628a385eb4 100644
--- a/engines/wintermute/ad/ad_scale_level.h
+++ b/engines/wintermute/ad/ad_scale_level.h
@@ -1,50 +1,50 @@
-/* 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_ADSCALELEVEL_H
-#define WINTERMUTE_ADSCALELEVEL_H
-
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-
-class AdScaleLevel : public BaseObject {
-public:
- DECLARE_PERSISTENT(AdScaleLevel, BaseObject)
- float _scale;
- AdScaleLevel(BaseGame *inGame);
- virtual ~AdScaleLevel();
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
-};
-
-} // 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_ADSCALELEVEL_H
+#define WINTERMUTE_ADSCALELEVEL_H
+
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+
+class AdScaleLevel : public BaseObject {
+public:
+ DECLARE_PERSISTENT(AdScaleLevel, BaseObject)
+ float _scale;
+ AdScaleLevel(BaseGame *inGame);
+ virtual ~AdScaleLevel();
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_scene.cpp b/engines/wintermute/ad/ad_scene.cpp
index f67252350e..e47acc63c9 100644
--- a/engines/wintermute/ad/ad_scene.cpp
+++ b/engines/wintermute/ad/ad_scene.cpp
@@ -1,2986 +1,2986 @@
-/* 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/ad/ad_scene.h"
-#include "engines/wintermute/ad/ad_actor.h"
-#include "engines/wintermute/ad/ad_entity.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/ad/ad_layer.h"
-#include "engines/wintermute/ad/ad_node_state.h"
-#include "engines/wintermute/ad/ad_object.h"
-#include "engines/wintermute/ad/ad_path.h"
-#include "engines/wintermute/ad/ad_path_point.h"
-#include "engines/wintermute/ad/ad_rot_level.h"
-#include "engines/wintermute/ad/ad_scale_level.h"
-#include "engines/wintermute/ad/ad_scene_node.h"
-#include "engines/wintermute/ad/ad_scene_state.h"
-#include "engines/wintermute/ad/ad_sentence.h"
-#include "engines/wintermute/ad/ad_waypoint_group.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_object.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_point.h"
-#include "engines/wintermute/base/base_region.h"
-#include "engines/wintermute/base/base_scriptable.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_viewport.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/ui/ui_window.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/wintermute.h"
-#include <limits.h>
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdScene, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdScene::AdScene(BaseGame *inGame) : BaseObject(inGame) {
- _pfTarget = new BasePoint;
- setDefaults();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdScene::~AdScene() {
- cleanup();
- _gameRef->unregisterObject(_fader);
- delete _pfTarget;
- _pfTarget = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::setDefaults() {
- _initialized = false;
- _pfReady = true;
- _pfTargetPath = NULL;
- _pfRequester = NULL;
- _mainLayer = NULL;
-
- _pfPointsNum = 0;
- _persistentState = false;
- _persistentStateSprites = true;
-
- _autoScroll = true;
- _offsetLeft = _offsetTop = 0;
- _targetOffsetLeft = _targetOffsetTop = 0;
-
- _lastTimeH = _lastTimeV = 0;
- _scrollTimeH = _scrollTimeV = 10;
- _scrollPixelsH = _scrollPixelsV = 1;
-
- _pfMaxTime = 15;
-
- _paralaxScrolling = true;
-
- // editor settings
- _editorMarginH = _editorMarginV = 100;
-
- _editorColFrame = 0xE0888888;
- _editorColEntity = 0xFF008000;
- _editorColRegion = 0xFF0000FF;
- _editorColBlocked = 0xFF800080;
- _editorColWaypoints = 0xFF0000FF;
- _editorColEntitySel = 0xFFFF0000;
- _editorColRegionSel = 0xFFFF0000;
- _editorColBlockedSel = 0xFFFF0000;
- _editorColWaypointsSel = 0xFFFF0000;
- _editorColScale = 0xFF00FF00;
- _editorColDecor = 0xFF00FFFF;
- _editorColDecorSel = 0xFFFF0000;
-
- _editorShowRegions = true;
- _editorShowBlocked = true;
- _editorShowDecor = true;
- _editorShowEntities = true;
- _editorShowScale = true;
-
- _shieldWindow = NULL;
-
- _fader = new BaseFader(_gameRef);
- _gameRef->registerObject(_fader);
-
- _viewport = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::cleanup() {
- BaseObject::cleanup();
-
- _mainLayer = NULL; // reference only
-
- delete _shieldWindow;
- _shieldWindow = NULL;
-
- _gameRef->unregisterObject(_fader);
- _fader = NULL;
-
- for (uint32 i = 0; i < _layers.size(); i++) {
- _gameRef->unregisterObject(_layers[i]);
- }
- _layers.clear();
-
-
- for (uint32 i = 0; i < _waypointGroups.size(); i++) {
- _gameRef->unregisterObject(_waypointGroups[i]);
- }
- _waypointGroups.clear();
-
- for (uint32 i = 0; i < _scaleLevels.size(); i++) {
- _gameRef->unregisterObject(_scaleLevels[i]);
- }
- _scaleLevels.clear();
-
- for (uint32 i = 0; i < _rotLevels.size(); i++) {
- _gameRef->unregisterObject(_rotLevels[i]);
- }
- _rotLevels.clear();
-
-
- for (uint32 i = 0; i < _pfPath.size(); i++) {
- delete _pfPath[i];
- }
- _pfPath.clear();
- _pfPointsNum = 0;
-
- for (uint32 i = 0; i < _objects.size(); i++) {
- _gameRef->unregisterObject(_objects[i]);
- }
- _objects.clear();
-
- delete _viewport;
- _viewport = NULL;
-
- setDefaults();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getPath(BasePoint source, BasePoint target, AdPath *path, BaseObject *requester) {
- if (!_pfReady) {
- return false;
- } else {
- _pfReady = false;
- *_pfTarget = target;
- _pfTargetPath = path;
- _pfRequester = requester;
-
- _pfTargetPath->reset();
- _pfTargetPath->setReady(false);
-
- // prepare working path
- pfPointsStart();
-
- // first point
- //_pfPath.add(new AdPathPoint(source.x, source.y, 0));
-
- // if we're one pixel stuck, get unstuck
- int startX = source.x;
- int startY = source.y;
- int bestDistance = 1000;
- if (isBlockedAt(startX, startY, true, requester)) {
- int tolerance = 2;
- for (int xxx = startX - tolerance; xxx <= startX + tolerance; xxx++) {
- for (int yyy = startY - tolerance; yyy <= startY + tolerance; yyy++) {
- if (isWalkableAt(xxx, yyy, true, requester)) {
- int distance = abs(xxx - source.x) + abs(yyy - source.y);
- if (distance < bestDistance) {
- startX = xxx;
- startY = yyy;
-
- bestDistance = distance;
- }
- }
- }
- }
- }
-
- pfPointsAdd(startX, startY, 0);
-
- //CorrectTargetPoint(&target.x, &target.y);
-
- // last point
- //_pfPath.add(new AdPathPoint(target.x, target.y, INT_MAX));
- pfPointsAdd(target.x, target.y, INT_MAX);
-
- // active waypoints
- for (uint32 i = 0; i < _waypointGroups.size(); i++) {
- if (_waypointGroups[i]->_active) {
- pfAddWaypointGroup(_waypointGroups[i], requester);
- }
- }
-
-
- // free waypoints
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentWptGroup) {
- pfAddWaypointGroup(_objects[i]->_currentWptGroup, requester);
- }
- }
- AdGame *adGame = (AdGame *)_gameRef;
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentWptGroup) {
- pfAddWaypointGroup(adGame->_objects[i]->_currentWptGroup, requester);
- }
- }
-
- return true;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::pfAddWaypointGroup(AdWaypointGroup *wpt, BaseObject *requester) {
- if (!wpt->_active) {
- return;
- }
-
- for (uint32 i = 0; i < wpt->_points.size(); i++) {
- if (isBlockedAt(wpt->_points[i]->x, wpt->_points[i]->y, true, requester)) {
- continue;
- }
-
- //_pfPath.add(new AdPathPoint(Wpt->_points[i]->x, Wpt->_points[i]->y, INT_MAX));
- pfPointsAdd(wpt->_points[i]->x, wpt->_points[i]->y, INT_MAX);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-float AdScene::getZoomAt(int x, int y) {
- float ret = 100;
-
- bool found = false;
- if (_mainLayer) {
- for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_blocked && node->_region->pointInRegion(x, y)) {
- if (node->_region->_zoom != 0) {
- ret = node->_region->_zoom;
- found = true;
- break;
- }
- }
- }
- }
- if (!found) {
- ret = getScaleAt(y);
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-uint32 AdScene::getAlphaAt(int x, int y, bool colorCheck) {
- if (!_gameRef->_debugDebugMode) {
- colorCheck = false;
- }
-
- uint32 ret;
- if (colorCheck) {
- ret = 0xFFFF0000;
- } else {
- ret = 0xFFFFFFFF;
- }
-
- if (_mainLayer) {
- for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- if (node->_type == OBJECT_REGION && node->_region->_active && (colorCheck || !node->_region->_blocked) && node->_region->pointInRegion(x, y)) {
- if (!node->_region->_blocked) {
- ret = node->_region->_alpha;
- }
- break;
- }
- }
- }
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::isBlockedAt(int x, int y, bool checkFreeObjects, BaseObject *requester) {
- bool ret = true;
-
- if (checkFreeObjects) {
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentBlockRegion) {
- if (_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
- return true;
- }
- }
- }
- AdGame *adGame = (AdGame *)_gameRef;
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentBlockRegion) {
- if (adGame->_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
- return true;
- }
- }
- }
- }
-
-
- if (_mainLayer) {
- for (uint32 i = 0; i < _mainLayer->_nodes.size(); i++) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- /*
- if (Node->_type == OBJECT_REGION && Node->_region->_active && Node->_region->_blocked && Node->_region->PointInRegion(X, Y))
- {
- ret = true;
- break;
- }
- */
- if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_decoration && node->_region->pointInRegion(x, y)) {
- if (node->_region->_blocked) {
- ret = true;
- break;
- } else {
- ret = false;
- }
- }
- }
- }
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::isWalkableAt(int x, int y, bool checkFreeObjects, BaseObject *requester) {
- bool ret = false;
-
- if (checkFreeObjects) {
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentBlockRegion) {
- if (_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
- return false;
- }
- }
- }
- AdGame *adGame = (AdGame *)_gameRef;
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentBlockRegion) {
- if (adGame->_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
- return false;
- }
- }
- }
- }
-
-
- if (_mainLayer) {
- for (uint32 i = 0; i < _mainLayer->_nodes.size(); i++) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_decoration && node->_region->pointInRegion(x, y)) {
- if (node->_region->_blocked) {
- ret = false;
- break;
- } else {
- ret = true;
- }
- }
- }
- }
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdScene::getPointsDist(BasePoint p1, BasePoint p2, BaseObject *requester) {
- double xStep, yStep, x, y;
- int xLength, yLength, xCount, yCount;
- int x1, y1, x2, y2;
-
- x1 = p1.x;
- y1 = p1.y;
- x2 = p2.x;
- y2 = p2.y;
-
- xLength = abs(x2 - x1);
- yLength = abs(y2 - y1);
-
- if (xLength > yLength) {
- if (x1 > x2) {
- BaseUtils::swap(&x1, &x2);
- BaseUtils::swap(&y1, &y2);
- }
-
- yStep = (double)(y2 - y1) / (double)(x2 - x1);
- y = y1;
-
- for (xCount = x1; xCount < x2; xCount++) {
- if (isBlockedAt(xCount, (int)y, true, requester)) {
- return -1;
- }
- y += yStep;
- }
- } else {
- if (y1 > y2) {
- BaseUtils::swap(&x1, &x2);
- BaseUtils::swap(&y1, &y2);
- }
-
- xStep = (double)(x2 - x1) / (double)(y2 - y1);
- x = x1;
-
- for (yCount = y1; yCount < y2; yCount++) {
- if (isBlockedAt((int)x, yCount, true, requester)) {
- return -1;
- }
- x += xStep;
- }
- }
- return MAX(xLength, yLength);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::pathFinderStep() {
- int i;
- // get lowest unmarked
- int lowestDist = INT_MAX;
- AdPathPoint *lowestPt = NULL;
-
- for (i = 0; i < _pfPointsNum; i++)
- if (!_pfPath[i]->_marked && _pfPath[i]->_distance < lowestDist) {
- lowestDist = _pfPath[i]->_distance;
- lowestPt = _pfPath[i];
- }
-
- if (lowestPt == NULL) { // no path -> terminate PathFinder
- _pfReady = true;
- _pfTargetPath->setReady(true);
- return;
- }
-
- lowestPt->_marked = true;
-
- // target point marked, generate path and terminate
- if (lowestPt->x == _pfTarget->x && lowestPt->y == _pfTarget->y) {
- while (lowestPt != NULL) {
- _pfTargetPath->_points.insert_at(0, new BasePoint(lowestPt->x, lowestPt->y));
- lowestPt = lowestPt->_origin;
- }
-
- _pfReady = true;
- _pfTargetPath->setReady(true);
- return;
- }
-
- // otherwise keep on searching
- for (i = 0; i < _pfPointsNum; i++)
- if (!_pfPath[i]->_marked) {
- int j = getPointsDist(*lowestPt, *_pfPath[i], _pfRequester);
- if (j != -1 && lowestPt->_distance + j < _pfPath[i]->_distance) {
- _pfPath[i]->_distance = lowestPt->_distance + j;
- _pfPath[i]->_origin = lowestPt;
- }
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::initLoop() {
-#ifdef _DEBUGxxxx
- int nu_steps = 0;
- uint32 start = _gameRef->_currentTime;
- while (!_pfReady && g_system->getMillis() - start <= _pfMaxTime) {
- PathFinderStep();
- nu_steps++;
- }
- if (nu_steps > 0) {
- _gameRef->LOG(0, "STAT: PathFinder iterations in one loop: %d (%s) _pfMaxTime=%d", nu_steps, _pfReady ? "finished" : "not yet done", _pfMaxTime);
- }
-#else
- uint32 start = _gameRef->_currentTime;
- while (!_pfReady && g_system->getMillis() - start <= _pfMaxTime) {
- pathFinderStep();
- }
-#endif
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdScene::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing SCENE file '%s'", filename);
- }
-
- setFilename(filename);
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(SCENE)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(LAYER)
-TOKEN_DEF(WAYPOINTS)
-TOKEN_DEF(EVENTS)
-TOKEN_DEF(CURSOR)
-TOKEN_DEF(CAMERA)
-TOKEN_DEF(ENTITY)
-TOKEN_DEF(SCALE_LEVEL)
-TOKEN_DEF(ROTATION_LEVEL)
-TOKEN_DEF(EDITOR_MARGIN_H)
-TOKEN_DEF(EDITOR_MARGIN_V)
-TOKEN_DEF(EDITOR_COLOR_FRAME)
-TOKEN_DEF(EDITOR_COLOR_ENTITY_SEL)
-TOKEN_DEF(EDITOR_COLOR_REGION_SEL)
-TOKEN_DEF(EDITOR_COLOR_DECORATION_SEL)
-TOKEN_DEF(EDITOR_COLOR_BLOCKED_SEL)
-TOKEN_DEF(EDITOR_COLOR_WAYPOINTS_SEL)
-TOKEN_DEF(EDITOR_COLOR_REGION)
-TOKEN_DEF(EDITOR_COLOR_DECORATION)
-TOKEN_DEF(EDITOR_COLOR_BLOCKED)
-TOKEN_DEF(EDITOR_COLOR_ENTITY)
-TOKEN_DEF(EDITOR_COLOR_WAYPOINTS)
-TOKEN_DEF(EDITOR_COLOR_SCALE)
-TOKEN_DEF(EDITOR_SHOW_REGIONS)
-TOKEN_DEF(EDITOR_SHOW_BLOCKED)
-TOKEN_DEF(EDITOR_SHOW_DECORATION)
-TOKEN_DEF(EDITOR_SHOW_ENTITIES)
-TOKEN_DEF(EDITOR_SHOW_SCALE)
-TOKEN_DEF(SCRIPT)
-TOKEN_DEF(CAPTION)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(VIEWPORT)
-TOKEN_DEF(PERSISTENT_STATE_SPRITES)
-TOKEN_DEF(PERSISTENT_STATE)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(SCENE)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(LAYER)
- TOKEN_TABLE(WAYPOINTS)
- TOKEN_TABLE(EVENTS)
- TOKEN_TABLE(CURSOR)
- TOKEN_TABLE(CAMERA)
- TOKEN_TABLE(ENTITY)
- TOKEN_TABLE(SCALE_LEVEL)
- TOKEN_TABLE(ROTATION_LEVEL)
- TOKEN_TABLE(EDITOR_MARGIN_H)
- TOKEN_TABLE(EDITOR_MARGIN_V)
- TOKEN_TABLE(EDITOR_COLOR_FRAME)
- TOKEN_TABLE(EDITOR_COLOR_ENTITY_SEL)
- TOKEN_TABLE(EDITOR_COLOR_REGION_SEL)
- TOKEN_TABLE(EDITOR_COLOR_DECORATION_SEL)
- TOKEN_TABLE(EDITOR_COLOR_BLOCKED_SEL)
- TOKEN_TABLE(EDITOR_COLOR_WAYPOINTS_SEL)
- TOKEN_TABLE(EDITOR_COLOR_REGION)
- TOKEN_TABLE(EDITOR_COLOR_DECORATION)
- TOKEN_TABLE(EDITOR_COLOR_BLOCKED)
- TOKEN_TABLE(EDITOR_COLOR_ENTITY)
- TOKEN_TABLE(EDITOR_COLOR_WAYPOINTS)
- TOKEN_TABLE(EDITOR_COLOR_SCALE)
- TOKEN_TABLE(EDITOR_SHOW_REGIONS)
- TOKEN_TABLE(EDITOR_SHOW_DECORATION)
- TOKEN_TABLE(EDITOR_SHOW_BLOCKED)
- TOKEN_TABLE(EDITOR_SHOW_ENTITIES)
- TOKEN_TABLE(EDITOR_SHOW_SCALE)
- TOKEN_TABLE(SCRIPT)
- TOKEN_TABLE(CAPTION)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(VIEWPORT)
- TOKEN_TABLE(PERSISTENT_STATE_SPRITES)
- TOKEN_TABLE(PERSISTENT_STATE)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- cleanup();
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCENE) {
- _gameRef->LOG(0, "'SCENE' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- int ar, ag, ab, aa;
- char camera[MAX_PATH_LENGTH] = "";
- /* float waypointHeight = -1.0f; */
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_CAPTION:
- setCaption((char *)params);
- break;
-
- case TOKEN_LAYER: {
- AdLayer *layer = new AdLayer(_gameRef);
- if (!layer || DID_FAIL(layer->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete layer;
- layer = NULL;
- } else {
- _gameRef->registerObject(layer);
- _layers.add(layer);
- if (layer->_main) {
- _mainLayer = layer;
- _width = layer->_width;
- _height = layer->_height;
- }
- }
- }
- break;
-
- case TOKEN_WAYPOINTS: {
- AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
- if (!wpt || DID_FAIL(wpt->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete wpt;
- wpt = NULL;
- } else {
- _gameRef->registerObject(wpt);
- _waypointGroups.add(wpt);
- }
- }
- break;
-
- case TOKEN_SCALE_LEVEL: {
- AdScaleLevel *sl = new AdScaleLevel(_gameRef);
- if (!sl || DID_FAIL(sl->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete sl;
- sl = NULL;
- } else {
- _gameRef->registerObject(sl);
- _scaleLevels.add(sl);
- }
- }
- break;
-
- case TOKEN_ROTATION_LEVEL: {
- AdRotLevel *rl = new AdRotLevel(_gameRef);
- if (!rl || DID_FAIL(rl->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete rl;
- rl = NULL;
- } else {
- _gameRef->registerObject(rl);
- _rotLevels.add(rl);
- }
- }
- break;
-
- case TOKEN_ENTITY: {
- AdEntity *entity = new AdEntity(_gameRef);
- if (!entity || DID_FAIL(entity->loadBuffer(params, false))) {
- cmd = PARSERR_GENERIC;
- delete entity;
- entity = NULL;
- } else {
- addObject(entity);
- }
- }
- break;
-
- case TOKEN_CURSOR:
- delete _cursor;
- _cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
- delete _cursor;
- _cursor = NULL;
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_CAMERA:
- strcpy(camera, (char *)params);
- break;
-
- case TOKEN_EDITOR_MARGIN_H:
- parser.scanStr((char *)params, "%d", &_editorMarginH);
- break;
-
- case TOKEN_EDITOR_MARGIN_V:
- parser.scanStr((char *)params, "%d", &_editorMarginV);
- break;
-
- case TOKEN_EDITOR_COLOR_FRAME:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColFrame = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_ENTITY:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColEntity = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_ENTITY_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColEntitySel = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_REGION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColRegionSel = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_DECORATION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColDecorSel = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_BLOCKED_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColBlockedSel = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_WAYPOINTS_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColWaypointsSel = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_REGION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColRegion = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_DECORATION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColDecor = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_BLOCKED:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColBlocked = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_WAYPOINTS:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColWaypoints = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_COLOR_SCALE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
- _editorColScale = BYTETORGBA(ar, ag, ab, aa);
- break;
-
- case TOKEN_EDITOR_SHOW_REGIONS:
- parser.scanStr((char *)params, "%b", &_editorShowRegions);
- break;
-
- case TOKEN_EDITOR_SHOW_BLOCKED:
- parser.scanStr((char *)params, "%b", &_editorShowBlocked);
- break;
-
- case TOKEN_EDITOR_SHOW_DECORATION:
- parser.scanStr((char *)params, "%b", &_editorShowDecor);
- break;
-
- case TOKEN_EDITOR_SHOW_ENTITIES:
- parser.scanStr((char *)params, "%b", &_editorShowEntities);
- break;
-
- case TOKEN_EDITOR_SHOW_SCALE:
- parser.scanStr((char *)params, "%b", &_editorShowScale);
- break;
-
- case TOKEN_SCRIPT:
- addScript((char *)params);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_VIEWPORT: {
- Rect32 rc;
- parser.scanStr((char *)params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
- if (!_viewport) {
- _viewport = new BaseViewport(_gameRef);
- }
- if (_viewport) {
- _viewport->setRect(rc.left, rc.top, rc.right, rc.bottom, true);
- }
- }
-
- case TOKEN_PERSISTENT_STATE:
- parser.scanStr((char *)params, "%b", &_persistentState);
- break;
-
- case TOKEN_PERSISTENT_STATE_SPRITES:
- parser.scanStr((char *)params, "%b", &_persistentStateSprites);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
-
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in SCENE definition");
- return STATUS_FAILED;
- }
-
- if (_mainLayer == NULL) {
- _gameRef->LOG(0, "Warning: scene '%s' has no main layer.", getFilename());
- }
-
-
- sortScaleLevels();
- sortRotLevels();
-
- _initialized = true;
-
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::traverseNodes(bool doUpdate) {
- if (!_initialized) {
- return STATUS_OK;
- }
-
- AdGame *adGame = (AdGame *)_gameRef;
-
-
- //////////////////////////////////////////////////////////////////////////
- // prepare viewport
- bool popViewport = false;
- if (_viewport && !_gameRef->_editorMode) {
- _gameRef->pushViewport(_viewport);
- popViewport = true;
- } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
- _gameRef->pushViewport(adGame->_sceneViewport);
- popViewport = true;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // *** adjust scroll offset
- if (doUpdate) {
- /*
- if (_autoScroll && _gameRef->_mainObject != NULL)
- {
- ScrollToObject(_gameRef->_mainObject);
- }
- */
-
- if (_autoScroll) {
- // adjust horizontal scroll
- if (_gameRef->_timer - _lastTimeH >= _scrollTimeH) {
- _lastTimeH = _gameRef->_timer;
- if (_offsetLeft < _targetOffsetLeft) {
- _offsetLeft += _scrollPixelsH;
- _offsetLeft = MIN(_offsetLeft, _targetOffsetLeft);
- } else if (_offsetLeft > _targetOffsetLeft) {
- _offsetLeft -= _scrollPixelsH;
- _offsetLeft = MAX(_offsetLeft, _targetOffsetLeft);
- }
- }
-
- // adjust vertical scroll
- if (_gameRef->_timer - _lastTimeV >= _scrollTimeV) {
- _lastTimeV = _gameRef->_timer;
- if (_offsetTop < _targetOffsetTop) {
- _offsetTop += _scrollPixelsV;
- _offsetTop = MIN(_offsetTop, _targetOffsetTop);
- } else if (_offsetTop > _targetOffsetTop) {
- _offsetTop -= _scrollPixelsV;
- _offsetTop = MAX(_offsetTop, _targetOffsetTop);
- }
- }
-
- if (_offsetTop == _targetOffsetTop && _offsetLeft == _targetOffsetLeft) {
- _ready = true;
- }
- } else {
- _ready = true; // not scrolling, i.e. always ready
- }
- }
-
-
-
-
- //////////////////////////////////////////////////////////////////////////
- int viewportWidth, viewportHeight;
- getViewportSize(&viewportWidth, &viewportHeight);
-
- int viewportX, viewportY;
- getViewportOffset(&viewportX, &viewportY);
-
- int scrollableX = _width - viewportWidth;
- int scrollableY = _height - viewportHeight;
-
- double widthRatio = scrollableX <= 0 ? 0 : ((double)(_offsetLeft) / (double)scrollableX);
- double heightRatio = scrollableY <= 0 ? 0 : ((double)(_offsetTop) / (double)scrollableY);
-
- int origX, origY;
- _gameRef->getOffset(&origX, &origY);
-
-
-
- //////////////////////////////////////////////////////////////////////////
- // *** display/update everything
- _gameRef->_renderer->setup2D();
-
- // for each layer
- /* int mainOffsetX = 0; */
- /* int mainOffsetY = 0; */
-
- for (uint32 j = 0; j < _layers.size(); j++) {
- if (!_layers[j]->_active) {
- continue;
- }
-
- // make layer exclusive
- if (!doUpdate) {
- if (_layers[j]->_closeUp && !_gameRef->_editorMode) {
- if (!_shieldWindow) {
- _shieldWindow = new UIWindow(_gameRef);
- }
- if (_shieldWindow) {
- _shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->_width;
- _shieldWindow->_height = _gameRef->_renderer->_height;
- _shieldWindow->display();
- }
- }
- }
-
- if (_paralaxScrolling) {
- int offsetX = (int)(widthRatio * (_layers[j]->_width - viewportWidth) - viewportX);
- int offsetY = (int)(heightRatio * (_layers[j]->_height - viewportHeight) - viewportY);
- _gameRef->setOffset(offsetX, offsetY);
-
- _gameRef->_offsetPercentX = (float)offsetX / ((float)_layers[j]->_width - viewportWidth) * 100.0f;
- _gameRef->_offsetPercentY = (float)offsetY / ((float)_layers[j]->_height - viewportHeight) * 100.0f;
-
- //_gameRef->QuickMessageForm("%d %f", OffsetX+ViewportX, _gameRef->_offsetPercentX);
- } else {
- _gameRef->setOffset(_offsetLeft - viewportX, _offsetTop - viewportY);
-
- _gameRef->_offsetPercentX = (float)(_offsetLeft - viewportX) / ((float)_layers[j]->_width - viewportWidth) * 100.0f;
- _gameRef->_offsetPercentY = (float)(_offsetTop - viewportY) / ((float)_layers[j]->_height - viewportHeight) * 100.0f;
- }
-
-
- // for each node
- for (uint32 k = 0; k < _layers[j]->_nodes.size(); k++) {
- AdSceneNode *node = _layers[j]->_nodes[k];
- switch (node->_type) {
- case OBJECT_ENTITY:
- if (node->_entity->_active && (_gameRef->_editorMode || !node->_entity->_editorOnly)) {
- _gameRef->_renderer->setup2D();
-
- if (doUpdate) {
- node->_entity->update();
- } else {
- node->_entity->display();
- }
- }
- break;
-
- case OBJECT_REGION: {
- if (node->_region->_blocked) {
- break;
- }
- if (node->_region->_decoration) {
- break;
- }
-
- if (!doUpdate) {
- displayRegionContent(node->_region);
- }
- }
- break;
- default:
- error("AdScene::TraverseNodes - Unhandled enum");
- break;
- } // switch
- } // each node
-
- // display/update all objects which are off-regions
- if (_layers[j]->_main) {
- if (doUpdate) {
- updateFreeObjects();
- } else {
- displayRegionContent(NULL);
- }
- }
- } // each layer
-
-
- // restore state
- _gameRef->setOffset(origX, origY);
- _gameRef->_renderer->setup2D();
-
- // display/update fader
- if (_fader) {
- if (doUpdate) {
- _fader->update();
- } else {
- _fader->display();
- }
- }
-
- if (popViewport) {
- _gameRef->popViewport();
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::display() {
- return traverseNodes(false);
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::updateFreeObjects() {
- AdGame *adGame = (AdGame *)_gameRef;
- // 3D-code removed
- // bool is3DSet;
-
- // *** update all active objects
- // is3DSet = false;
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- if (!adGame->_objects[i]->_active) {
- continue;
- }
- // 3D-code removed
- adGame->_objects[i]->update();
- adGame->_objects[i]->_drawn = false;
- }
-
-
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (!_objects[i]->_active) {
- continue;
- }
-
- _objects[i]->update();
- _objects[i]->_drawn = false;
- }
-
-
- if (_autoScroll && _gameRef->_mainObject != NULL) {
- scrollToObject(_gameRef->_mainObject);
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::displayRegionContent(AdRegion *region, bool display3DOnly) {
- AdGame *adGame = (AdGame *)_gameRef;
- BaseArray<AdObject *> objects;
- AdObject *obj;
-
- // global objects
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- obj = adGame->_objects[i];
- if (obj->_active && !obj->_drawn && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
- objects.add(obj);
- }
- }
-
- // scene objects
- for (uint32 i = 0; i < _objects.size(); i++) {
- obj = _objects[i];
- if (obj->_active && !obj->_editorOnly && !obj->_drawn && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
- objects.add(obj);
- }
- }
-
- // sort by _posY
- Common::sort(objects.begin(), objects.end(), AdScene::compareObjs);
-
- // display them
- for (uint32 i = 0; i < objects.size(); i++) {
- obj = objects[i];
-
- if (display3DOnly && !obj->_is3D) {
- continue;
- }
-
- _gameRef->_renderer->setup2D();
-
- if (_gameRef->_editorMode || !obj->_editorOnly) {
- obj->display();
- }
- obj->_drawn = true;
- }
-
-
- // display design only objects
- if (!display3DOnly) {
- if (_gameRef->_editorMode && region == NULL) {
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && _objects[i]->_editorOnly) {
- _objects[i]->display();
- _objects[i]->_drawn = true;
- }
- }
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-int AdScene::compareObjs(const void *obj1, const void *obj2) {
- const AdObject *object1 = *(const AdObject *const *)obj1;
- const AdObject *object2 = *(const AdObject *const *)obj2;
-
- if (object1->_posY < object2->_posY) {
- return -1;
- } else if (object1->_posY > object2->_posY) {
- return 1;
- } else {
- return 0;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::displayRegionContentOld(AdRegion *region) {
- AdGame *adGame = (AdGame *)_gameRef;
- AdObject *obj;
-
- // display all objects in region sorted by _posY
- do {
- obj = NULL;
- int minY = INT_MAX;
-
- // global objects
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- if (adGame->_objects[i]->_active && !adGame->_objects[i]->_drawn && adGame->_objects[i]->_posY < minY && (adGame->_objects[i]->_stickRegion == region || region == NULL || (adGame->_objects[i]->_stickRegion == NULL && region->pointInRegion(adGame->_objects[i]->_posX, adGame->_objects[i]->_posY)))) {
- obj = adGame->_objects[i];
- minY = adGame->_objects[i]->_posY;
- }
- }
-
- // scene objects
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && !_objects[i]->_editorOnly && !_objects[i]->_drawn && _objects[i]->_posY < minY && (_objects[i]->_stickRegion == region || region == NULL || (_objects[i]->_stickRegion == NULL && region->pointInRegion(_objects[i]->_posX, _objects[i]->_posY)))) {
- obj = _objects[i];
- minY = _objects[i]->_posY;
- }
- }
-
-
- if (obj != NULL) {
- _gameRef->_renderer->setup2D();
-
- if (_gameRef->_editorMode || !obj->_editorOnly) {
- obj->display();
- }
- obj->_drawn = true;
- }
- } while (obj != NULL);
-
-
- // design only objects
- if (_gameRef->_editorMode && region == NULL) {
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_active && _objects[i]->_editorOnly) {
- _objects[i]->display();
- _objects[i]->_drawn = true;
- }
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::update() {
- return traverseNodes(true);
-}
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::scrollTo(int offsetX, int offsetY) {
- int viewportWidth, viewportHeight;
- getViewportSize(&viewportWidth, &viewportHeight);
-
- int origOffsetLeft = _targetOffsetLeft;
- int origOffsetTop = _targetOffsetTop;
-
- _targetOffsetLeft = MAX(0, offsetX - viewportWidth / 2);
- _targetOffsetLeft = MIN(_targetOffsetLeft, _width - viewportWidth);
-
- _targetOffsetTop = MAX(0, offsetY - viewportHeight / 2);
- _targetOffsetTop = MIN(_targetOffsetTop, _height - viewportHeight);
-
-
- if (_gameRef->_mainObject && _gameRef->_mainObject->_is3D) {
- if (abs(origOffsetLeft - _targetOffsetLeft) < 5) {
- _targetOffsetLeft = origOffsetLeft;
- }
- if (abs(origOffsetTop - _targetOffsetTop) < 5) {
- _targetOffsetTop = origOffsetTop;
- }
- //_targetOffsetTop = 0;
- }
-
- _ready = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::scrollToObject(BaseObject *object) {
- if (object) {
- scrollTo(object->_posX, object->_posY - object->getHeight() / 2);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::skipToObject(BaseObject *object) {
- if (object) {
- skipTo(object->_posX, object->_posY - object->getHeight() / 2);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::skipTo(int offsetX, int offsetY) {
- int viewportWidth, viewportHeight;
- getViewportSize(&viewportWidth, &viewportHeight);
-
- _offsetLeft = MAX(0, offsetX - viewportWidth / 2);
- _offsetLeft = MIN(_offsetLeft, _width - viewportWidth);
-
- _offsetTop = MAX(0, offsetY - viewportHeight / 2);
- _offsetTop = MIN(_offsetTop, _height - viewportHeight);
-
- _targetOffsetLeft = _offsetLeft;
- _targetOffsetTop = _offsetTop;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // LoadActor
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "LoadActor") == 0) {
- stack->correctParams(1);
- AdActor *act = new AdActor(_gameRef);
- if (act && DID_SUCCEED(act->loadFile(stack->pop()->getString()))) {
- addObject(act);
- stack->pushNative(act, true);
- } else {
- delete act;
- act = NULL;
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // LoadEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "LoadEntity") == 0) {
- stack->correctParams(1);
- AdEntity *ent = new AdEntity(_gameRef);
- if (ent && DID_SUCCEED(ent->loadFile(stack->pop()->getString()))) {
- addObject(ent);
- stack->pushNative(ent, true);
- } else {
- delete ent;
- ent = NULL;
- stack->pushNULL();
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // CreateEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "CreateEntity") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdEntity *ent = new AdEntity(_gameRef);
- addObject(ent);
- if (!val->isNULL()) {
- ent->setName(val->getString());
- }
- stack->pushNative(ent, true);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // UnloadObject / UnloadActor / UnloadEntity / UnloadActor3D / DeleteEntity
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "UnloadObject") == 0 || strcmp(name, "UnloadActor") == 0 || strcmp(name, "UnloadEntity") == 0 || strcmp(name, "UnloadActor3D") == 0 || strcmp(name, "DeleteEntity") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- AdObject *obj = (AdObject *)val->getNative();
- removeObject(obj);
- if (val->getType() == VAL_VARIABLE_REF) {
- val->setNULL();
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SkipTo
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SkipTo") == 0) {
- stack->correctParams(2);
- ScValue *val1 = stack->pop();
- ScValue *val2 = stack->pop();
- if (val1->isNative()) {
- skipToObject((BaseObject *)val1->getNative());
- } else {
- skipTo(val1->getInt(), val2->getInt());
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollTo / ScrollToAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollTo") == 0 || strcmp(name, "ScrollToAsync") == 0) {
- stack->correctParams(2);
- ScValue *val1 = stack->pop();
- ScValue *val2 = stack->pop();
- if (val1->isNative()) {
- scrollToObject((BaseObject *)val1->getNative());
- } else {
- scrollTo(val1->getInt(), val2->getInt());
- }
- if (strcmp(name, "ScrollTo") == 0) {
- script->waitForExclusive(this);
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetLayer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetLayer") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
- if (val->isInt()) {
- int layer = val->getInt();
- if (layer < 0 || layer >= (int32)_layers.size()) {
- stack->pushNULL();
- } else {
- stack->pushNative(_layers[layer], true);
- }
- } else {
- const char *layerName = val->getString();
- bool layerFound = false;
- for (uint32 i = 0; i < _layers.size(); i++) {
- if (scumm_stricmp(layerName, _layers[i]->getName()) == 0) {
- stack->pushNative(_layers[i], true);
- layerFound = true;
- break;
- }
- }
- if (!layerFound) {
- stack->pushNULL();
- }
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetWaypointGroup
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetWaypointGroup") == 0) {
- stack->correctParams(1);
- int group = stack->pop()->getInt();
- if (group < 0 || group >= (int32)_waypointGroups.size()) {
- stack->pushNULL();
- } else {
- stack->pushNative(_waypointGroups[group], true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetNode
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetNode") == 0) {
- stack->correctParams(1);
- const char *nodeName = stack->pop()->getString();
-
- BaseObject *node = getNodeByName(nodeName);
- if (node) {
- stack->pushNative((BaseScriptable *)node, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetFreeNode
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetFreeNode") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdObject *ret = NULL;
- if (val->isInt()) {
- int index = val->getInt();
- if (index >= 0 && index < (int32)_objects.size()) {
- ret = _objects[index];
- }
- } else {
- const char *nodeName = val->getString();
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i] && _objects[i]->getName() && scumm_stricmp(_objects[i]->getName(), nodeName) == 0) {
- ret = _objects[i];
- break;
- }
- }
- }
- if (ret) {
- stack->pushNative(ret, true);
- } else {
- stack->pushNULL();
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetRegionAt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetRegionAt") == 0) {
- stack->correctParams(3);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
- ScValue *val = stack->pop();
-
- bool includeDecors = false;
- if (!val->isNULL()) {
- includeDecors = val->getBool();
- }
-
- if (_mainLayer) {
- for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- if (node->_type == OBJECT_REGION && node->_region->_active && node->_region->pointInRegion(x, y)) {
- if (node->_region->_decoration && !includeDecors) {
- continue;
- }
-
- stack->pushNative(node->_region, true);
- return STATUS_OK;
- }
- }
- }
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsBlockedAt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsBlockedAt") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
-
- stack->pushBool(isBlockedAt(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsWalkableAt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsWalkableAt") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
-
- stack->pushBool(isWalkableAt(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetScaleAt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetScaleAt") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
-
- stack->pushFloat(getZoomAt(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetRotationAt
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetRotationAt") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
-
- stack->pushFloat(getRotationAt(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsScrolling
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsScrolling") == 0) {
- stack->correctParams(0);
- bool ret = false;
- if (_autoScroll) {
- if (_targetOffsetLeft != _offsetLeft || _targetOffsetTop != _offsetTop) {
- ret = true;
- }
- }
-
- stack->pushBool(ret);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // FadeOut / FadeOutAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "FadeOut") == 0 || strcmp(name, "FadeOutAsync") == 0) {
- stack->correctParams(5);
- uint32 duration = stack->pop()->getInt(500);
- byte red = stack->pop()->getInt(0);
- byte green = stack->pop()->getInt(0);
- byte blue = stack->pop()->getInt(0);
- byte alpha = stack->pop()->getInt(0xFF);
-
- _fader->fadeOut(BYTETORGBA(red, green, blue, alpha), duration);
- if (strcmp(name, "FadeOutAsync") != 0) {
- script->waitFor(_fader);
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // FadeIn / FadeInAsync
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "FadeIn") == 0 || strcmp(name, "FadeInAsync") == 0) {
- stack->correctParams(5);
- uint32 duration = stack->pop()->getInt(500);
- byte red = stack->pop()->getInt(0);
- byte green = stack->pop()->getInt(0);
- byte blue = stack->pop()->getInt(0);
- byte alpha = stack->pop()->getInt(0xFF);
-
- _fader->fadeIn(BYTETORGBA(red, green, blue, alpha), duration);
- if (strcmp(name, "FadeInAsync") != 0) {
- script->waitFor(_fader);
- }
-
- stack->pushNULL();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetFadeColor
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetFadeColor") == 0) {
- stack->correctParams(0);
- stack->pushInt(_fader->getCurrentColor());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // IsPointInViewport
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "IsPointInViewport") == 0) {
- stack->correctParams(2);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
- stack->pushBool(pointInViewport(x, y));
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetViewport
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetViewport") == 0) {
- stack->correctParams(4);
- int x = stack->pop()->getInt();
- int y = stack->pop()->getInt();
- int width = stack->pop()->getInt();
- int height = stack->pop()->getInt();
-
- if (width <= 0) {
- width = _gameRef->_renderer->_width;
- }
- if (height <= 0) {
- height = _gameRef->_renderer->_height;
- }
-
- if (!_viewport) {
- _viewport = new BaseViewport(_gameRef);
- }
- if (_viewport) {
- _viewport->setRect(x, y, x + width, y + height);
- }
-
- stack->pushBool(true);
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AddLayer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddLayer") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdLayer *layer = new AdLayer(_gameRef);
- if (!val->isNULL()) {
- layer->setName(val->getString());
- }
- if (_mainLayer) {
- layer->_width = _mainLayer->_width;
- layer->_height = _mainLayer->_height;
- }
- _layers.add(layer);
- _gameRef->registerObject(layer);
-
- stack->pushNative(layer, true);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // InsertLayer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "InsertLayer") == 0) {
- stack->correctParams(2);
- int index = stack->pop()->getInt();
- ScValue *val = stack->pop();
-
- AdLayer *layer = new AdLayer(_gameRef);
- if (!val->isNULL()) {
- layer->setName(val->getString());
- }
- if (_mainLayer) {
- layer->_width = _mainLayer->_width;
- layer->_height = _mainLayer->_height;
- }
- if (index < 0) {
- index = 0;
- }
- if (index <= (int32)_layers.size() - 1) {
- _layers.insert_at(index, layer);
- } else {
- _layers.add(layer);
- }
-
- _gameRef->registerObject(layer);
-
- stack->pushNative(layer, true);
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // DeleteLayer
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "DeleteLayer") == 0) {
- stack->correctParams(1);
- ScValue *val = stack->pop();
-
- AdLayer *toDelete = NULL;
- if (val->isNative()) {
- BaseScriptable *temp = val->getNative();
- for (uint32 i = 0; i < _layers.size(); i++) {
- if (_layers[i] == temp) {
- toDelete = _layers[i];
- break;
- }
- }
- } else {
- int index = val->getInt();
- if (index >= 0 && index < (int32)_layers.size()) {
- toDelete = _layers[index];
- }
- }
- if (toDelete == NULL) {
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- if (toDelete->_main) {
- script->runtimeError("Scene.DeleteLayer - cannot delete main scene layer");
- stack->pushBool(false);
- return STATUS_OK;
- }
-
- for (uint32 i = 0; i < _layers.size(); i++) {
- if (_layers[i] == toDelete) {
- _layers.remove_at(i);
- _gameRef->unregisterObject(toDelete);
- break;
- }
- }
- stack->pushBool(true);
- return STATUS_OK;
- } else {
- return BaseObject::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdScene::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("scene");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumLayers (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumLayers") == 0) {
- _scValue->setInt(_layers.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumWaypointGroups (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumWaypointGroups") == 0) {
- _scValue->setInt(_waypointGroups.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // MainLayer (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "MainLayer") == 0) {
- if (_mainLayer) {
- _scValue->setNative(_mainLayer, true);
- } else {
- _scValue->setNULL();
- }
-
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // NumFreeNodes (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "NumFreeNodes") == 0) {
- _scValue->setInt(_objects.size());
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // MouseX (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "MouseX") == 0) {
- int viewportX;
- getViewportOffset(&viewportX);
-
- _scValue->setInt(_gameRef->_mousePos.x + _offsetLeft - viewportX);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // MouseY (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "MouseY") == 0) {
- int viewportY;
- getViewportOffset(NULL, &viewportY);
-
- _scValue->setInt(_gameRef->_mousePos.y + _offsetTop - viewportY);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AutoScroll
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AutoScroll") == 0) {
- _scValue->setBool(_autoScroll);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PersistentState
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PersistentState") == 0) {
- _scValue->setBool(_persistentState);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PersistentStateSprites
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PersistentStateSprites") == 0) {
- _scValue->setBool(_persistentStateSprites);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollPixelsX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollPixelsX") == 0) {
- _scValue->setInt(_scrollPixelsH);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollPixelsY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollPixelsY") == 0) {
- _scValue->setInt(_scrollPixelsV);
- return _scValue;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollSpeedX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollSpeedX") == 0) {
- _scValue->setInt(_scrollTimeH);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollSpeedY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollSpeedY") == 0) {
- _scValue->setInt(_scrollTimeV);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // OffsetX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "OffsetX") == 0) {
- _scValue->setInt(_offsetLeft);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // OffsetY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "OffsetY") == 0) {
- _scValue->setInt(_offsetTop);
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Width (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Width") == 0) {
- if (_mainLayer) {
- _scValue->setInt(_mainLayer->_width);
- } else {
- _scValue->setInt(0);
- }
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Height (RO)
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Height") == 0) {
- if (_mainLayer) {
- _scValue->setInt(_mainLayer->_height);
- } else {
- _scValue->setInt(0);
- }
- return _scValue;
- } else {
- return BaseObject::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Name
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Name") == 0) {
- setName(value->getString());
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AutoScroll
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AutoScroll") == 0) {
- _autoScroll = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PersistentState
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PersistentState") == 0) {
- _persistentState = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // PersistentStateSprites
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "PersistentStateSprites") == 0) {
- _persistentStateSprites = value->getBool();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollPixelsX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollPixelsX") == 0) {
- _scrollPixelsH = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollPixelsY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollPixelsY") == 0) {
- _scrollPixelsV = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollSpeedX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollSpeedX") == 0) {
- _scrollTimeH = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // ScrollSpeedY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "ScrollSpeedY") == 0) {
- _scrollTimeV = value->getInt();
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // OffsetX
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "OffsetX") == 0) {
- _offsetLeft = value->getInt();
-
- int viewportWidth, viewportHeight;
- getViewportSize(&viewportWidth, &viewportHeight);
-
- _offsetLeft = MAX(0, _offsetLeft - viewportWidth / 2);
- _offsetLeft = MIN(_offsetLeft, _width - viewportWidth);
- _targetOffsetLeft = _offsetLeft;
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // OffsetY
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "OffsetY") == 0) {
- _offsetTop = value->getInt();
-
- int viewportWidth, viewportHeight;
- getViewportSize(&viewportWidth, &viewportHeight);
-
- _offsetTop = MAX(0, _offsetTop - viewportHeight / 2);
- _offsetTop = MIN(_offsetTop, _height - viewportHeight);
- _targetOffsetTop = _offsetTop;
-
- return STATUS_OK;
- } else {
- return BaseObject::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdScene::scToString() {
- return "[scene object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::addObject(AdObject *object) {
- _objects.add(object);
- return _gameRef->registerObject(object);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::removeObject(AdObject *object) {
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i] == object) {
- _objects.remove_at(i);
- return _gameRef->unregisterObject(object);
- }
- }
- return STATUS_FAILED;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "SCENE {\n");
-
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
-
- if (_persistentState) {
- buffer->putTextIndent(indent + 2, "PERSISTENT_STATE=%s\n", _persistentState ? "TRUE" : "FALSE");
- }
-
- if (!_persistentStateSprites) {
- buffer->putTextIndent(indent + 2, "PERSISTENT_STATE_SPRITES=%s\n", _persistentStateSprites ? "TRUE" : "FALSE");
- }
-
-
- // scripts
- for (uint32 i = 0; i < _scripts.size(); i++) {
- buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
- }
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // properties
- if (_scProp) {
- _scProp->saveAsText(buffer, indent + 2);
- }
-
- // viewport
- if (_viewport) {
- Rect32 *rc = _viewport->getRect();
- buffer->putTextIndent(indent + 2, "VIEWPORT { %d, %d, %d, %d }\n", rc->left, rc->top, rc->right, rc->bottom);
- }
-
-
-
- // editor settings
- buffer->putTextIndent(indent + 2, "; ----- editor settings\n");
- buffer->putTextIndent(indent + 2, "EDITOR_MARGIN_H=%d\n", _editorMarginH);
- buffer->putTextIndent(indent + 2, "EDITOR_MARGIN_V=%d\n", _editorMarginV);
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_FRAME { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColFrame), RGBCOLGetG(_editorColFrame), RGBCOLGetB(_editorColFrame), RGBCOLGetA(_editorColFrame));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_ENTITY_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColEntitySel), RGBCOLGetG(_editorColEntitySel), RGBCOLGetB(_editorColEntitySel), RGBCOLGetA(_editorColEntitySel));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_REGION_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColRegionSel), RGBCOLGetG(_editorColRegionSel), RGBCOLGetB(_editorColRegionSel), RGBCOLGetA(_editorColRegionSel));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_BLOCKED_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColBlockedSel), RGBCOLGetG(_editorColBlockedSel), RGBCOLGetB(_editorColBlockedSel), RGBCOLGetA(_editorColBlockedSel));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_DECORATION_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColDecorSel), RGBCOLGetG(_editorColDecorSel), RGBCOLGetB(_editorColDecorSel), RGBCOLGetA(_editorColDecorSel));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_WAYPOINTS_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColWaypointsSel), RGBCOLGetG(_editorColWaypointsSel), RGBCOLGetB(_editorColWaypointsSel), RGBCOLGetA(_editorColWaypointsSel));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_ENTITY { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColEntity), RGBCOLGetG(_editorColEntity), RGBCOLGetB(_editorColEntity), RGBCOLGetA(_editorColEntity));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_REGION { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColRegion), RGBCOLGetG(_editorColRegion), RGBCOLGetB(_editorColRegion), RGBCOLGetA(_editorColRegion));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_DECORATION { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColDecor), RGBCOLGetG(_editorColDecor), RGBCOLGetB(_editorColDecor), RGBCOLGetA(_editorColDecor));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_BLOCKED { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColBlocked), RGBCOLGetG(_editorColBlocked), RGBCOLGetB(_editorColBlocked), RGBCOLGetA(_editorColBlocked));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_WAYPOINTS { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColWaypoints), RGBCOLGetG(_editorColWaypoints), RGBCOLGetB(_editorColWaypoints), RGBCOLGetA(_editorColWaypoints));
- buffer->putTextIndent(indent + 2, "EDITOR_COLOR_SCALE { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColScale), RGBCOLGetG(_editorColScale), RGBCOLGetB(_editorColScale), RGBCOLGetA(_editorColScale));
-
- buffer->putTextIndent(indent + 2, "EDITOR_SHOW_REGIONS=%s\n", _editorShowRegions ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SHOW_BLOCKED=%s\n", _editorShowBlocked ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SHOW_DECORATION=%s\n", _editorShowDecor ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SHOW_ENTITIES=%s\n", _editorShowEntities ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SHOW_SCALE=%s\n", _editorShowScale ? "TRUE" : "FALSE");
-
- buffer->putTextIndent(indent + 2, "\n");
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- // waypoints
- buffer->putTextIndent(indent + 2, "; ----- waypoints\n");
- for (uint32 i = 0; i < _waypointGroups.size(); i++) {
- _waypointGroups[i]->saveAsText(buffer, indent + 2);
- }
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // layers
- buffer->putTextIndent(indent + 2, "; ----- layers\n");
- for (uint32 i = 0; i < _layers.size(); i++) {
- _layers[i]->saveAsText(buffer, indent + 2);
- }
-
- // scale levels
- buffer->putTextIndent(indent + 2, "; ----- scale levels\n");
- for (uint32 i = 0; i < _scaleLevels.size(); i++) {
- _scaleLevels[i]->saveAsText(buffer, indent + 2);
- }
-
- // rotation levels
- buffer->putTextIndent(indent + 2, "; ----- rotation levels\n");
- for (uint32 i = 0; i < _rotLevels.size(); i++) {
- _rotLevels[i]->saveAsText(buffer, indent + 2);
- }
-
-
- buffer->putTextIndent(indent + 2, "\n");
-
- // free entities
- buffer->putTextIndent(indent + 2, "; ----- free entities\n");
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_type == OBJECT_ENTITY) {
- _objects[i]->saveAsText(buffer, indent + 2);
-
- }
- }
-
- buffer->putTextIndent(indent, "}\n");
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::sortScaleLevels() {
- if (_scaleLevels.size() == 0) {
- return STATUS_OK;
- }
- bool changed;
- do {
- changed = false;
- for (uint32 i = 0; i < _scaleLevels.size() - 1; i++) {
- if (_scaleLevels[i]->_posY > _scaleLevels[i + 1]->_posY) {
- AdScaleLevel *sl = _scaleLevels[i];
- _scaleLevels[i] = _scaleLevels[i + 1];
- _scaleLevels[i + 1] = sl;
-
- changed = true;
- }
- }
-
- } while (changed);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::sortRotLevels() {
- if (_rotLevels.size() == 0) {
- return STATUS_OK;
- }
- bool changed;
- do {
- changed = false;
- for (uint32 i = 0; i < _rotLevels.size() - 1; i++) {
- if (_rotLevels[i]->_posX > _rotLevels[i + 1]->_posX) {
- AdRotLevel *rl = _rotLevels[i];
- _rotLevels[i] = _rotLevels[i + 1];
- _rotLevels[i + 1] = rl;
-
- changed = true;
- }
- }
-
- } while (changed);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-float AdScene::getScaleAt(int Y) {
- AdScaleLevel *prev = NULL;
- AdScaleLevel *next = NULL;
-
- for (uint32 i = 0; i < _scaleLevels.size(); i++) {
- /* AdScaleLevel *xxx = _scaleLevels[i];*/
- /* int j = _scaleLevels.size(); */
- if (_scaleLevels[i]->_posY < Y) {
- prev = _scaleLevels[i];
- } else {
- next = _scaleLevels[i];
- break;
- }
- }
-
- if (prev == NULL || next == NULL) {
- return 100;
- }
-
- int delta_y = next->_posY - prev->_posY;
- float delta_scale = next->_scale - prev->_scale;
- Y -= prev->_posY;
-
- float percent = (float)Y / ((float)delta_y / 100.0f);
- return prev->_scale + delta_scale / 100 * percent;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::persist(BasePersistenceManager *persistMgr) {
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_autoScroll));
- persistMgr->transfer(TMEMBER(_editorColBlocked));
- persistMgr->transfer(TMEMBER(_editorColBlockedSel));
- persistMgr->transfer(TMEMBER(_editorColDecor));
- persistMgr->transfer(TMEMBER(_editorColDecorSel));
- persistMgr->transfer(TMEMBER(_editorColEntity));
- persistMgr->transfer(TMEMBER(_editorColEntitySel));
- persistMgr->transfer(TMEMBER(_editorColFrame));
- persistMgr->transfer(TMEMBER(_editorColRegion));
- persistMgr->transfer(TMEMBER(_editorColRegionSel));
- persistMgr->transfer(TMEMBER(_editorColScale));
- persistMgr->transfer(TMEMBER(_editorColWaypoints));
- persistMgr->transfer(TMEMBER(_editorColWaypointsSel));
- persistMgr->transfer(TMEMBER(_editorMarginH));
- persistMgr->transfer(TMEMBER(_editorMarginV));
- persistMgr->transfer(TMEMBER(_editorShowBlocked));
- persistMgr->transfer(TMEMBER(_editorShowDecor));
- persistMgr->transfer(TMEMBER(_editorShowEntities));
- persistMgr->transfer(TMEMBER(_editorShowRegions));
- persistMgr->transfer(TMEMBER(_editorShowScale));
- persistMgr->transfer(TMEMBER(_fader));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_initialized));
- persistMgr->transfer(TMEMBER(_lastTimeH));
- persistMgr->transfer(TMEMBER(_lastTimeV));
- _layers.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_mainLayer));
- _objects.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_offsetLeft));
- persistMgr->transfer(TMEMBER(_offsetTop));
- persistMgr->transfer(TMEMBER(_paralaxScrolling));
- persistMgr->transfer(TMEMBER(_persistentState));
- persistMgr->transfer(TMEMBER(_persistentStateSprites));
- persistMgr->transfer(TMEMBER(_pfMaxTime));
- _pfPath.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_pfPointsNum));
- persistMgr->transfer(TMEMBER(_pfReady));
- persistMgr->transfer(TMEMBER(_pfRequester));
- persistMgr->transfer(TMEMBER(_pfTarget));
- persistMgr->transfer(TMEMBER(_pfTargetPath));
- _rotLevels.persist(persistMgr);
- _scaleLevels.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollPixelsH));
- persistMgr->transfer(TMEMBER(_scrollPixelsV));
- persistMgr->transfer(TMEMBER(_scrollTimeH));
- persistMgr->transfer(TMEMBER(_scrollTimeV));
- persistMgr->transfer(TMEMBER(_shieldWindow));
- persistMgr->transfer(TMEMBER(_targetOffsetLeft));
- persistMgr->transfer(TMEMBER(_targetOffsetTop));
- _waypointGroups.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_viewport));
- persistMgr->transfer(TMEMBER(_width));
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::afterLoad() {
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::correctTargetPoint2(int startX, int startY, int *targetX, int *targetY, bool checkFreeObjects, BaseObject *requester) {
- double xStep, yStep, x, y;
- int xLength, yLength, xCount, yCount;
- int x1, y1, x2, y2;
-
- x1 = *targetX;
- y1 = *targetY;
- x2 = startX;
- y2 = startY;
-
-
- xLength = abs(x2 - x1);
- yLength = abs(y2 - y1);
-
- if (xLength > yLength) {
-
- yStep = fabs((double)(y2 - y1) / (double)(x2 - x1));
- y = y1;
-
- for (xCount = x1; xCount < x2; xCount++) {
- if (isWalkableAt(xCount, (int)y, checkFreeObjects, requester)) {
- *targetX = xCount;
- *targetY = (int)y;
- return STATUS_OK;
- }
- y += yStep;
- }
- } else {
-
- xStep = fabs((double)(x2 - x1) / (double)(y2 - y1));
- x = x1;
-
- for (yCount = y1; yCount < y2; yCount++) {
- if (isWalkableAt((int)x, yCount, checkFreeObjects, requester)) {
- *targetX = (int)x;
- *targetY = yCount;
- return STATUS_OK;
- }
- x += xStep;
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::correctTargetPoint(int startX, int startY, int *argX, int *argY, bool checkFreeObjects, BaseObject *requester) {
- int x = *argX;
- int y = *argY;
-
- if (isWalkableAt(x, y, checkFreeObjects, requester) || !_mainLayer) {
- return STATUS_OK;
- }
-
- // right
- int lengthRight = 0;
- bool foundRight = false;
- for (x = *argX, y = *argY; x < _mainLayer->_width; x++, lengthRight++) {
- if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x - 5, y, checkFreeObjects, requester)) {
- foundRight = true;
- break;
- }
- }
-
- // left
- int lengthLeft = 0;
- bool foundLeft = false;
- for (x = *argX, y = *argY; x >= 0; x--, lengthLeft--) {
- if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x + 5, y, checkFreeObjects, requester)) {
- foundLeft = true;
- break;
- }
- }
-
- // up
- int lengthUp = 0;
- bool foundUp = false;
- for (x = *argX, y = *argY; y >= 0; y--, lengthUp--) {
- if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x, y + 5, checkFreeObjects, requester)) {
- foundUp = true;
- break;
- }
- }
-
- // down
- int lengthDown = 0;
- bool foundDown = false;
- for (x = *argX, y = *argY; y < _mainLayer->_height; y++, lengthDown++) {
- if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x, y - 5, checkFreeObjects, requester)) {
- foundDown = true;
- break;
- }
- }
-
- if (!foundLeft && !foundRight && !foundUp && !foundDown) {
- return STATUS_OK;
- }
-
- int offsetX = INT_MAX, offsetY = INT_MAX;
-
- if (foundLeft && foundRight) {
- if (abs(lengthLeft) < abs(lengthRight)) {
- offsetX = lengthLeft;
- } else {
- offsetX = lengthRight;
- }
- } else if (foundLeft) {
- offsetX = lengthLeft;
- } else if (foundRight) {
- offsetX = lengthRight;
- }
-
- if (foundUp && foundDown) {
- if (abs(lengthUp) < abs(lengthDown)) {
- offsetY = lengthUp;
- } else {
- offsetY = lengthDown;
- }
- } else if (foundUp) {
- offsetY = lengthUp;
- } else if (foundDown) {
- offsetY = lengthDown;
- }
-
- if (abs(offsetX) < abs(offsetY)) {
- *argX = *argX + offsetX;
- } else {
- *argY = *argY + offsetY;
- }
-
- if (!isWalkableAt(*argX, *argY)) {
- return correctTargetPoint2(startX, startY, argX, argY, checkFreeObjects, requester);
- } else {
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::pfPointsStart() {
- _pfPointsNum = 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::pfPointsAdd(int x, int y, int distance) {
- if (_pfPointsNum >= (int32)_pfPath.size()) {
- _pfPath.add(new AdPathPoint(x, y, distance));
- } else {
- _pfPath[_pfPointsNum]->x = x;
- _pfPath[_pfPointsNum]->y = y;
- _pfPath[_pfPointsNum]->_distance = distance;
- _pfPath[_pfPointsNum]->_marked = false;
- _pfPath[_pfPointsNum]->_origin = NULL;
- }
-
- _pfPointsNum++;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getViewportOffset(int *offsetX, int *offsetY) {
- AdGame *adGame = (AdGame *)_gameRef;
- if (_viewport && !_gameRef->_editorMode) {
- if (offsetX) {
- *offsetX = _viewport->_offsetX;
- }
- if (offsetY) {
- *offsetY = _viewport->_offsetY;
- }
- } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
- if (offsetX) {
- *offsetX = adGame->_sceneViewport->_offsetX;
- }
- if (offsetY) {
- *offsetY = adGame->_sceneViewport->_offsetY;
- }
- } else {
- if (offsetX) {
- *offsetX = 0;
- }
- if (offsetY) {
- *offsetY = 0;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getViewportSize(int *width, int *height) {
- AdGame *adGame = (AdGame *)_gameRef;
- if (_viewport && !_gameRef->_editorMode) {
- if (width) {
- *width = _viewport->getWidth();
- }
- if (height) {
- *height = _viewport->getHeight();
- }
- } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
- if (width) {
- *width = adGame->_sceneViewport->getWidth();
- }
- if (height) {
- *height = adGame->_sceneViewport->getHeight();
- }
- } else {
- if (width) {
- *width = _gameRef->_renderer->_width;
- }
- if (height) {
- *height = _gameRef->_renderer->_height;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdScene::getOffsetLeft() {
- int viewportX;
- getViewportOffset(&viewportX);
-
- return _offsetLeft - viewportX;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int AdScene::getOffsetTop() {
- int viewportY;
- getViewportOffset(NULL, &viewportY);
-
- return _offsetTop - viewportY;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::pointInViewport(int x, int y) {
- int left, top, width, height;
-
- getViewportOffset(&left, &top);
- getViewportSize(&width, &height);
-
- return x >= left && x <= left + width && y >= top && y <= top + height;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdScene::setOffset(int offsetLeft, int offsetTop) {
- _offsetLeft = offsetLeft;
- _offsetTop = offsetTop;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseObject *AdScene::getNodeByName(const char *name) {
- BaseObject *ret = NULL;
-
- // dependent objects
- for (uint32 i = 0; i < _layers.size(); i++) {
- AdLayer *layer = _layers[i];
- for (uint32 j = 0; j < layer->_nodes.size(); j++) {
- AdSceneNode *node = layer->_nodes[j];
- if ((node->_type == OBJECT_ENTITY && !scumm_stricmp(name, node->_entity->getName())) ||
- (node->_type == OBJECT_REGION && !scumm_stricmp(name, node->_region->getName()))) {
- switch (node->_type) {
- case OBJECT_ENTITY:
- ret = node->_entity;
- break;
- case OBJECT_REGION:
- ret = node->_region;
- break;
- default:
- ret = NULL;
- }
- return ret;
- }
- }
- }
-
- // free entities
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_type == OBJECT_ENTITY && !scumm_stricmp(name, _objects[i]->getName())) {
- return _objects[i];
- }
- }
-
- // waypoint groups
- for (uint32 i = 0; i < _waypointGroups.size(); i++) {
- if (!scumm_stricmp(name, _waypointGroups[i]->getName())) {
- return _waypointGroups[i];
- }
- }
-
- return NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::saveState() {
- return persistState(true);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::loadState() {
- return persistState(false);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::persistState(bool saving) {
- if (!_persistentState) {
- return STATUS_OK;
- }
-
- AdGame *adGame = (AdGame *)_gameRef;
- AdSceneState *state = adGame->getSceneState(getFilename(), saving);
- if (!state) {
- return STATUS_OK;
- }
-
- AdNodeState *nodeState;
-
- // dependent objects
- for (uint32 i = 0; i < _layers.size(); i++) {
- AdLayer *layer = _layers[i];
- for (uint32 j = 0; j < layer->_nodes.size(); j++) {
- AdSceneNode *node = layer->_nodes[j];
- switch (node->_type) {
- case OBJECT_ENTITY:
- if (!node->_entity->_saveState) {
- continue;
- }
- nodeState = state->getNodeState(node->_entity->getName(), saving);
- if (nodeState) {
- nodeState->transferEntity(node->_entity, _persistentStateSprites, saving);
- //if (Saving) NodeState->_active = node->_entity->_active;
- //else node->_entity->_active = NodeState->_active;
- }
- break;
- case OBJECT_REGION:
- if (!node->_region->_saveState) {
- continue;
- }
- nodeState = state->getNodeState(node->_region->getName(), saving);
- if (nodeState) {
- if (saving) {
- nodeState->_active = node->_region->_active;
- } else {
- node->_region->_active = nodeState->_active;
- }
- }
- break;
- default:
- warning("AdScene::PersistState - unhandled enum");
- break;
- }
- }
- }
-
- // free entities
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (!_objects[i]->_saveState) {
- continue;
- }
- if (_objects[i]->_type == OBJECT_ENTITY) {
- nodeState = state->getNodeState(_objects[i]->getName(), saving);
- if (nodeState) {
- nodeState->transferEntity((AdEntity *)_objects[i], _persistentStateSprites, saving);
- //if (Saving) NodeState->_active = _objects[i]->_active;
- //else _objects[i]->_active = NodeState->_active;
- }
- }
- }
-
- // waypoint groups
- for (uint32 i = 0; i < _waypointGroups.size(); i++) {
- nodeState = state->getNodeState(_waypointGroups[i]->getName(), saving);
- if (nodeState) {
- if (saving) {
- nodeState->_active = _waypointGroups[i]->_active;
- } else {
- _waypointGroups[i]->_active = nodeState->_active;
- }
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-float AdScene::getRotationAt(int x, int y) {
- AdRotLevel *prev = NULL;
- AdRotLevel *next = NULL;
-
- for (uint32 i = 0; i < _rotLevels.size(); i++) {
- /* AdRotLevel *xxx = _rotLevels[i];
- int j = _rotLevels.size();*/
- if (_rotLevels[i]->_posX < x) {
- prev = _rotLevels[i];
- } else {
- next = _rotLevels[i];
- break;
- }
- }
-
- if (prev == NULL || next == NULL) {
- return 0;
- }
-
- int delta_x = next->_posX - prev->_posX;
- float delta_rot = next->_rotation - prev->_rotation;
- x -= prev->_posX;
-
- float percent = (float)x / ((float)delta_x / 100.0f);
- return prev->_rotation + delta_rot / 100 * percent;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::handleItemAssociations(const char *itemName, bool show) {
- for (uint32 i = 0; i < _layers.size(); i++) {
- AdLayer *layer = _layers[i];
- for (uint32 j = 0; j < layer->_nodes.size(); j++) {
- if (layer->_nodes[j]->_type == OBJECT_ENTITY) {
- AdEntity *ent = layer->_nodes[j]->_entity;
-
- if (ent->_item && strcmp(ent->_item, itemName) == 0) {
- ent->_active = show;
- }
- }
- }
- }
-
- for (uint32 i = 0; i < _objects.size(); i++) {
- if (_objects[i]->_type == OBJECT_ENTITY) {
- AdEntity *ent = (AdEntity *)_objects[i];
- if (ent->_item && strcmp(ent->_item, itemName) == 0) {
- ent->_active = show;
- }
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getRegionsAt(int x, int y, AdRegion **regionList, int numRegions) {
- int numUsed = 0;
- if (_mainLayer) {
- for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
- AdSceneNode *node = _mainLayer->_nodes[i];
- if (node->_type == OBJECT_REGION && node->_region->_active && node->_region->pointInRegion(x, y)) {
- if (numUsed < numRegions - 1) {
- regionList[numUsed] = node->_region;
- numUsed++;
- } else {
- break;
- }
- }
- }
- }
- for (int i = numUsed; i < numRegions; i++) {
- regionList[i] = NULL;
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::restoreDeviceObjects() {
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseObject *AdScene::getNextAccessObject(BaseObject *currObject) {
- BaseArray<AdObject *> objects;
- getSceneObjects(objects, true);
-
- if (objects.size() == 0) {
- return NULL;
- } else {
- if (currObject != NULL) {
- for (uint32 i = 0; i < objects.size(); i++) {
- if (objects[i] == currObject) {
- if (i < objects.size() - 1) {
- return objects[i + 1];
- } else {
- break;
- }
- }
- }
- }
- return objects[0];
- }
- return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseObject *AdScene::getPrevAccessObject(BaseObject *currObject) {
- BaseArray<AdObject *> objects;
- getSceneObjects(objects, true);
-
- if (objects.size() == 0) {
- return NULL;
- } else {
- if (currObject != NULL) {
- for (int i = objects.size() - 1; i >= 0; i--) {
- if (objects[i] == currObject) {
- if (i > 0) {
- return objects[i - 1];
- } else {
- break;
- }
- }
- }
- }
- return objects[objects.size() - 1];
- }
- return NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getSceneObjects(BaseArray<AdObject *> &objects, bool interactiveOnly) {
- for (uint32 i = 0; i < _layers.size(); i++) {
- // close-up layer -> remove everything below it
- if (interactiveOnly && _layers[i]->_closeUp) {
- objects.clear();
- }
-
-
- for (uint32 j = 0; j < _layers[i]->_nodes.size(); j++) {
- AdSceneNode *node = _layers[i]->_nodes[j];
- switch (node->_type) {
- case OBJECT_ENTITY: {
- AdEntity *ent = node->_entity;
- if (ent->_active && (ent->_registrable || !interactiveOnly)) {
- objects.add(ent);
- }
- }
- break;
-
- case OBJECT_REGION: {
- BaseArray<AdObject *> regionObj;
- getRegionObjects(node->_region, regionObj, interactiveOnly);
- for (uint32 newIndex = 0; newIndex < regionObj.size(); newIndex++) {
- bool found = false;
- for (uint32 old = 0; old < objects.size(); old++) {
- if (objects[old] == regionObj[newIndex]) {
- found = true;
- break;
- }
- }
- if (!found) {
- objects.add(regionObj[newIndex]);
- }
- }
- //if (regionObj.size() > 0) Objects.Append(RegionObj);
- }
- break;
- default:
- debugC(kWintermuteDebugGeneral, "AdScene::GetSceneObjects - Unhandled enum");
- break;
- }
- }
- }
-
- // objects outside any region
- BaseArray<AdObject *> regionObj;
- getRegionObjects(NULL, regionObj, interactiveOnly);
- for (uint32 newIndex = 0; newIndex < regionObj.size(); newIndex++) {
- bool found = false;
- for (uint32 old = 0; old < objects.size(); old++) {
- if (objects[old] == regionObj[newIndex]) {
- found = true;
- break;
- }
- }
- if (!found) {
- objects.add(regionObj[newIndex]);
- }
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdScene::getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, bool interactiveOnly) {
- AdGame *adGame = (AdGame *)_gameRef;
- AdObject *obj;
-
- // global objects
- for (uint32 i = 0; i < adGame->_objects.size(); i++) {
- obj = adGame->_objects[i];
- if (obj->_active && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
- if (interactiveOnly && !obj->_registrable) {
- continue;
- }
-
- objects.add(obj);
- }
- }
-
- // scene objects
- for (uint32 i = 0; i < _objects.size(); i++) {
- obj = _objects[i];
- if (obj->_active && !obj->_editorOnly && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
- if (interactiveOnly && !obj->_registrable) {
- continue;
- }
-
- objects.add(obj);
- }
- }
-
- // sort by _posY
- Common::sort(objects.begin(), objects.end(), AdScene::compareObjs);
-
- 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/ad/ad_scene.h"
+#include "engines/wintermute/ad/ad_actor.h"
+#include "engines/wintermute/ad/ad_entity.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/ad/ad_layer.h"
+#include "engines/wintermute/ad/ad_node_state.h"
+#include "engines/wintermute/ad/ad_object.h"
+#include "engines/wintermute/ad/ad_path.h"
+#include "engines/wintermute/ad/ad_path_point.h"
+#include "engines/wintermute/ad/ad_rot_level.h"
+#include "engines/wintermute/ad/ad_scale_level.h"
+#include "engines/wintermute/ad/ad_scene_node.h"
+#include "engines/wintermute/ad/ad_scene_state.h"
+#include "engines/wintermute/ad/ad_sentence.h"
+#include "engines/wintermute/ad/ad_waypoint_group.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_object.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_point.h"
+#include "engines/wintermute/base/base_region.h"
+#include "engines/wintermute/base/base_scriptable.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_viewport.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/ui/ui_window.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/wintermute.h"
+#include <limits.h>
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdScene, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdScene::AdScene(BaseGame *inGame) : BaseObject(inGame) {
+ _pfTarget = new BasePoint;
+ setDefaults();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdScene::~AdScene() {
+ cleanup();
+ _gameRef->unregisterObject(_fader);
+ delete _pfTarget;
+ _pfTarget = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::setDefaults() {
+ _initialized = false;
+ _pfReady = true;
+ _pfTargetPath = NULL;
+ _pfRequester = NULL;
+ _mainLayer = NULL;
+
+ _pfPointsNum = 0;
+ _persistentState = false;
+ _persistentStateSprites = true;
+
+ _autoScroll = true;
+ _offsetLeft = _offsetTop = 0;
+ _targetOffsetLeft = _targetOffsetTop = 0;
+
+ _lastTimeH = _lastTimeV = 0;
+ _scrollTimeH = _scrollTimeV = 10;
+ _scrollPixelsH = _scrollPixelsV = 1;
+
+ _pfMaxTime = 15;
+
+ _paralaxScrolling = true;
+
+ // editor settings
+ _editorMarginH = _editorMarginV = 100;
+
+ _editorColFrame = 0xE0888888;
+ _editorColEntity = 0xFF008000;
+ _editorColRegion = 0xFF0000FF;
+ _editorColBlocked = 0xFF800080;
+ _editorColWaypoints = 0xFF0000FF;
+ _editorColEntitySel = 0xFFFF0000;
+ _editorColRegionSel = 0xFFFF0000;
+ _editorColBlockedSel = 0xFFFF0000;
+ _editorColWaypointsSel = 0xFFFF0000;
+ _editorColScale = 0xFF00FF00;
+ _editorColDecor = 0xFF00FFFF;
+ _editorColDecorSel = 0xFFFF0000;
+
+ _editorShowRegions = true;
+ _editorShowBlocked = true;
+ _editorShowDecor = true;
+ _editorShowEntities = true;
+ _editorShowScale = true;
+
+ _shieldWindow = NULL;
+
+ _fader = new BaseFader(_gameRef);
+ _gameRef->registerObject(_fader);
+
+ _viewport = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::cleanup() {
+ BaseObject::cleanup();
+
+ _mainLayer = NULL; // reference only
+
+ delete _shieldWindow;
+ _shieldWindow = NULL;
+
+ _gameRef->unregisterObject(_fader);
+ _fader = NULL;
+
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ _gameRef->unregisterObject(_layers[i]);
+ }
+ _layers.clear();
+
+
+ for (uint32 i = 0; i < _waypointGroups.size(); i++) {
+ _gameRef->unregisterObject(_waypointGroups[i]);
+ }
+ _waypointGroups.clear();
+
+ for (uint32 i = 0; i < _scaleLevels.size(); i++) {
+ _gameRef->unregisterObject(_scaleLevels[i]);
+ }
+ _scaleLevels.clear();
+
+ for (uint32 i = 0; i < _rotLevels.size(); i++) {
+ _gameRef->unregisterObject(_rotLevels[i]);
+ }
+ _rotLevels.clear();
+
+
+ for (uint32 i = 0; i < _pfPath.size(); i++) {
+ delete _pfPath[i];
+ }
+ _pfPath.clear();
+ _pfPointsNum = 0;
+
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ _gameRef->unregisterObject(_objects[i]);
+ }
+ _objects.clear();
+
+ delete _viewport;
+ _viewport = NULL;
+
+ setDefaults();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getPath(BasePoint source, BasePoint target, AdPath *path, BaseObject *requester) {
+ if (!_pfReady) {
+ return false;
+ } else {
+ _pfReady = false;
+ *_pfTarget = target;
+ _pfTargetPath = path;
+ _pfRequester = requester;
+
+ _pfTargetPath->reset();
+ _pfTargetPath->setReady(false);
+
+ // prepare working path
+ pfPointsStart();
+
+ // first point
+ //_pfPath.add(new AdPathPoint(source.x, source.y, 0));
+
+ // if we're one pixel stuck, get unstuck
+ int startX = source.x;
+ int startY = source.y;
+ int bestDistance = 1000;
+ if (isBlockedAt(startX, startY, true, requester)) {
+ int tolerance = 2;
+ for (int xxx = startX - tolerance; xxx <= startX + tolerance; xxx++) {
+ for (int yyy = startY - tolerance; yyy <= startY + tolerance; yyy++) {
+ if (isWalkableAt(xxx, yyy, true, requester)) {
+ int distance = abs(xxx - source.x) + abs(yyy - source.y);
+ if (distance < bestDistance) {
+ startX = xxx;
+ startY = yyy;
+
+ bestDistance = distance;
+ }
+ }
+ }
+ }
+ }
+
+ pfPointsAdd(startX, startY, 0);
+
+ //CorrectTargetPoint(&target.x, &target.y);
+
+ // last point
+ //_pfPath.add(new AdPathPoint(target.x, target.y, INT_MAX));
+ pfPointsAdd(target.x, target.y, INT_MAX);
+
+ // active waypoints
+ for (uint32 i = 0; i < _waypointGroups.size(); i++) {
+ if (_waypointGroups[i]->_active) {
+ pfAddWaypointGroup(_waypointGroups[i], requester);
+ }
+ }
+
+
+ // free waypoints
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentWptGroup) {
+ pfAddWaypointGroup(_objects[i]->_currentWptGroup, requester);
+ }
+ }
+ AdGame *adGame = (AdGame *)_gameRef;
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentWptGroup) {
+ pfAddWaypointGroup(adGame->_objects[i]->_currentWptGroup, requester);
+ }
+ }
+
+ return true;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::pfAddWaypointGroup(AdWaypointGroup *wpt, BaseObject *requester) {
+ if (!wpt->_active) {
+ return;
+ }
+
+ for (uint32 i = 0; i < wpt->_points.size(); i++) {
+ if (isBlockedAt(wpt->_points[i]->x, wpt->_points[i]->y, true, requester)) {
+ continue;
+ }
+
+ //_pfPath.add(new AdPathPoint(Wpt->_points[i]->x, Wpt->_points[i]->y, INT_MAX));
+ pfPointsAdd(wpt->_points[i]->x, wpt->_points[i]->y, INT_MAX);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+float AdScene::getZoomAt(int x, int y) {
+ float ret = 100;
+
+ bool found = false;
+ if (_mainLayer) {
+ for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_blocked && node->_region->pointInRegion(x, y)) {
+ if (node->_region->_zoom != 0) {
+ ret = node->_region->_zoom;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!found) {
+ ret = getScaleAt(y);
+ }
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 AdScene::getAlphaAt(int x, int y, bool colorCheck) {
+ if (!_gameRef->_debugDebugMode) {
+ colorCheck = false;
+ }
+
+ uint32 ret;
+ if (colorCheck) {
+ ret = 0xFFFF0000;
+ } else {
+ ret = 0xFFFFFFFF;
+ }
+
+ if (_mainLayer) {
+ for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ if (node->_type == OBJECT_REGION && node->_region->_active && (colorCheck || !node->_region->_blocked) && node->_region->pointInRegion(x, y)) {
+ if (!node->_region->_blocked) {
+ ret = node->_region->_alpha;
+ }
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::isBlockedAt(int x, int y, bool checkFreeObjects, BaseObject *requester) {
+ bool ret = true;
+
+ if (checkFreeObjects) {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentBlockRegion) {
+ if (_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
+ return true;
+ }
+ }
+ }
+ AdGame *adGame = (AdGame *)_gameRef;
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentBlockRegion) {
+ if (adGame->_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
+ return true;
+ }
+ }
+ }
+ }
+
+
+ if (_mainLayer) {
+ for (uint32 i = 0; i < _mainLayer->_nodes.size(); i++) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ /*
+ if (Node->_type == OBJECT_REGION && Node->_region->_active && Node->_region->_blocked && Node->_region->PointInRegion(X, Y))
+ {
+ ret = true;
+ break;
+ }
+ */
+ if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_decoration && node->_region->pointInRegion(x, y)) {
+ if (node->_region->_blocked) {
+ ret = true;
+ break;
+ } else {
+ ret = false;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::isWalkableAt(int x, int y, bool checkFreeObjects, BaseObject *requester) {
+ bool ret = false;
+
+ if (checkFreeObjects) {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && _objects[i] != requester && _objects[i]->_currentBlockRegion) {
+ if (_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
+ return false;
+ }
+ }
+ }
+ AdGame *adGame = (AdGame *)_gameRef;
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ if (adGame->_objects[i]->_active && adGame->_objects[i] != requester && adGame->_objects[i]->_currentBlockRegion) {
+ if (adGame->_objects[i]->_currentBlockRegion->pointInRegion(x, y)) {
+ return false;
+ }
+ }
+ }
+ }
+
+
+ if (_mainLayer) {
+ for (uint32 i = 0; i < _mainLayer->_nodes.size(); i++) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ if (node->_type == OBJECT_REGION && node->_region->_active && !node->_region->_decoration && node->_region->pointInRegion(x, y)) {
+ if (node->_region->_blocked) {
+ ret = false;
+ break;
+ } else {
+ ret = true;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdScene::getPointsDist(BasePoint p1, BasePoint p2, BaseObject *requester) {
+ double xStep, yStep, x, y;
+ int xLength, yLength, xCount, yCount;
+ int x1, y1, x2, y2;
+
+ x1 = p1.x;
+ y1 = p1.y;
+ x2 = p2.x;
+ y2 = p2.y;
+
+ xLength = abs(x2 - x1);
+ yLength = abs(y2 - y1);
+
+ if (xLength > yLength) {
+ if (x1 > x2) {
+ BaseUtils::swap(&x1, &x2);
+ BaseUtils::swap(&y1, &y2);
+ }
+
+ yStep = (double)(y2 - y1) / (double)(x2 - x1);
+ y = y1;
+
+ for (xCount = x1; xCount < x2; xCount++) {
+ if (isBlockedAt(xCount, (int)y, true, requester)) {
+ return -1;
+ }
+ y += yStep;
+ }
+ } else {
+ if (y1 > y2) {
+ BaseUtils::swap(&x1, &x2);
+ BaseUtils::swap(&y1, &y2);
+ }
+
+ xStep = (double)(x2 - x1) / (double)(y2 - y1);
+ x = x1;
+
+ for (yCount = y1; yCount < y2; yCount++) {
+ if (isBlockedAt((int)x, yCount, true, requester)) {
+ return -1;
+ }
+ x += xStep;
+ }
+ }
+ return MAX(xLength, yLength);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::pathFinderStep() {
+ int i;
+ // get lowest unmarked
+ int lowestDist = INT_MAX;
+ AdPathPoint *lowestPt = NULL;
+
+ for (i = 0; i < _pfPointsNum; i++)
+ if (!_pfPath[i]->_marked && _pfPath[i]->_distance < lowestDist) {
+ lowestDist = _pfPath[i]->_distance;
+ lowestPt = _pfPath[i];
+ }
+
+ if (lowestPt == NULL) { // no path -> terminate PathFinder
+ _pfReady = true;
+ _pfTargetPath->setReady(true);
+ return;
+ }
+
+ lowestPt->_marked = true;
+
+ // target point marked, generate path and terminate
+ if (lowestPt->x == _pfTarget->x && lowestPt->y == _pfTarget->y) {
+ while (lowestPt != NULL) {
+ _pfTargetPath->_points.insert_at(0, new BasePoint(lowestPt->x, lowestPt->y));
+ lowestPt = lowestPt->_origin;
+ }
+
+ _pfReady = true;
+ _pfTargetPath->setReady(true);
+ return;
+ }
+
+ // otherwise keep on searching
+ for (i = 0; i < _pfPointsNum; i++)
+ if (!_pfPath[i]->_marked) {
+ int j = getPointsDist(*lowestPt, *_pfPath[i], _pfRequester);
+ if (j != -1 && lowestPt->_distance + j < _pfPath[i]->_distance) {
+ _pfPath[i]->_distance = lowestPt->_distance + j;
+ _pfPath[i]->_origin = lowestPt;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::initLoop() {
+#ifdef _DEBUGxxxx
+ int nu_steps = 0;
+ uint32 start = _gameRef->_currentTime;
+ while (!_pfReady && g_system->getMillis() - start <= _pfMaxTime) {
+ PathFinderStep();
+ nu_steps++;
+ }
+ if (nu_steps > 0) {
+ _gameRef->LOG(0, "STAT: PathFinder iterations in one loop: %d (%s) _pfMaxTime=%d", nu_steps, _pfReady ? "finished" : "not yet done", _pfMaxTime);
+ }
+#else
+ uint32 start = _gameRef->_currentTime;
+ while (!_pfReady && g_system->getMillis() - start <= _pfMaxTime) {
+ pathFinderStep();
+ }
+#endif
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdScene::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing SCENE file '%s'", filename);
+ }
+
+ setFilename(filename);
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(SCENE)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(LAYER)
+TOKEN_DEF(WAYPOINTS)
+TOKEN_DEF(EVENTS)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(CAMERA)
+TOKEN_DEF(ENTITY)
+TOKEN_DEF(SCALE_LEVEL)
+TOKEN_DEF(ROTATION_LEVEL)
+TOKEN_DEF(EDITOR_MARGIN_H)
+TOKEN_DEF(EDITOR_MARGIN_V)
+TOKEN_DEF(EDITOR_COLOR_FRAME)
+TOKEN_DEF(EDITOR_COLOR_ENTITY_SEL)
+TOKEN_DEF(EDITOR_COLOR_REGION_SEL)
+TOKEN_DEF(EDITOR_COLOR_DECORATION_SEL)
+TOKEN_DEF(EDITOR_COLOR_BLOCKED_SEL)
+TOKEN_DEF(EDITOR_COLOR_WAYPOINTS_SEL)
+TOKEN_DEF(EDITOR_COLOR_REGION)
+TOKEN_DEF(EDITOR_COLOR_DECORATION)
+TOKEN_DEF(EDITOR_COLOR_BLOCKED)
+TOKEN_DEF(EDITOR_COLOR_ENTITY)
+TOKEN_DEF(EDITOR_COLOR_WAYPOINTS)
+TOKEN_DEF(EDITOR_COLOR_SCALE)
+TOKEN_DEF(EDITOR_SHOW_REGIONS)
+TOKEN_DEF(EDITOR_SHOW_BLOCKED)
+TOKEN_DEF(EDITOR_SHOW_DECORATION)
+TOKEN_DEF(EDITOR_SHOW_ENTITIES)
+TOKEN_DEF(EDITOR_SHOW_SCALE)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(VIEWPORT)
+TOKEN_DEF(PERSISTENT_STATE_SPRITES)
+TOKEN_DEF(PERSISTENT_STATE)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(SCENE)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(LAYER)
+ TOKEN_TABLE(WAYPOINTS)
+ TOKEN_TABLE(EVENTS)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(CAMERA)
+ TOKEN_TABLE(ENTITY)
+ TOKEN_TABLE(SCALE_LEVEL)
+ TOKEN_TABLE(ROTATION_LEVEL)
+ TOKEN_TABLE(EDITOR_MARGIN_H)
+ TOKEN_TABLE(EDITOR_MARGIN_V)
+ TOKEN_TABLE(EDITOR_COLOR_FRAME)
+ TOKEN_TABLE(EDITOR_COLOR_ENTITY_SEL)
+ TOKEN_TABLE(EDITOR_COLOR_REGION_SEL)
+ TOKEN_TABLE(EDITOR_COLOR_DECORATION_SEL)
+ TOKEN_TABLE(EDITOR_COLOR_BLOCKED_SEL)
+ TOKEN_TABLE(EDITOR_COLOR_WAYPOINTS_SEL)
+ TOKEN_TABLE(EDITOR_COLOR_REGION)
+ TOKEN_TABLE(EDITOR_COLOR_DECORATION)
+ TOKEN_TABLE(EDITOR_COLOR_BLOCKED)
+ TOKEN_TABLE(EDITOR_COLOR_ENTITY)
+ TOKEN_TABLE(EDITOR_COLOR_WAYPOINTS)
+ TOKEN_TABLE(EDITOR_COLOR_SCALE)
+ TOKEN_TABLE(EDITOR_SHOW_REGIONS)
+ TOKEN_TABLE(EDITOR_SHOW_DECORATION)
+ TOKEN_TABLE(EDITOR_SHOW_BLOCKED)
+ TOKEN_TABLE(EDITOR_SHOW_ENTITIES)
+ TOKEN_TABLE(EDITOR_SHOW_SCALE)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(VIEWPORT)
+ TOKEN_TABLE(PERSISTENT_STATE_SPRITES)
+ TOKEN_TABLE(PERSISTENT_STATE)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ cleanup();
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCENE) {
+ _gameRef->LOG(0, "'SCENE' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ int ar, ag, ab, aa;
+ char camera[MAX_PATH_LENGTH] = "";
+ /* float waypointHeight = -1.0f; */
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ setCaption((char *)params);
+ break;
+
+ case TOKEN_LAYER: {
+ AdLayer *layer = new AdLayer(_gameRef);
+ if (!layer || DID_FAIL(layer->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete layer;
+ layer = NULL;
+ } else {
+ _gameRef->registerObject(layer);
+ _layers.add(layer);
+ if (layer->_main) {
+ _mainLayer = layer;
+ _width = layer->_width;
+ _height = layer->_height;
+ }
+ }
+ }
+ break;
+
+ case TOKEN_WAYPOINTS: {
+ AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
+ if (!wpt || DID_FAIL(wpt->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete wpt;
+ wpt = NULL;
+ } else {
+ _gameRef->registerObject(wpt);
+ _waypointGroups.add(wpt);
+ }
+ }
+ break;
+
+ case TOKEN_SCALE_LEVEL: {
+ AdScaleLevel *sl = new AdScaleLevel(_gameRef);
+ if (!sl || DID_FAIL(sl->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete sl;
+ sl = NULL;
+ } else {
+ _gameRef->registerObject(sl);
+ _scaleLevels.add(sl);
+ }
+ }
+ break;
+
+ case TOKEN_ROTATION_LEVEL: {
+ AdRotLevel *rl = new AdRotLevel(_gameRef);
+ if (!rl || DID_FAIL(rl->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete rl;
+ rl = NULL;
+ } else {
+ _gameRef->registerObject(rl);
+ _rotLevels.add(rl);
+ }
+ }
+ break;
+
+ case TOKEN_ENTITY: {
+ AdEntity *entity = new AdEntity(_gameRef);
+ if (!entity || DID_FAIL(entity->loadBuffer(params, false))) {
+ cmd = PARSERR_GENERIC;
+ delete entity;
+ entity = NULL;
+ } else {
+ addObject(entity);
+ }
+ }
+ break;
+
+ case TOKEN_CURSOR:
+ delete _cursor;
+ _cursor = new BaseSprite(_gameRef);
+ if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ delete _cursor;
+ _cursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_CAMERA:
+ strcpy(camera, (char *)params);
+ break;
+
+ case TOKEN_EDITOR_MARGIN_H:
+ parser.scanStr((char *)params, "%d", &_editorMarginH);
+ break;
+
+ case TOKEN_EDITOR_MARGIN_V:
+ parser.scanStr((char *)params, "%d", &_editorMarginV);
+ break;
+
+ case TOKEN_EDITOR_COLOR_FRAME:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColFrame = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_ENTITY:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColEntity = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_ENTITY_SEL:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColEntitySel = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_REGION_SEL:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColRegionSel = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_DECORATION_SEL:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColDecorSel = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_BLOCKED_SEL:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColBlockedSel = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_WAYPOINTS_SEL:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColWaypointsSel = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_REGION:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColRegion = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_DECORATION:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColDecor = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_BLOCKED:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColBlocked = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_WAYPOINTS:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColWaypoints = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_COLOR_SCALE:
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ _editorColScale = BYTETORGBA(ar, ag, ab, aa);
+ break;
+
+ case TOKEN_EDITOR_SHOW_REGIONS:
+ parser.scanStr((char *)params, "%b", &_editorShowRegions);
+ break;
+
+ case TOKEN_EDITOR_SHOW_BLOCKED:
+ parser.scanStr((char *)params, "%b", &_editorShowBlocked);
+ break;
+
+ case TOKEN_EDITOR_SHOW_DECORATION:
+ parser.scanStr((char *)params, "%b", &_editorShowDecor);
+ break;
+
+ case TOKEN_EDITOR_SHOW_ENTITIES:
+ parser.scanStr((char *)params, "%b", &_editorShowEntities);
+ break;
+
+ case TOKEN_EDITOR_SHOW_SCALE:
+ parser.scanStr((char *)params, "%b", &_editorShowScale);
+ break;
+
+ case TOKEN_SCRIPT:
+ addScript((char *)params);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_VIEWPORT: {
+ Rect32 rc;
+ parser.scanStr((char *)params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ if (!_viewport) {
+ _viewport = new BaseViewport(_gameRef);
+ }
+ if (_viewport) {
+ _viewport->setRect(rc.left, rc.top, rc.right, rc.bottom, true);
+ }
+ }
+
+ case TOKEN_PERSISTENT_STATE:
+ parser.scanStr((char *)params, "%b", &_persistentState);
+ break;
+
+ case TOKEN_PERSISTENT_STATE_SPRITES:
+ parser.scanStr((char *)params, "%b", &_persistentStateSprites);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in SCENE definition");
+ return STATUS_FAILED;
+ }
+
+ if (_mainLayer == NULL) {
+ _gameRef->LOG(0, "Warning: scene '%s' has no main layer.", getFilename());
+ }
+
+
+ sortScaleLevels();
+ sortRotLevels();
+
+ _initialized = true;
+
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::traverseNodes(bool doUpdate) {
+ if (!_initialized) {
+ return STATUS_OK;
+ }
+
+ AdGame *adGame = (AdGame *)_gameRef;
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // prepare viewport
+ bool popViewport = false;
+ if (_viewport && !_gameRef->_editorMode) {
+ _gameRef->pushViewport(_viewport);
+ popViewport = true;
+ } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
+ _gameRef->pushViewport(adGame->_sceneViewport);
+ popViewport = true;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // *** adjust scroll offset
+ if (doUpdate) {
+ /*
+ if (_autoScroll && _gameRef->_mainObject != NULL)
+ {
+ ScrollToObject(_gameRef->_mainObject);
+ }
+ */
+
+ if (_autoScroll) {
+ // adjust horizontal scroll
+ if (_gameRef->_timer - _lastTimeH >= _scrollTimeH) {
+ _lastTimeH = _gameRef->_timer;
+ if (_offsetLeft < _targetOffsetLeft) {
+ _offsetLeft += _scrollPixelsH;
+ _offsetLeft = MIN(_offsetLeft, _targetOffsetLeft);
+ } else if (_offsetLeft > _targetOffsetLeft) {
+ _offsetLeft -= _scrollPixelsH;
+ _offsetLeft = MAX(_offsetLeft, _targetOffsetLeft);
+ }
+ }
+
+ // adjust vertical scroll
+ if (_gameRef->_timer - _lastTimeV >= _scrollTimeV) {
+ _lastTimeV = _gameRef->_timer;
+ if (_offsetTop < _targetOffsetTop) {
+ _offsetTop += _scrollPixelsV;
+ _offsetTop = MIN(_offsetTop, _targetOffsetTop);
+ } else if (_offsetTop > _targetOffsetTop) {
+ _offsetTop -= _scrollPixelsV;
+ _offsetTop = MAX(_offsetTop, _targetOffsetTop);
+ }
+ }
+
+ if (_offsetTop == _targetOffsetTop && _offsetLeft == _targetOffsetLeft) {
+ _ready = true;
+ }
+ } else {
+ _ready = true; // not scrolling, i.e. always ready
+ }
+ }
+
+
+
+
+ //////////////////////////////////////////////////////////////////////////
+ int viewportWidth, viewportHeight;
+ getViewportSize(&viewportWidth, &viewportHeight);
+
+ int viewportX, viewportY;
+ getViewportOffset(&viewportX, &viewportY);
+
+ int scrollableX = _width - viewportWidth;
+ int scrollableY = _height - viewportHeight;
+
+ double widthRatio = scrollableX <= 0 ? 0 : ((double)(_offsetLeft) / (double)scrollableX);
+ double heightRatio = scrollableY <= 0 ? 0 : ((double)(_offsetTop) / (double)scrollableY);
+
+ int origX, origY;
+ _gameRef->getOffset(&origX, &origY);
+
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // *** display/update everything
+ _gameRef->_renderer->setup2D();
+
+ // for each layer
+ /* int mainOffsetX = 0; */
+ /* int mainOffsetY = 0; */
+
+ for (uint32 j = 0; j < _layers.size(); j++) {
+ if (!_layers[j]->_active) {
+ continue;
+ }
+
+ // make layer exclusive
+ if (!doUpdate) {
+ if (_layers[j]->_closeUp && !_gameRef->_editorMode) {
+ if (!_shieldWindow) {
+ _shieldWindow = new UIWindow(_gameRef);
+ }
+ if (_shieldWindow) {
+ _shieldWindow->_posX = _shieldWindow->_posY = 0;
+ _shieldWindow->_width = _gameRef->_renderer->_width;
+ _shieldWindow->_height = _gameRef->_renderer->_height;
+ _shieldWindow->display();
+ }
+ }
+ }
+
+ if (_paralaxScrolling) {
+ int offsetX = (int)(widthRatio * (_layers[j]->_width - viewportWidth) - viewportX);
+ int offsetY = (int)(heightRatio * (_layers[j]->_height - viewportHeight) - viewportY);
+ _gameRef->setOffset(offsetX, offsetY);
+
+ _gameRef->_offsetPercentX = (float)offsetX / ((float)_layers[j]->_width - viewportWidth) * 100.0f;
+ _gameRef->_offsetPercentY = (float)offsetY / ((float)_layers[j]->_height - viewportHeight) * 100.0f;
+
+ //_gameRef->QuickMessageForm("%d %f", OffsetX+ViewportX, _gameRef->_offsetPercentX);
+ } else {
+ _gameRef->setOffset(_offsetLeft - viewportX, _offsetTop - viewportY);
+
+ _gameRef->_offsetPercentX = (float)(_offsetLeft - viewportX) / ((float)_layers[j]->_width - viewportWidth) * 100.0f;
+ _gameRef->_offsetPercentY = (float)(_offsetTop - viewportY) / ((float)_layers[j]->_height - viewportHeight) * 100.0f;
+ }
+
+
+ // for each node
+ for (uint32 k = 0; k < _layers[j]->_nodes.size(); k++) {
+ AdSceneNode *node = _layers[j]->_nodes[k];
+ switch (node->_type) {
+ case OBJECT_ENTITY:
+ if (node->_entity->_active && (_gameRef->_editorMode || !node->_entity->_editorOnly)) {
+ _gameRef->_renderer->setup2D();
+
+ if (doUpdate) {
+ node->_entity->update();
+ } else {
+ node->_entity->display();
+ }
+ }
+ break;
+
+ case OBJECT_REGION: {
+ if (node->_region->_blocked) {
+ break;
+ }
+ if (node->_region->_decoration) {
+ break;
+ }
+
+ if (!doUpdate) {
+ displayRegionContent(node->_region);
+ }
+ }
+ break;
+ default:
+ error("AdScene::TraverseNodes - Unhandled enum");
+ break;
+ } // switch
+ } // each node
+
+ // display/update all objects which are off-regions
+ if (_layers[j]->_main) {
+ if (doUpdate) {
+ updateFreeObjects();
+ } else {
+ displayRegionContent(NULL);
+ }
+ }
+ } // each layer
+
+
+ // restore state
+ _gameRef->setOffset(origX, origY);
+ _gameRef->_renderer->setup2D();
+
+ // display/update fader
+ if (_fader) {
+ if (doUpdate) {
+ _fader->update();
+ } else {
+ _fader->display();
+ }
+ }
+
+ if (popViewport) {
+ _gameRef->popViewport();
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::display() {
+ return traverseNodes(false);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::updateFreeObjects() {
+ AdGame *adGame = (AdGame *)_gameRef;
+ // 3D-code removed
+ // bool is3DSet;
+
+ // *** update all active objects
+ // is3DSet = false;
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ if (!adGame->_objects[i]->_active) {
+ continue;
+ }
+ // 3D-code removed
+ adGame->_objects[i]->update();
+ adGame->_objects[i]->_drawn = false;
+ }
+
+
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (!_objects[i]->_active) {
+ continue;
+ }
+
+ _objects[i]->update();
+ _objects[i]->_drawn = false;
+ }
+
+
+ if (_autoScroll && _gameRef->_mainObject != NULL) {
+ scrollToObject(_gameRef->_mainObject);
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::displayRegionContent(AdRegion *region, bool display3DOnly) {
+ AdGame *adGame = (AdGame *)_gameRef;
+ BaseArray<AdObject *> objects;
+ AdObject *obj;
+
+ // global objects
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ obj = adGame->_objects[i];
+ if (obj->_active && !obj->_drawn && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
+ objects.add(obj);
+ }
+ }
+
+ // scene objects
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ obj = _objects[i];
+ if (obj->_active && !obj->_editorOnly && !obj->_drawn && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
+ objects.add(obj);
+ }
+ }
+
+ // sort by _posY
+ Common::sort(objects.begin(), objects.end(), AdScene::compareObjs);
+
+ // display them
+ for (uint32 i = 0; i < objects.size(); i++) {
+ obj = objects[i];
+
+ if (display3DOnly && !obj->_is3D) {
+ continue;
+ }
+
+ _gameRef->_renderer->setup2D();
+
+ if (_gameRef->_editorMode || !obj->_editorOnly) {
+ obj->display();
+ }
+ obj->_drawn = true;
+ }
+
+
+ // display design only objects
+ if (!display3DOnly) {
+ if (_gameRef->_editorMode && region == NULL) {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && _objects[i]->_editorOnly) {
+ _objects[i]->display();
+ _objects[i]->_drawn = true;
+ }
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int AdScene::compareObjs(const void *obj1, const void *obj2) {
+ const AdObject *object1 = *(const AdObject *const *)obj1;
+ const AdObject *object2 = *(const AdObject *const *)obj2;
+
+ if (object1->_posY < object2->_posY) {
+ return -1;
+ } else if (object1->_posY > object2->_posY) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::displayRegionContentOld(AdRegion *region) {
+ AdGame *adGame = (AdGame *)_gameRef;
+ AdObject *obj;
+
+ // display all objects in region sorted by _posY
+ do {
+ obj = NULL;
+ int minY = INT_MAX;
+
+ // global objects
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ if (adGame->_objects[i]->_active && !adGame->_objects[i]->_drawn && adGame->_objects[i]->_posY < minY && (adGame->_objects[i]->_stickRegion == region || region == NULL || (adGame->_objects[i]->_stickRegion == NULL && region->pointInRegion(adGame->_objects[i]->_posX, adGame->_objects[i]->_posY)))) {
+ obj = adGame->_objects[i];
+ minY = adGame->_objects[i]->_posY;
+ }
+ }
+
+ // scene objects
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && !_objects[i]->_editorOnly && !_objects[i]->_drawn && _objects[i]->_posY < minY && (_objects[i]->_stickRegion == region || region == NULL || (_objects[i]->_stickRegion == NULL && region->pointInRegion(_objects[i]->_posX, _objects[i]->_posY)))) {
+ obj = _objects[i];
+ minY = _objects[i]->_posY;
+ }
+ }
+
+
+ if (obj != NULL) {
+ _gameRef->_renderer->setup2D();
+
+ if (_gameRef->_editorMode || !obj->_editorOnly) {
+ obj->display();
+ }
+ obj->_drawn = true;
+ }
+ } while (obj != NULL);
+
+
+ // design only objects
+ if (_gameRef->_editorMode && region == NULL) {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_active && _objects[i]->_editorOnly) {
+ _objects[i]->display();
+ _objects[i]->_drawn = true;
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::update() {
+ return traverseNodes(true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::scrollTo(int offsetX, int offsetY) {
+ int viewportWidth, viewportHeight;
+ getViewportSize(&viewportWidth, &viewportHeight);
+
+ int origOffsetLeft = _targetOffsetLeft;
+ int origOffsetTop = _targetOffsetTop;
+
+ _targetOffsetLeft = MAX(0, offsetX - viewportWidth / 2);
+ _targetOffsetLeft = MIN(_targetOffsetLeft, _width - viewportWidth);
+
+ _targetOffsetTop = MAX(0, offsetY - viewportHeight / 2);
+ _targetOffsetTop = MIN(_targetOffsetTop, _height - viewportHeight);
+
+
+ if (_gameRef->_mainObject && _gameRef->_mainObject->_is3D) {
+ if (abs(origOffsetLeft - _targetOffsetLeft) < 5) {
+ _targetOffsetLeft = origOffsetLeft;
+ }
+ if (abs(origOffsetTop - _targetOffsetTop) < 5) {
+ _targetOffsetTop = origOffsetTop;
+ }
+ //_targetOffsetTop = 0;
+ }
+
+ _ready = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::scrollToObject(BaseObject *object) {
+ if (object) {
+ scrollTo(object->_posX, object->_posY - object->getHeight() / 2);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::skipToObject(BaseObject *object) {
+ if (object) {
+ skipTo(object->_posX, object->_posY - object->getHeight() / 2);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::skipTo(int offsetX, int offsetY) {
+ int viewportWidth, viewportHeight;
+ getViewportSize(&viewportWidth, &viewportHeight);
+
+ _offsetLeft = MAX(0, offsetX - viewportWidth / 2);
+ _offsetLeft = MIN(_offsetLeft, _width - viewportWidth);
+
+ _offsetTop = MAX(0, offsetY - viewportHeight / 2);
+ _offsetTop = MIN(_offsetTop, _height - viewportHeight);
+
+ _targetOffsetLeft = _offsetLeft;
+ _targetOffsetTop = _offsetTop;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // LoadActor
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "LoadActor") == 0) {
+ stack->correctParams(1);
+ AdActor *act = new AdActor(_gameRef);
+ if (act && DID_SUCCEED(act->loadFile(stack->pop()->getString()))) {
+ addObject(act);
+ stack->pushNative(act, true);
+ } else {
+ delete act;
+ act = NULL;
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "LoadEntity") == 0) {
+ stack->correctParams(1);
+ AdEntity *ent = new AdEntity(_gameRef);
+ if (ent && DID_SUCCEED(ent->loadFile(stack->pop()->getString()))) {
+ addObject(ent);
+ stack->pushNative(ent, true);
+ } else {
+ delete ent;
+ ent = NULL;
+ stack->pushNULL();
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "CreateEntity") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdEntity *ent = new AdEntity(_gameRef);
+ addObject(ent);
+ if (!val->isNULL()) {
+ ent->setName(val->getString());
+ }
+ stack->pushNative(ent, true);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // UnloadObject / UnloadActor / UnloadEntity / UnloadActor3D / DeleteEntity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "UnloadObject") == 0 || strcmp(name, "UnloadActor") == 0 || strcmp(name, "UnloadEntity") == 0 || strcmp(name, "UnloadActor3D") == 0 || strcmp(name, "DeleteEntity") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ AdObject *obj = (AdObject *)val->getNative();
+ removeObject(obj);
+ if (val->getType() == VAL_VARIABLE_REF) {
+ val->setNULL();
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SkipTo
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SkipTo") == 0) {
+ stack->correctParams(2);
+ ScValue *val1 = stack->pop();
+ ScValue *val2 = stack->pop();
+ if (val1->isNative()) {
+ skipToObject((BaseObject *)val1->getNative());
+ } else {
+ skipTo(val1->getInt(), val2->getInt());
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollTo / ScrollToAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollTo") == 0 || strcmp(name, "ScrollToAsync") == 0) {
+ stack->correctParams(2);
+ ScValue *val1 = stack->pop();
+ ScValue *val2 = stack->pop();
+ if (val1->isNative()) {
+ scrollToObject((BaseObject *)val1->getNative());
+ } else {
+ scrollTo(val1->getInt(), val2->getInt());
+ }
+ if (strcmp(name, "ScrollTo") == 0) {
+ script->waitForExclusive(this);
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetLayer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetLayer") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+ if (val->isInt()) {
+ int layer = val->getInt();
+ if (layer < 0 || layer >= (int32)_layers.size()) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_layers[layer], true);
+ }
+ } else {
+ const char *layerName = val->getString();
+ bool layerFound = false;
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ if (scumm_stricmp(layerName, _layers[i]->getName()) == 0) {
+ stack->pushNative(_layers[i], true);
+ layerFound = true;
+ break;
+ }
+ }
+ if (!layerFound) {
+ stack->pushNULL();
+ }
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetWaypointGroup
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetWaypointGroup") == 0) {
+ stack->correctParams(1);
+ int group = stack->pop()->getInt();
+ if (group < 0 || group >= (int32)_waypointGroups.size()) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_waypointGroups[group], true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetNode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetNode") == 0) {
+ stack->correctParams(1);
+ const char *nodeName = stack->pop()->getString();
+
+ BaseObject *node = getNodeByName(nodeName);
+ if (node) {
+ stack->pushNative((BaseScriptable *)node, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFreeNode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetFreeNode") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdObject *ret = NULL;
+ if (val->isInt()) {
+ int index = val->getInt();
+ if (index >= 0 && index < (int32)_objects.size()) {
+ ret = _objects[index];
+ }
+ } else {
+ const char *nodeName = val->getString();
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i] && _objects[i]->getName() && scumm_stricmp(_objects[i]->getName(), nodeName) == 0) {
+ ret = _objects[i];
+ break;
+ }
+ }
+ }
+ if (ret) {
+ stack->pushNative(ret, true);
+ } else {
+ stack->pushNULL();
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetRegionAt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetRegionAt") == 0) {
+ stack->correctParams(3);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+ ScValue *val = stack->pop();
+
+ bool includeDecors = false;
+ if (!val->isNULL()) {
+ includeDecors = val->getBool();
+ }
+
+ if (_mainLayer) {
+ for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ if (node->_type == OBJECT_REGION && node->_region->_active && node->_region->pointInRegion(x, y)) {
+ if (node->_region->_decoration && !includeDecors) {
+ continue;
+ }
+
+ stack->pushNative(node->_region, true);
+ return STATUS_OK;
+ }
+ }
+ }
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsBlockedAt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsBlockedAt") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+
+ stack->pushBool(isBlockedAt(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsWalkableAt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsWalkableAt") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+
+ stack->pushBool(isWalkableAt(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetScaleAt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetScaleAt") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+
+ stack->pushFloat(getZoomAt(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetRotationAt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetRotationAt") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+
+ stack->pushFloat(getRotationAt(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsScrolling
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsScrolling") == 0) {
+ stack->correctParams(0);
+ bool ret = false;
+ if (_autoScroll) {
+ if (_targetOffsetLeft != _offsetLeft || _targetOffsetTop != _offsetTop) {
+ ret = true;
+ }
+ }
+
+ stack->pushBool(ret);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FadeOut / FadeOutAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "FadeOut") == 0 || strcmp(name, "FadeOutAsync") == 0) {
+ stack->correctParams(5);
+ uint32 duration = stack->pop()->getInt(500);
+ byte red = stack->pop()->getInt(0);
+ byte green = stack->pop()->getInt(0);
+ byte blue = stack->pop()->getInt(0);
+ byte alpha = stack->pop()->getInt(0xFF);
+
+ _fader->fadeOut(BYTETORGBA(red, green, blue, alpha), duration);
+ if (strcmp(name, "FadeOutAsync") != 0) {
+ script->waitFor(_fader);
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FadeIn / FadeInAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "FadeIn") == 0 || strcmp(name, "FadeInAsync") == 0) {
+ stack->correctParams(5);
+ uint32 duration = stack->pop()->getInt(500);
+ byte red = stack->pop()->getInt(0);
+ byte green = stack->pop()->getInt(0);
+ byte blue = stack->pop()->getInt(0);
+ byte alpha = stack->pop()->getInt(0xFF);
+
+ _fader->fadeIn(BYTETORGBA(red, green, blue, alpha), duration);
+ if (strcmp(name, "FadeInAsync") != 0) {
+ script->waitFor(_fader);
+ }
+
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFadeColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetFadeColor") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(_fader->getCurrentColor());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsPointInViewport
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsPointInViewport") == 0) {
+ stack->correctParams(2);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+ stack->pushBool(pointInViewport(x, y));
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetViewport
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetViewport") == 0) {
+ stack->correctParams(4);
+ int x = stack->pop()->getInt();
+ int y = stack->pop()->getInt();
+ int width = stack->pop()->getInt();
+ int height = stack->pop()->getInt();
+
+ if (width <= 0) {
+ width = _gameRef->_renderer->_width;
+ }
+ if (height <= 0) {
+ height = _gameRef->_renderer->_height;
+ }
+
+ if (!_viewport) {
+ _viewport = new BaseViewport(_gameRef);
+ }
+ if (_viewport) {
+ _viewport->setRect(x, y, x + width, y + height);
+ }
+
+ stack->pushBool(true);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddLayer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddLayer") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdLayer *layer = new AdLayer(_gameRef);
+ if (!val->isNULL()) {
+ layer->setName(val->getString());
+ }
+ if (_mainLayer) {
+ layer->_width = _mainLayer->_width;
+ layer->_height = _mainLayer->_height;
+ }
+ _layers.add(layer);
+ _gameRef->registerObject(layer);
+
+ stack->pushNative(layer, true);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InsertLayer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "InsertLayer") == 0) {
+ stack->correctParams(2);
+ int index = stack->pop()->getInt();
+ ScValue *val = stack->pop();
+
+ AdLayer *layer = new AdLayer(_gameRef);
+ if (!val->isNULL()) {
+ layer->setName(val->getString());
+ }
+ if (_mainLayer) {
+ layer->_width = _mainLayer->_width;
+ layer->_height = _mainLayer->_height;
+ }
+ if (index < 0) {
+ index = 0;
+ }
+ if (index <= (int32)_layers.size() - 1) {
+ _layers.insert_at(index, layer);
+ } else {
+ _layers.add(layer);
+ }
+
+ _gameRef->registerObject(layer);
+
+ stack->pushNative(layer, true);
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteLayer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DeleteLayer") == 0) {
+ stack->correctParams(1);
+ ScValue *val = stack->pop();
+
+ AdLayer *toDelete = NULL;
+ if (val->isNative()) {
+ BaseScriptable *temp = val->getNative();
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ if (_layers[i] == temp) {
+ toDelete = _layers[i];
+ break;
+ }
+ }
+ } else {
+ int index = val->getInt();
+ if (index >= 0 && index < (int32)_layers.size()) {
+ toDelete = _layers[index];
+ }
+ }
+ if (toDelete == NULL) {
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ if (toDelete->_main) {
+ script->runtimeError("Scene.DeleteLayer - cannot delete main scene layer");
+ stack->pushBool(false);
+ return STATUS_OK;
+ }
+
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ if (_layers[i] == toDelete) {
+ _layers.remove_at(i);
+ _gameRef->unregisterObject(toDelete);
+ break;
+ }
+ }
+ stack->pushBool(true);
+ return STATUS_OK;
+ } else {
+ return BaseObject::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdScene::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("scene");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumLayers (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumLayers") == 0) {
+ _scValue->setInt(_layers.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumWaypointGroups (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumWaypointGroups") == 0) {
+ _scValue->setInt(_waypointGroups.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MainLayer (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "MainLayer") == 0) {
+ if (_mainLayer) {
+ _scValue->setNative(_mainLayer, true);
+ } else {
+ _scValue->setNULL();
+ }
+
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumFreeNodes (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumFreeNodes") == 0) {
+ _scValue->setInt(_objects.size());
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseX (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "MouseX") == 0) {
+ int viewportX;
+ getViewportOffset(&viewportX);
+
+ _scValue->setInt(_gameRef->_mousePos.x + _offsetLeft - viewportX);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseY (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "MouseY") == 0) {
+ int viewportY;
+ getViewportOffset(NULL, &viewportY);
+
+ _scValue->setInt(_gameRef->_mousePos.y + _offsetTop - viewportY);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoScroll
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AutoScroll") == 0) {
+ _scValue->setBool(_autoScroll);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PersistentState
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PersistentState") == 0) {
+ _scValue->setBool(_persistentState);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PersistentStateSprites
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PersistentStateSprites") == 0) {
+ _scValue->setBool(_persistentStateSprites);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollPixelsX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollPixelsX") == 0) {
+ _scValue->setInt(_scrollPixelsH);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollPixelsY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollPixelsY") == 0) {
+ _scValue->setInt(_scrollPixelsV);
+ return _scValue;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollSpeedX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollSpeedX") == 0) {
+ _scValue->setInt(_scrollTimeH);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollSpeedY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollSpeedY") == 0) {
+ _scValue->setInt(_scrollTimeV);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OffsetX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "OffsetX") == 0) {
+ _scValue->setInt(_offsetLeft);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OffsetY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "OffsetY") == 0) {
+ _scValue->setInt(_offsetTop);
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Width (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Width") == 0) {
+ if (_mainLayer) {
+ _scValue->setInt(_mainLayer->_width);
+ } else {
+ _scValue->setInt(0);
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Height (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Height") == 0) {
+ if (_mainLayer) {
+ _scValue->setInt(_mainLayer->_height);
+ } else {
+ _scValue->setInt(0);
+ }
+ return _scValue;
+ } else {
+ return BaseObject::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Name") == 0) {
+ setName(value->getString());
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoScroll
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AutoScroll") == 0) {
+ _autoScroll = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PersistentState
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PersistentState") == 0) {
+ _persistentState = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PersistentStateSprites
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "PersistentStateSprites") == 0) {
+ _persistentStateSprites = value->getBool();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollPixelsX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollPixelsX") == 0) {
+ _scrollPixelsH = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollPixelsY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollPixelsY") == 0) {
+ _scrollPixelsV = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollSpeedX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollSpeedX") == 0) {
+ _scrollTimeH = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScrollSpeedY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ScrollSpeedY") == 0) {
+ _scrollTimeV = value->getInt();
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OffsetX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "OffsetX") == 0) {
+ _offsetLeft = value->getInt();
+
+ int viewportWidth, viewportHeight;
+ getViewportSize(&viewportWidth, &viewportHeight);
+
+ _offsetLeft = MAX(0, _offsetLeft - viewportWidth / 2);
+ _offsetLeft = MIN(_offsetLeft, _width - viewportWidth);
+ _targetOffsetLeft = _offsetLeft;
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OffsetY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "OffsetY") == 0) {
+ _offsetTop = value->getInt();
+
+ int viewportWidth, viewportHeight;
+ getViewportSize(&viewportWidth, &viewportHeight);
+
+ _offsetTop = MAX(0, _offsetTop - viewportHeight / 2);
+ _offsetTop = MIN(_offsetTop, _height - viewportHeight);
+ _targetOffsetTop = _offsetTop;
+
+ return STATUS_OK;
+ } else {
+ return BaseObject::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdScene::scToString() {
+ return "[scene object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::addObject(AdObject *object) {
+ _objects.add(object);
+ return _gameRef->registerObject(object);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::removeObject(AdObject *object) {
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i] == object) {
+ _objects.remove_at(i);
+ return _gameRef->unregisterObject(object);
+ }
+ }
+ return STATUS_FAILED;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "SCENE {\n");
+
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
+
+ if (_persistentState) {
+ buffer->putTextIndent(indent + 2, "PERSISTENT_STATE=%s\n", _persistentState ? "TRUE" : "FALSE");
+ }
+
+ if (!_persistentStateSprites) {
+ buffer->putTextIndent(indent + 2, "PERSISTENT_STATE_SPRITES=%s\n", _persistentStateSprites ? "TRUE" : "FALSE");
+ }
+
+
+ // scripts
+ for (uint32 i = 0; i < _scripts.size(); i++) {
+ buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
+ }
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // properties
+ if (_scProp) {
+ _scProp->saveAsText(buffer, indent + 2);
+ }
+
+ // viewport
+ if (_viewport) {
+ Rect32 *rc = _viewport->getRect();
+ buffer->putTextIndent(indent + 2, "VIEWPORT { %d, %d, %d, %d }\n", rc->left, rc->top, rc->right, rc->bottom);
+ }
+
+
+
+ // editor settings
+ buffer->putTextIndent(indent + 2, "; ----- editor settings\n");
+ buffer->putTextIndent(indent + 2, "EDITOR_MARGIN_H=%d\n", _editorMarginH);
+ buffer->putTextIndent(indent + 2, "EDITOR_MARGIN_V=%d\n", _editorMarginV);
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_FRAME { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColFrame), RGBCOLGetG(_editorColFrame), RGBCOLGetB(_editorColFrame), RGBCOLGetA(_editorColFrame));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_ENTITY_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColEntitySel), RGBCOLGetG(_editorColEntitySel), RGBCOLGetB(_editorColEntitySel), RGBCOLGetA(_editorColEntitySel));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_REGION_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColRegionSel), RGBCOLGetG(_editorColRegionSel), RGBCOLGetB(_editorColRegionSel), RGBCOLGetA(_editorColRegionSel));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_BLOCKED_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColBlockedSel), RGBCOLGetG(_editorColBlockedSel), RGBCOLGetB(_editorColBlockedSel), RGBCOLGetA(_editorColBlockedSel));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_DECORATION_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColDecorSel), RGBCOLGetG(_editorColDecorSel), RGBCOLGetB(_editorColDecorSel), RGBCOLGetA(_editorColDecorSel));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_WAYPOINTS_SEL { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColWaypointsSel), RGBCOLGetG(_editorColWaypointsSel), RGBCOLGetB(_editorColWaypointsSel), RGBCOLGetA(_editorColWaypointsSel));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_ENTITY { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColEntity), RGBCOLGetG(_editorColEntity), RGBCOLGetB(_editorColEntity), RGBCOLGetA(_editorColEntity));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_REGION { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColRegion), RGBCOLGetG(_editorColRegion), RGBCOLGetB(_editorColRegion), RGBCOLGetA(_editorColRegion));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_DECORATION { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColDecor), RGBCOLGetG(_editorColDecor), RGBCOLGetB(_editorColDecor), RGBCOLGetA(_editorColDecor));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_BLOCKED { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColBlocked), RGBCOLGetG(_editorColBlocked), RGBCOLGetB(_editorColBlocked), RGBCOLGetA(_editorColBlocked));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_WAYPOINTS { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColWaypoints), RGBCOLGetG(_editorColWaypoints), RGBCOLGetB(_editorColWaypoints), RGBCOLGetA(_editorColWaypoints));
+ buffer->putTextIndent(indent + 2, "EDITOR_COLOR_SCALE { %d,%d,%d,%d }\n", RGBCOLGetR(_editorColScale), RGBCOLGetG(_editorColScale), RGBCOLGetB(_editorColScale), RGBCOLGetA(_editorColScale));
+
+ buffer->putTextIndent(indent + 2, "EDITOR_SHOW_REGIONS=%s\n", _editorShowRegions ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SHOW_BLOCKED=%s\n", _editorShowBlocked ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SHOW_DECORATION=%s\n", _editorShowDecor ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SHOW_ENTITIES=%s\n", _editorShowEntities ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SHOW_SCALE=%s\n", _editorShowScale ? "TRUE" : "FALSE");
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ // waypoints
+ buffer->putTextIndent(indent + 2, "; ----- waypoints\n");
+ for (uint32 i = 0; i < _waypointGroups.size(); i++) {
+ _waypointGroups[i]->saveAsText(buffer, indent + 2);
+ }
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // layers
+ buffer->putTextIndent(indent + 2, "; ----- layers\n");
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ _layers[i]->saveAsText(buffer, indent + 2);
+ }
+
+ // scale levels
+ buffer->putTextIndent(indent + 2, "; ----- scale levels\n");
+ for (uint32 i = 0; i < _scaleLevels.size(); i++) {
+ _scaleLevels[i]->saveAsText(buffer, indent + 2);
+ }
+
+ // rotation levels
+ buffer->putTextIndent(indent + 2, "; ----- rotation levels\n");
+ for (uint32 i = 0; i < _rotLevels.size(); i++) {
+ _rotLevels[i]->saveAsText(buffer, indent + 2);
+ }
+
+
+ buffer->putTextIndent(indent + 2, "\n");
+
+ // free entities
+ buffer->putTextIndent(indent + 2, "; ----- free entities\n");
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJECT_ENTITY) {
+ _objects[i]->saveAsText(buffer, indent + 2);
+
+ }
+ }
+
+ buffer->putTextIndent(indent, "}\n");
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::sortScaleLevels() {
+ if (_scaleLevels.size() == 0) {
+ return STATUS_OK;
+ }
+ bool changed;
+ do {
+ changed = false;
+ for (uint32 i = 0; i < _scaleLevels.size() - 1; i++) {
+ if (_scaleLevels[i]->_posY > _scaleLevels[i + 1]->_posY) {
+ AdScaleLevel *sl = _scaleLevels[i];
+ _scaleLevels[i] = _scaleLevels[i + 1];
+ _scaleLevels[i + 1] = sl;
+
+ changed = true;
+ }
+ }
+
+ } while (changed);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::sortRotLevels() {
+ if (_rotLevels.size() == 0) {
+ return STATUS_OK;
+ }
+ bool changed;
+ do {
+ changed = false;
+ for (uint32 i = 0; i < _rotLevels.size() - 1; i++) {
+ if (_rotLevels[i]->_posX > _rotLevels[i + 1]->_posX) {
+ AdRotLevel *rl = _rotLevels[i];
+ _rotLevels[i] = _rotLevels[i + 1];
+ _rotLevels[i + 1] = rl;
+
+ changed = true;
+ }
+ }
+
+ } while (changed);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+float AdScene::getScaleAt(int Y) {
+ AdScaleLevel *prev = NULL;
+ AdScaleLevel *next = NULL;
+
+ for (uint32 i = 0; i < _scaleLevels.size(); i++) {
+ /* AdScaleLevel *xxx = _scaleLevels[i];*/
+ /* int j = _scaleLevels.size(); */
+ if (_scaleLevels[i]->_posY < Y) {
+ prev = _scaleLevels[i];
+ } else {
+ next = _scaleLevels[i];
+ break;
+ }
+ }
+
+ if (prev == NULL || next == NULL) {
+ return 100;
+ }
+
+ int delta_y = next->_posY - prev->_posY;
+ float delta_scale = next->_scale - prev->_scale;
+ Y -= prev->_posY;
+
+ float percent = (float)Y / ((float)delta_y / 100.0f);
+ return prev->_scale + delta_scale / 100 * percent;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::persist(BasePersistenceManager *persistMgr) {
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_autoScroll));
+ persistMgr->transfer(TMEMBER(_editorColBlocked));
+ persistMgr->transfer(TMEMBER(_editorColBlockedSel));
+ persistMgr->transfer(TMEMBER(_editorColDecor));
+ persistMgr->transfer(TMEMBER(_editorColDecorSel));
+ persistMgr->transfer(TMEMBER(_editorColEntity));
+ persistMgr->transfer(TMEMBER(_editorColEntitySel));
+ persistMgr->transfer(TMEMBER(_editorColFrame));
+ persistMgr->transfer(TMEMBER(_editorColRegion));
+ persistMgr->transfer(TMEMBER(_editorColRegionSel));
+ persistMgr->transfer(TMEMBER(_editorColScale));
+ persistMgr->transfer(TMEMBER(_editorColWaypoints));
+ persistMgr->transfer(TMEMBER(_editorColWaypointsSel));
+ persistMgr->transfer(TMEMBER(_editorMarginH));
+ persistMgr->transfer(TMEMBER(_editorMarginV));
+ persistMgr->transfer(TMEMBER(_editorShowBlocked));
+ persistMgr->transfer(TMEMBER(_editorShowDecor));
+ persistMgr->transfer(TMEMBER(_editorShowEntities));
+ persistMgr->transfer(TMEMBER(_editorShowRegions));
+ persistMgr->transfer(TMEMBER(_editorShowScale));
+ persistMgr->transfer(TMEMBER(_fader));
+ persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transfer(TMEMBER(_initialized));
+ persistMgr->transfer(TMEMBER(_lastTimeH));
+ persistMgr->transfer(TMEMBER(_lastTimeV));
+ _layers.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_mainLayer));
+ _objects.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_offsetLeft));
+ persistMgr->transfer(TMEMBER(_offsetTop));
+ persistMgr->transfer(TMEMBER(_paralaxScrolling));
+ persistMgr->transfer(TMEMBER(_persistentState));
+ persistMgr->transfer(TMEMBER(_persistentStateSprites));
+ persistMgr->transfer(TMEMBER(_pfMaxTime));
+ _pfPath.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_pfPointsNum));
+ persistMgr->transfer(TMEMBER(_pfReady));
+ persistMgr->transfer(TMEMBER(_pfRequester));
+ persistMgr->transfer(TMEMBER(_pfTarget));
+ persistMgr->transfer(TMEMBER(_pfTargetPath));
+ _rotLevels.persist(persistMgr);
+ _scaleLevels.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_scrollPixelsH));
+ persistMgr->transfer(TMEMBER(_scrollPixelsV));
+ persistMgr->transfer(TMEMBER(_scrollTimeH));
+ persistMgr->transfer(TMEMBER(_scrollTimeV));
+ persistMgr->transfer(TMEMBER(_shieldWindow));
+ persistMgr->transfer(TMEMBER(_targetOffsetLeft));
+ persistMgr->transfer(TMEMBER(_targetOffsetTop));
+ _waypointGroups.persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_viewport));
+ persistMgr->transfer(TMEMBER(_width));
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::afterLoad() {
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::correctTargetPoint2(int startX, int startY, int *targetX, int *targetY, bool checkFreeObjects, BaseObject *requester) {
+ double xStep, yStep, x, y;
+ int xLength, yLength, xCount, yCount;
+ int x1, y1, x2, y2;
+
+ x1 = *targetX;
+ y1 = *targetY;
+ x2 = startX;
+ y2 = startY;
+
+
+ xLength = abs(x2 - x1);
+ yLength = abs(y2 - y1);
+
+ if (xLength > yLength) {
+
+ yStep = fabs((double)(y2 - y1) / (double)(x2 - x1));
+ y = y1;
+
+ for (xCount = x1; xCount < x2; xCount++) {
+ if (isWalkableAt(xCount, (int)y, checkFreeObjects, requester)) {
+ *targetX = xCount;
+ *targetY = (int)y;
+ return STATUS_OK;
+ }
+ y += yStep;
+ }
+ } else {
+
+ xStep = fabs((double)(x2 - x1) / (double)(y2 - y1));
+ x = x1;
+
+ for (yCount = y1; yCount < y2; yCount++) {
+ if (isWalkableAt((int)x, yCount, checkFreeObjects, requester)) {
+ *targetX = (int)x;
+ *targetY = yCount;
+ return STATUS_OK;
+ }
+ x += xStep;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::correctTargetPoint(int startX, int startY, int *argX, int *argY, bool checkFreeObjects, BaseObject *requester) {
+ int x = *argX;
+ int y = *argY;
+
+ if (isWalkableAt(x, y, checkFreeObjects, requester) || !_mainLayer) {
+ return STATUS_OK;
+ }
+
+ // right
+ int lengthRight = 0;
+ bool foundRight = false;
+ for (x = *argX, y = *argY; x < _mainLayer->_width; x++, lengthRight++) {
+ if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x - 5, y, checkFreeObjects, requester)) {
+ foundRight = true;
+ break;
+ }
+ }
+
+ // left
+ int lengthLeft = 0;
+ bool foundLeft = false;
+ for (x = *argX, y = *argY; x >= 0; x--, lengthLeft--) {
+ if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x + 5, y, checkFreeObjects, requester)) {
+ foundLeft = true;
+ break;
+ }
+ }
+
+ // up
+ int lengthUp = 0;
+ bool foundUp = false;
+ for (x = *argX, y = *argY; y >= 0; y--, lengthUp--) {
+ if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x, y + 5, checkFreeObjects, requester)) {
+ foundUp = true;
+ break;
+ }
+ }
+
+ // down
+ int lengthDown = 0;
+ bool foundDown = false;
+ for (x = *argX, y = *argY; y < _mainLayer->_height; y++, lengthDown++) {
+ if (isWalkableAt(x, y, checkFreeObjects, requester) && isWalkableAt(x, y - 5, checkFreeObjects, requester)) {
+ foundDown = true;
+ break;
+ }
+ }
+
+ if (!foundLeft && !foundRight && !foundUp && !foundDown) {
+ return STATUS_OK;
+ }
+
+ int offsetX = INT_MAX, offsetY = INT_MAX;
+
+ if (foundLeft && foundRight) {
+ if (abs(lengthLeft) < abs(lengthRight)) {
+ offsetX = lengthLeft;
+ } else {
+ offsetX = lengthRight;
+ }
+ } else if (foundLeft) {
+ offsetX = lengthLeft;
+ } else if (foundRight) {
+ offsetX = lengthRight;
+ }
+
+ if (foundUp && foundDown) {
+ if (abs(lengthUp) < abs(lengthDown)) {
+ offsetY = lengthUp;
+ } else {
+ offsetY = lengthDown;
+ }
+ } else if (foundUp) {
+ offsetY = lengthUp;
+ } else if (foundDown) {
+ offsetY = lengthDown;
+ }
+
+ if (abs(offsetX) < abs(offsetY)) {
+ *argX = *argX + offsetX;
+ } else {
+ *argY = *argY + offsetY;
+ }
+
+ if (!isWalkableAt(*argX, *argY)) {
+ return correctTargetPoint2(startX, startY, argX, argY, checkFreeObjects, requester);
+ } else {
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::pfPointsStart() {
+ _pfPointsNum = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::pfPointsAdd(int x, int y, int distance) {
+ if (_pfPointsNum >= (int32)_pfPath.size()) {
+ _pfPath.add(new AdPathPoint(x, y, distance));
+ } else {
+ _pfPath[_pfPointsNum]->x = x;
+ _pfPath[_pfPointsNum]->y = y;
+ _pfPath[_pfPointsNum]->_distance = distance;
+ _pfPath[_pfPointsNum]->_marked = false;
+ _pfPath[_pfPointsNum]->_origin = NULL;
+ }
+
+ _pfPointsNum++;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getViewportOffset(int *offsetX, int *offsetY) {
+ AdGame *adGame = (AdGame *)_gameRef;
+ if (_viewport && !_gameRef->_editorMode) {
+ if (offsetX) {
+ *offsetX = _viewport->_offsetX;
+ }
+ if (offsetY) {
+ *offsetY = _viewport->_offsetY;
+ }
+ } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
+ if (offsetX) {
+ *offsetX = adGame->_sceneViewport->_offsetX;
+ }
+ if (offsetY) {
+ *offsetY = adGame->_sceneViewport->_offsetY;
+ }
+ } else {
+ if (offsetX) {
+ *offsetX = 0;
+ }
+ if (offsetY) {
+ *offsetY = 0;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getViewportSize(int *width, int *height) {
+ AdGame *adGame = (AdGame *)_gameRef;
+ if (_viewport && !_gameRef->_editorMode) {
+ if (width) {
+ *width = _viewport->getWidth();
+ }
+ if (height) {
+ *height = _viewport->getHeight();
+ }
+ } else if (adGame->_sceneViewport && !_gameRef->_editorMode) {
+ if (width) {
+ *width = adGame->_sceneViewport->getWidth();
+ }
+ if (height) {
+ *height = adGame->_sceneViewport->getHeight();
+ }
+ } else {
+ if (width) {
+ *width = _gameRef->_renderer->_width;
+ }
+ if (height) {
+ *height = _gameRef->_renderer->_height;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdScene::getOffsetLeft() {
+ int viewportX;
+ getViewportOffset(&viewportX);
+
+ return _offsetLeft - viewportX;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int AdScene::getOffsetTop() {
+ int viewportY;
+ getViewportOffset(NULL, &viewportY);
+
+ return _offsetTop - viewportY;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::pointInViewport(int x, int y) {
+ int left, top, width, height;
+
+ getViewportOffset(&left, &top);
+ getViewportSize(&width, &height);
+
+ return x >= left && x <= left + width && y >= top && y <= top + height;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdScene::setOffset(int offsetLeft, int offsetTop) {
+ _offsetLeft = offsetLeft;
+ _offsetTop = offsetTop;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseObject *AdScene::getNodeByName(const char *name) {
+ BaseObject *ret = NULL;
+
+ // dependent objects
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ AdLayer *layer = _layers[i];
+ for (uint32 j = 0; j < layer->_nodes.size(); j++) {
+ AdSceneNode *node = layer->_nodes[j];
+ if ((node->_type == OBJECT_ENTITY && !scumm_stricmp(name, node->_entity->getName())) ||
+ (node->_type == OBJECT_REGION && !scumm_stricmp(name, node->_region->getName()))) {
+ switch (node->_type) {
+ case OBJECT_ENTITY:
+ ret = node->_entity;
+ break;
+ case OBJECT_REGION:
+ ret = node->_region;
+ break;
+ default:
+ ret = NULL;
+ }
+ return ret;
+ }
+ }
+ }
+
+ // free entities
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJECT_ENTITY && !scumm_stricmp(name, _objects[i]->getName())) {
+ return _objects[i];
+ }
+ }
+
+ // waypoint groups
+ for (uint32 i = 0; i < _waypointGroups.size(); i++) {
+ if (!scumm_stricmp(name, _waypointGroups[i]->getName())) {
+ return _waypointGroups[i];
+ }
+ }
+
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::saveState() {
+ return persistState(true);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::loadState() {
+ return persistState(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::persistState(bool saving) {
+ if (!_persistentState) {
+ return STATUS_OK;
+ }
+
+ AdGame *adGame = (AdGame *)_gameRef;
+ AdSceneState *state = adGame->getSceneState(getFilename(), saving);
+ if (!state) {
+ return STATUS_OK;
+ }
+
+ AdNodeState *nodeState;
+
+ // dependent objects
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ AdLayer *layer = _layers[i];
+ for (uint32 j = 0; j < layer->_nodes.size(); j++) {
+ AdSceneNode *node = layer->_nodes[j];
+ switch (node->_type) {
+ case OBJECT_ENTITY:
+ if (!node->_entity->_saveState) {
+ continue;
+ }
+ nodeState = state->getNodeState(node->_entity->getName(), saving);
+ if (nodeState) {
+ nodeState->transferEntity(node->_entity, _persistentStateSprites, saving);
+ //if (Saving) NodeState->_active = node->_entity->_active;
+ //else node->_entity->_active = NodeState->_active;
+ }
+ break;
+ case OBJECT_REGION:
+ if (!node->_region->_saveState) {
+ continue;
+ }
+ nodeState = state->getNodeState(node->_region->getName(), saving);
+ if (nodeState) {
+ if (saving) {
+ nodeState->_active = node->_region->_active;
+ } else {
+ node->_region->_active = nodeState->_active;
+ }
+ }
+ break;
+ default:
+ warning("AdScene::PersistState - unhandled enum");
+ break;
+ }
+ }
+ }
+
+ // free entities
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (!_objects[i]->_saveState) {
+ continue;
+ }
+ if (_objects[i]->_type == OBJECT_ENTITY) {
+ nodeState = state->getNodeState(_objects[i]->getName(), saving);
+ if (nodeState) {
+ nodeState->transferEntity((AdEntity *)_objects[i], _persistentStateSprites, saving);
+ //if (Saving) NodeState->_active = _objects[i]->_active;
+ //else _objects[i]->_active = NodeState->_active;
+ }
+ }
+ }
+
+ // waypoint groups
+ for (uint32 i = 0; i < _waypointGroups.size(); i++) {
+ nodeState = state->getNodeState(_waypointGroups[i]->getName(), saving);
+ if (nodeState) {
+ if (saving) {
+ nodeState->_active = _waypointGroups[i]->_active;
+ } else {
+ _waypointGroups[i]->_active = nodeState->_active;
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+float AdScene::getRotationAt(int x, int y) {
+ AdRotLevel *prev = NULL;
+ AdRotLevel *next = NULL;
+
+ for (uint32 i = 0; i < _rotLevels.size(); i++) {
+ /* AdRotLevel *xxx = _rotLevels[i];
+ int j = _rotLevels.size();*/
+ if (_rotLevels[i]->_posX < x) {
+ prev = _rotLevels[i];
+ } else {
+ next = _rotLevels[i];
+ break;
+ }
+ }
+
+ if (prev == NULL || next == NULL) {
+ return 0;
+ }
+
+ int delta_x = next->_posX - prev->_posX;
+ float delta_rot = next->_rotation - prev->_rotation;
+ x -= prev->_posX;
+
+ float percent = (float)x / ((float)delta_x / 100.0f);
+ return prev->_rotation + delta_rot / 100 * percent;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::handleItemAssociations(const char *itemName, bool show) {
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ AdLayer *layer = _layers[i];
+ for (uint32 j = 0; j < layer->_nodes.size(); j++) {
+ if (layer->_nodes[j]->_type == OBJECT_ENTITY) {
+ AdEntity *ent = layer->_nodes[j]->_entity;
+
+ if (ent->_item && strcmp(ent->_item, itemName) == 0) {
+ ent->_active = show;
+ }
+ }
+ }
+ }
+
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJECT_ENTITY) {
+ AdEntity *ent = (AdEntity *)_objects[i];
+ if (ent->_item && strcmp(ent->_item, itemName) == 0) {
+ ent->_active = show;
+ }
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getRegionsAt(int x, int y, AdRegion **regionList, int numRegions) {
+ int numUsed = 0;
+ if (_mainLayer) {
+ for (int i = _mainLayer->_nodes.size() - 1; i >= 0; i--) {
+ AdSceneNode *node = _mainLayer->_nodes[i];
+ if (node->_type == OBJECT_REGION && node->_region->_active && node->_region->pointInRegion(x, y)) {
+ if (numUsed < numRegions - 1) {
+ regionList[numUsed] = node->_region;
+ numUsed++;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ for (int i = numUsed; i < numRegions; i++) {
+ regionList[i] = NULL;
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::restoreDeviceObjects() {
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseObject *AdScene::getNextAccessObject(BaseObject *currObject) {
+ BaseArray<AdObject *> objects;
+ getSceneObjects(objects, true);
+
+ if (objects.size() == 0) {
+ return NULL;
+ } else {
+ if (currObject != NULL) {
+ for (uint32 i = 0; i < objects.size(); i++) {
+ if (objects[i] == currObject) {
+ if (i < objects.size() - 1) {
+ return objects[i + 1];
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ return objects[0];
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseObject *AdScene::getPrevAccessObject(BaseObject *currObject) {
+ BaseArray<AdObject *> objects;
+ getSceneObjects(objects, true);
+
+ if (objects.size() == 0) {
+ return NULL;
+ } else {
+ if (currObject != NULL) {
+ for (int i = objects.size() - 1; i >= 0; i--) {
+ if (objects[i] == currObject) {
+ if (i > 0) {
+ return objects[i - 1];
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ return objects[objects.size() - 1];
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getSceneObjects(BaseArray<AdObject *> &objects, bool interactiveOnly) {
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ // close-up layer -> remove everything below it
+ if (interactiveOnly && _layers[i]->_closeUp) {
+ objects.clear();
+ }
+
+
+ for (uint32 j = 0; j < _layers[i]->_nodes.size(); j++) {
+ AdSceneNode *node = _layers[i]->_nodes[j];
+ switch (node->_type) {
+ case OBJECT_ENTITY: {
+ AdEntity *ent = node->_entity;
+ if (ent->_active && (ent->_registrable || !interactiveOnly)) {
+ objects.add(ent);
+ }
+ }
+ break;
+
+ case OBJECT_REGION: {
+ BaseArray<AdObject *> regionObj;
+ getRegionObjects(node->_region, regionObj, interactiveOnly);
+ for (uint32 newIndex = 0; newIndex < regionObj.size(); newIndex++) {
+ bool found = false;
+ for (uint32 old = 0; old < objects.size(); old++) {
+ if (objects[old] == regionObj[newIndex]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ objects.add(regionObj[newIndex]);
+ }
+ }
+ //if (regionObj.size() > 0) Objects.Append(RegionObj);
+ }
+ break;
+ default:
+ debugC(kWintermuteDebugGeneral, "AdScene::GetSceneObjects - Unhandled enum");
+ break;
+ }
+ }
+ }
+
+ // objects outside any region
+ BaseArray<AdObject *> regionObj;
+ getRegionObjects(NULL, regionObj, interactiveOnly);
+ for (uint32 newIndex = 0; newIndex < regionObj.size(); newIndex++) {
+ bool found = false;
+ for (uint32 old = 0; old < objects.size(); old++) {
+ if (objects[old] == regionObj[newIndex]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ objects.add(regionObj[newIndex]);
+ }
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdScene::getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, bool interactiveOnly) {
+ AdGame *adGame = (AdGame *)_gameRef;
+ AdObject *obj;
+
+ // global objects
+ for (uint32 i = 0; i < adGame->_objects.size(); i++) {
+ obj = adGame->_objects[i];
+ if (obj->_active && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
+ if (interactiveOnly && !obj->_registrable) {
+ continue;
+ }
+
+ objects.add(obj);
+ }
+ }
+
+ // scene objects
+ for (uint32 i = 0; i < _objects.size(); i++) {
+ obj = _objects[i];
+ if (obj->_active && !obj->_editorOnly && (obj->_stickRegion == region || region == NULL || (obj->_stickRegion == NULL && region->pointInRegion(obj->_posX, obj->_posY)))) {
+ if (interactiveOnly && !obj->_registrable) {
+ continue;
+ }
+
+ objects.add(obj);
+ }
+ }
+
+ // sort by _posY
+ Common::sort(objects.begin(), objects.end(), AdScene::compareObjs);
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene.h b/engines/wintermute/ad/ad_scene.h
index 20b3f5026d..c9c0e413bf 100644
--- a/engines/wintermute/ad/ad_scene.h
+++ b/engines/wintermute/ad/ad_scene.h
@@ -1,181 +1,181 @@
-/* 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_ADSCENE_H
-#define WINTERMUTE_ADSCENE_H
-
-#include "engines/wintermute/base/base_fader.h"
-
-namespace Wintermute {
-
-class UIWindow;
-class AdObject;
-class AdRegion;
-class BaseViewport;
-class AdLayer;
-class BasePoint;
-class AdWaypointGroup;
-class AdPath;
-class AdScaleLevel;
-class AdRotLevel;
-class AdPathPoint;
-class AdScene : public BaseObject {
-public:
-
- BaseObject *getNextAccessObject(BaseObject *currObject);
- BaseObject *getPrevAccessObject(BaseObject *currObject);
- bool getSceneObjects(BaseArray<AdObject *> &objects, bool interactiveOnly);
- bool getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, bool interactiveOnly);
-
- bool afterLoad();
-
- bool getRegionsAt(int x, int y, AdRegion **regionList, int numRegions);
- bool handleItemAssociations(const char *itemName, bool show);
- UIWindow *_shieldWindow;
- float getRotationAt(int x, int y);
- bool loadState();
- bool saveState();
- bool _persistentState;
- bool _persistentStateSprites;
- BaseObject *getNodeByName(const char *name);
- void setOffset(int offsetLeft, int offsetTop);
- bool pointInViewport(int x, int y);
- int getOffsetTop();
- int getOffsetLeft();
- bool getViewportSize(int *width = NULL, int *height = NULL);
- bool getViewportOffset(int *offsetX = NULL, int *offsetY = NULL);
- BaseViewport *_viewport;
- BaseFader *_fader;
- int _pfPointsNum;
- void pfPointsAdd(int x, int y, int distance);
- void pfPointsStart();
- bool _initialized;
- bool correctTargetPoint(int startX, int startY, int *x, int *y, bool checkFreeObjects = false, BaseObject *requester = NULL);
- bool correctTargetPoint2(int startX, int startY, int *targetX, int *targetY, bool checkFreeObjects, BaseObject *requester);
- DECLARE_PERSISTENT(AdScene, BaseObject)
- bool displayRegionContent(AdRegion *region = NULL, bool display3DOnly = false);
- bool displayRegionContentOld(AdRegion *region = NULL);
- static int compareObjs(const void *obj1, const void *obj2);
-
- bool updateFreeObjects();
- bool traverseNodes(bool update = false);
- float getScaleAt(int y);
- bool sortScaleLevels();
- bool sortRotLevels();
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- uint32 getAlphaAt(int x, int y, bool colorCheck = false);
- bool _paralaxScrolling;
- void skipTo(int offsetX, int offsetY);
- void setDefaults();
- void cleanup();
- void skipToObject(BaseObject *object);
- void scrollToObject(BaseObject *object);
- void scrollTo(int offsetX, int offsetY);
- virtual bool update();
- bool _autoScroll;
- int _targetOffsetTop;
- int _targetOffsetLeft;
-
- int _scrollPixelsV;
- uint32 _scrollTimeV;
- uint32 _lastTimeV;
-
- int _scrollPixelsH;
- uint32 _scrollTimeH;
- uint32 _lastTimeH;
-
- virtual bool display();
- uint32 _pfMaxTime;
- bool initLoop();
- void pathFinderStep();
- bool isBlockedAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = NULL);
- bool isWalkableAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = NULL);
- AdLayer *_mainLayer;
- float getZoomAt(int x, int y);
- bool getPath(BasePoint source, BasePoint target, AdPath *path, BaseObject *requester = NULL);
- AdScene(BaseGame *inGame);
- virtual ~AdScene();
- BaseArray<AdLayer *> _layers;
- BaseArray<AdObject *> _objects;
- BaseArray<AdWaypointGroup *> _waypointGroups;
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- int _width;
- int _height;
- bool addObject(AdObject *Object);
- bool removeObject(AdObject *Object);
- int _editorMarginH;
- int _editorMarginV;
- uint32 _editorColFrame;
- uint32 _editorColEntity;
- uint32 _editorColRegion;
- uint32 _editorColBlocked;
- uint32 _editorColWaypoints;
- uint32 _editorColEntitySel;
- uint32 _editorColRegionSel;
- uint32 _editorColBlockedSel;
- uint32 _editorColWaypointsSel;
- uint32 _editorColScale;
- uint32 _editorColDecor;
- uint32 _editorColDecorSel;
-
- bool _editorShowRegions;
- bool _editorShowBlocked;
- bool _editorShowDecor;
- bool _editorShowEntities;
- bool _editorShowScale;
- BaseArray<AdScaleLevel *> _scaleLevels;
- BaseArray<AdRotLevel *> _rotLevels;
-
- virtual bool restoreDeviceObjects();
- int getPointsDist(BasePoint p1, BasePoint p2, BaseObject *requester = NULL);
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-
-
-private:
- bool persistState(bool saving = true);
- void pfAddWaypointGroup(AdWaypointGroup *Wpt, BaseObject *requester = NULL);
- bool _pfReady;
- BasePoint *_pfTarget;
- AdPath *_pfTargetPath;
- BaseObject *_pfRequester;
- BaseArray<AdPathPoint *> _pfPath;
-
- int _offsetTop;
- int _offsetLeft;
-
-};
-
-} // 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_ADSCENE_H
+#define WINTERMUTE_ADSCENE_H
+
+#include "engines/wintermute/base/base_fader.h"
+
+namespace Wintermute {
+
+class UIWindow;
+class AdObject;
+class AdRegion;
+class BaseViewport;
+class AdLayer;
+class BasePoint;
+class AdWaypointGroup;
+class AdPath;
+class AdScaleLevel;
+class AdRotLevel;
+class AdPathPoint;
+class AdScene : public BaseObject {
+public:
+
+ BaseObject *getNextAccessObject(BaseObject *currObject);
+ BaseObject *getPrevAccessObject(BaseObject *currObject);
+ bool getSceneObjects(BaseArray<AdObject *> &objects, bool interactiveOnly);
+ bool getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, bool interactiveOnly);
+
+ bool afterLoad();
+
+ bool getRegionsAt(int x, int y, AdRegion **regionList, int numRegions);
+ bool handleItemAssociations(const char *itemName, bool show);
+ UIWindow *_shieldWindow;
+ float getRotationAt(int x, int y);
+ bool loadState();
+ bool saveState();
+ bool _persistentState;
+ bool _persistentStateSprites;
+ BaseObject *getNodeByName(const char *name);
+ void setOffset(int offsetLeft, int offsetTop);
+ bool pointInViewport(int x, int y);
+ int getOffsetTop();
+ int getOffsetLeft();
+ bool getViewportSize(int *width = NULL, int *height = NULL);
+ bool getViewportOffset(int *offsetX = NULL, int *offsetY = NULL);
+ BaseViewport *_viewport;
+ BaseFader *_fader;
+ int _pfPointsNum;
+ void pfPointsAdd(int x, int y, int distance);
+ void pfPointsStart();
+ bool _initialized;
+ bool correctTargetPoint(int startX, int startY, int *x, int *y, bool checkFreeObjects = false, BaseObject *requester = NULL);
+ bool correctTargetPoint2(int startX, int startY, int *targetX, int *targetY, bool checkFreeObjects, BaseObject *requester);
+ DECLARE_PERSISTENT(AdScene, BaseObject)
+ bool displayRegionContent(AdRegion *region = NULL, bool display3DOnly = false);
+ bool displayRegionContentOld(AdRegion *region = NULL);
+ static int compareObjs(const void *obj1, const void *obj2);
+
+ bool updateFreeObjects();
+ bool traverseNodes(bool update = false);
+ float getScaleAt(int y);
+ bool sortScaleLevels();
+ bool sortRotLevels();
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ uint32 getAlphaAt(int x, int y, bool colorCheck = false);
+ bool _paralaxScrolling;
+ void skipTo(int offsetX, int offsetY);
+ void setDefaults();
+ void cleanup();
+ void skipToObject(BaseObject *object);
+ void scrollToObject(BaseObject *object);
+ void scrollTo(int offsetX, int offsetY);
+ virtual bool update();
+ bool _autoScroll;
+ int _targetOffsetTop;
+ int _targetOffsetLeft;
+
+ int _scrollPixelsV;
+ uint32 _scrollTimeV;
+ uint32 _lastTimeV;
+
+ int _scrollPixelsH;
+ uint32 _scrollTimeH;
+ uint32 _lastTimeH;
+
+ virtual bool display();
+ uint32 _pfMaxTime;
+ bool initLoop();
+ void pathFinderStep();
+ bool isBlockedAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = NULL);
+ bool isWalkableAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = NULL);
+ AdLayer *_mainLayer;
+ float getZoomAt(int x, int y);
+ bool getPath(BasePoint source, BasePoint target, AdPath *path, BaseObject *requester = NULL);
+ AdScene(BaseGame *inGame);
+ virtual ~AdScene();
+ BaseArray<AdLayer *> _layers;
+ BaseArray<AdObject *> _objects;
+ BaseArray<AdWaypointGroup *> _waypointGroups;
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ int _width;
+ int _height;
+ bool addObject(AdObject *Object);
+ bool removeObject(AdObject *Object);
+ int _editorMarginH;
+ int _editorMarginV;
+ uint32 _editorColFrame;
+ uint32 _editorColEntity;
+ uint32 _editorColRegion;
+ uint32 _editorColBlocked;
+ uint32 _editorColWaypoints;
+ uint32 _editorColEntitySel;
+ uint32 _editorColRegionSel;
+ uint32 _editorColBlockedSel;
+ uint32 _editorColWaypointsSel;
+ uint32 _editorColScale;
+ uint32 _editorColDecor;
+ uint32 _editorColDecorSel;
+
+ bool _editorShowRegions;
+ bool _editorShowBlocked;
+ bool _editorShowDecor;
+ bool _editorShowEntities;
+ bool _editorShowScale;
+ BaseArray<AdScaleLevel *> _scaleLevels;
+ BaseArray<AdRotLevel *> _rotLevels;
+
+ virtual bool restoreDeviceObjects();
+ int getPointsDist(BasePoint p1, BasePoint p2, BaseObject *requester = NULL);
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+
+
+private:
+ bool persistState(bool saving = true);
+ void pfAddWaypointGroup(AdWaypointGroup *Wpt, BaseObject *requester = NULL);
+ bool _pfReady;
+ BasePoint *_pfTarget;
+ AdPath *_pfTargetPath;
+ BaseObject *_pfRequester;
+ BaseArray<AdPathPoint *> _pfPath;
+
+ int _offsetTop;
+ int _offsetLeft;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_scene_node.cpp b/engines/wintermute/ad/ad_scene_node.cpp
index 4f6acdbc95..d0202236fd 100644
--- a/engines/wintermute/ad/ad_scene_node.cpp
+++ b/engines/wintermute/ad/ad_scene_node.cpp
@@ -1,82 +1,82 @@
-/* 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/ad/ad_scene_node.h"
-#include "engines/wintermute/base/base_game.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdSceneNode, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdSceneNode::AdSceneNode(BaseGame *inGame) : BaseObject(inGame) {
- _type = OBJECT_NONE;
- _region = NULL;
- _entity = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSceneNode::~AdSceneNode() {
- _gameRef->unregisterObject(_region);
- _region = NULL;
-
- _gameRef->unregisterObject(_entity);
- _entity = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSceneNode::setEntity(AdEntity *entity) {
- _type = OBJECT_ENTITY;
- _entity = entity;
- return _gameRef->registerObject(entity);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSceneNode::setRegion(AdRegion *region) {
- _type = OBJECT_REGION;
- _region = region;
- return _gameRef->registerObject(region);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_entity));
- persistMgr->transfer(TMEMBER(_region));
- persistMgr->transfer(TMEMBER_INT(_type));
-
- 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/ad/ad_scene_node.h"
+#include "engines/wintermute/base/base_game.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdSceneNode, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdSceneNode::AdSceneNode(BaseGame *inGame) : BaseObject(inGame) {
+ _type = OBJECT_NONE;
+ _region = NULL;
+ _entity = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSceneNode::~AdSceneNode() {
+ _gameRef->unregisterObject(_region);
+ _region = NULL;
+
+ _gameRef->unregisterObject(_entity);
+ _entity = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSceneNode::setEntity(AdEntity *entity) {
+ _type = OBJECT_ENTITY;
+ _entity = entity;
+ return _gameRef->registerObject(entity);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSceneNode::setRegion(AdRegion *region) {
+ _type = OBJECT_REGION;
+ _region = region;
+ return _gameRef->registerObject(region);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_entity));
+ persistMgr->transfer(TMEMBER(_region));
+ persistMgr->transfer(TMEMBER_INT(_type));
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene_node.h b/engines/wintermute/ad/ad_scene_node.h
index 8cc50b86c4..5bb1606d0e 100644
--- a/engines/wintermute/ad/ad_scene_node.h
+++ b/engines/wintermute/ad/ad_scene_node.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_ADSCENENODE_H
-#define WINTERMUTE_ADSCENENODE_H
-
-
-#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
-#include "engines/wintermute/ad/ad_region.h" // Added by ClassView
-#include "engines/wintermute/ad/ad_entity.h"
-
-namespace Wintermute {
-
-class AdSceneNode : public BaseObject {
-public:
- DECLARE_PERSISTENT(AdSceneNode, BaseObject)
- bool setRegion(AdRegion *region);
- bool setEntity(AdEntity *entity);
- AdEntity *_entity;
- AdRegion *_region;
- TObjectType _type;
- AdSceneNode(BaseGame *inGame);
- virtual ~AdSceneNode();
-
-};
-
-}
-
-#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_ADSCENENODE_H
+#define WINTERMUTE_ADSCENENODE_H
+
+
+#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
+#include "engines/wintermute/ad/ad_region.h" // Added by ClassView
+#include "engines/wintermute/ad/ad_entity.h"
+
+namespace Wintermute {
+
+class AdSceneNode : public BaseObject {
+public:
+ DECLARE_PERSISTENT(AdSceneNode, BaseObject)
+ bool setRegion(AdRegion *region);
+ bool setEntity(AdEntity *entity);
+ AdEntity *_entity;
+ AdRegion *_region;
+ TObjectType _type;
+ AdSceneNode(BaseGame *inGame);
+ virtual ~AdSceneNode();
+
+};
+
+}
+
+#endif
diff --git a/engines/wintermute/ad/ad_scene_state.cpp b/engines/wintermute/ad/ad_scene_state.cpp
index 04fd52c382..c09e6a259c 100644
--- a/engines/wintermute/ad/ad_scene_state.cpp
+++ b/engines/wintermute/ad/ad_scene_state.cpp
@@ -1,95 +1,95 @@
-/* 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/ad/ad_scene_state.h"
-#include "engines/wintermute/ad/ad_node_state.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdSceneState, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdSceneState::AdSceneState(BaseGame *inGame) : BaseClass(inGame) {
- _filename = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSceneState::~AdSceneState() {
- delete[] _filename;
- _filename = NULL;
-
- for (uint32 i = 0; i < _nodeStates.size(); i++) {
- delete _nodeStates[i];
- }
- _nodeStates.clear();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_filename));
- _nodeStates.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdSceneState::setFilename(const char *filename) {
- delete[] _filename;
- _filename = new char [strlen(filename) + 1];
- if (_filename) {
- strcpy(_filename, filename);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdNodeState *AdSceneState::getNodeState(const char *name, bool saving) {
- for (uint32 i = 0; i < _nodeStates.size(); i++) {
- if (scumm_stricmp(_nodeStates[i]->getName(), name) == 0) {
- return _nodeStates[i];
- }
- }
-
- if (saving) {
- AdNodeState *ret = new AdNodeState(_gameRef);
- ret->setName(name);
- _nodeStates.add(ret);
-
- return ret;
- } else {
- return NULL;
- }
-}
-
-} // 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/ad/ad_scene_state.h"
+#include "engines/wintermute/ad/ad_node_state.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdSceneState, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdSceneState::AdSceneState(BaseGame *inGame) : BaseClass(inGame) {
+ _filename = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSceneState::~AdSceneState() {
+ delete[] _filename;
+ _filename = NULL;
+
+ for (uint32 i = 0; i < _nodeStates.size(); i++) {
+ delete _nodeStates[i];
+ }
+ _nodeStates.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_filename));
+ _nodeStates.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdSceneState::setFilename(const char *filename) {
+ delete[] _filename;
+ _filename = new char [strlen(filename) + 1];
+ if (_filename) {
+ strcpy(_filename, filename);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdNodeState *AdSceneState::getNodeState(const char *name, bool saving) {
+ for (uint32 i = 0; i < _nodeStates.size(); i++) {
+ if (scumm_stricmp(_nodeStates[i]->getName(), name) == 0) {
+ return _nodeStates[i];
+ }
+ }
+
+ if (saving) {
+ AdNodeState *ret = new AdNodeState(_gameRef);
+ ret->setName(name);
+ _nodeStates.add(ret);
+
+ return ret;
+ } else {
+ return NULL;
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene_state.h b/engines/wintermute/ad/ad_scene_state.h
index 8298d23d76..2b25393c5a 100644
--- a/engines/wintermute/ad/ad_scene_state.h
+++ b/engines/wintermute/ad/ad_scene_state.h
@@ -1,51 +1,51 @@
-/* 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_ADSCENESTATE_H
-#define WINTERMUTE_ADSCENESTATE_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/coll_templ.h"
-
-namespace Wintermute {
-class AdNodeState;
-class AdSceneState : public BaseClass {
-public:
- AdNodeState *getNodeState(const char *name, bool saving);
- void setFilename(const char *filename);
- DECLARE_PERSISTENT(AdSceneState, BaseClass)
- AdSceneState(BaseGame *inGame);
- virtual ~AdSceneState();
- char *_filename;
- BaseArray<AdNodeState *> _nodeStates;
-};
-
-} // 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_ADSCENESTATE_H
+#define WINTERMUTE_ADSCENESTATE_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/coll_templ.h"
+
+namespace Wintermute {
+class AdNodeState;
+class AdSceneState : public BaseClass {
+public:
+ AdNodeState *getNodeState(const char *name, bool saving);
+ void setFilename(const char *filename);
+ DECLARE_PERSISTENT(AdSceneState, BaseClass)
+ AdSceneState(BaseGame *inGame);
+ virtual ~AdSceneState();
+ char *_filename;
+ BaseArray<AdNodeState *> _nodeStates;
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_sentence.cpp b/engines/wintermute/ad/ad_sentence.cpp
index 51765e3fe9..1f09d3ae0f 100644
--- a/engines/wintermute/ad/ad_sentence.cpp
+++ b/engines/wintermute/ad/ad_sentence.cpp
@@ -1,360 +1,360 @@
-/* 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/ad/ad_sentence.h"
-#include "engines/wintermute/ad/ad_talk_def.h"
-#include "engines/wintermute/ad/ad_talk_node.h"
-#include "engines/wintermute/ad/ad_game.h"
-#include "engines/wintermute/utils/path_util.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/ad/ad_scene.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_file_manager.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdSentence, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdSentence::AdSentence(BaseGame *inGame) : BaseClass(inGame) {
- _text = NULL;
- _stances = NULL;
- _tempStance = NULL;
-
- _duration = 0;
- _startTime = 0;
- _currentStance = 0;
-
- _font = NULL;
-
- _pos.x = _pos.y = 0;
- _width = _gameRef->_renderer->_width;
-
- _align = (TTextAlign)TAL_CENTER;
-
- _sound = NULL;
- _soundStarted = false;
-
- _talkDef = NULL;
- _currentSprite = NULL;
- _currentSkelAnim = NULL;
- _fixedPos = false;
- _freezable = true;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSentence::~AdSentence() {
- delete _sound;
- delete[] _text;
- delete[] _stances;
- delete[] _tempStance;
- delete _talkDef;
- _sound = NULL;
- _text = NULL;
- _stances = NULL;
- _tempStance = NULL;
- _talkDef = NULL;
-
- _currentSprite = NULL; // ref only
- _currentSkelAnim = NULL;
- _font = NULL; // ref only
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdSentence::setText(const char *text) {
- if (_text) {
- delete[] _text;
- }
- _text = new char[strlen(text) + 1];
- if (_text) {
- strcpy(_text, text);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdSentence::setStances(const char *stances) {
- if (_stances) {
- delete[] _stances;
- }
- if (stances) {
- _stances = new char[strlen(stances) + 1];
- if (_stances) {
- strcpy(_stances, stances);
- }
- } else {
- _stances = NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-char *AdSentence::getCurrentStance() {
- return getStance(_currentStance);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-char *AdSentence::getNextStance() {
- _currentStance++;
- return getStance(_currentStance);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-char *AdSentence::getStance(int stance) {
- if (_stances == NULL) {
- return NULL;
- }
-
- if (_tempStance) {
- delete[] _tempStance;
- }
- _tempStance = NULL;
-
- char *start;
- char *curr;
- int pos;
-
- if (stance == 0) {
- start = _stances;
- } else {
- pos = 0;
- start = NULL;
- curr = _stances;
- while (pos < stance) {
- if (*curr == '\0') {
- break;
- }
- if (*curr == ',') {
- pos++;
- }
- curr++;
- }
- if (pos == stance) {
- start = curr;
- }
- }
-
- if (start == NULL) {
- return NULL;
- }
-
- while (*start == ' ' && *start != ',' && *start != '\0') {
- start++;
- }
-
- curr = start;
- while (*curr != '\0' && *curr != ',') {
- curr++;
- }
-
- while (curr > start && *(curr - 1) == ' ') {
- curr--;
- }
-
- _tempStance = new char [curr - start + 1];
- if (_tempStance) {
- Common::strlcpy(_tempStance, start, curr - start + 1);
- }
-
- return _tempStance;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::display() {
- if (!_font || !_text) {
- return STATUS_FAILED;
- }
-
- if (_sound && !_soundStarted) {
- _sound->play();
- _soundStarted = true;
- }
-
- if (_gameRef->_subtitles) {
- int x = _pos.x;
- int y = _pos.y;
-
- if (!_fixedPos) {
- x = x - ((AdGame *)_gameRef)->_scene->getOffsetLeft();
- y = y - ((AdGame *)_gameRef)->_scene->getOffsetTop();
- }
-
-
- x = MAX(x, 0);
- x = MIN(x, _gameRef->_renderer->_width - _width);
- y = MAX(y, 0);
-
- _font->drawText((byte *)_text, x, y, _width, _align);
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdSentence::setSound(BaseSound *sound) {
- if (!sound) {
- return;
- }
- delete _sound;
- _sound = sound;
- _soundStarted = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::finish() {
- if (_sound) {
- _sound->stop();
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::persist(BasePersistenceManager *persistMgr) {
-
- persistMgr->transfer(TMEMBER(_gameRef));
-
- persistMgr->transfer(TMEMBER_INT(_align));
- persistMgr->transfer(TMEMBER(_currentStance));
- persistMgr->transfer(TMEMBER(_currentSprite));
- persistMgr->transfer(TMEMBER(_currentSkelAnim));
- persistMgr->transfer(TMEMBER(_duration));
- persistMgr->transfer(TMEMBER(_font));
- persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_sound));
- persistMgr->transfer(TMEMBER(_soundStarted));
- persistMgr->transfer(TMEMBER(_stances));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_talkDef));
- persistMgr->transfer(TMEMBER(_tempStance));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_width));
- persistMgr->transfer(TMEMBER(_fixedPos));
- persistMgr->transfer(TMEMBER(_freezable));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::setupTalkFile(const char *soundFilename) {
- delete _talkDef;
- _talkDef = NULL;
- _currentSprite = NULL;
-
- if (!soundFilename) {
- return STATUS_OK;
- }
-
-
- AnsiString path = PathUtil::getDirectoryName(soundFilename);
- AnsiString name = PathUtil::getFileNameWithoutExtension(soundFilename);
-
- AnsiString talkDefFileName = PathUtil::combine(path, name + ".talk");
-
- if (!BaseFileManager::getEngineInstance()->hasFile(talkDefFileName)) {
- return STATUS_OK; // no talk def file found
- }
-
- _talkDef = new AdTalkDef(_gameRef);
- if (!_talkDef || DID_FAIL(_talkDef->loadFile(talkDefFileName.c_str()))) {
- delete _talkDef;
- _talkDef = NULL;
- return STATUS_FAILED;
- }
- //_gameRef->LOG(0, "Using .talk file: %s", TalkDefFile);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::update(TDirection dir) {
- if (!_talkDef) {
- return STATUS_OK;
- }
-
- uint32 currentTime;
- // if sound is available, synchronize with sound, otherwise use timer
-
- /*
- if (_sound) CurrentTime = _sound->GetPositionTime();
- else CurrentTime = _gameRef->_timer - _startTime;
- */
- currentTime = _gameRef->_timer - _startTime;
-
- bool talkNodeFound = false;
- for (uint32 i = 0; i < _talkDef->_nodes.size(); i++) {
- if (_talkDef->_nodes[i]->isInTimeInterval(currentTime, dir)) {
- talkNodeFound = true;
-
- BaseSprite *newSprite = _talkDef->_nodes[i]->getSprite(dir);
- if (newSprite != _currentSprite) {
- newSprite->reset();
- }
- _currentSprite = newSprite;
-
- if (!_talkDef->_nodes[i]->_playToEnd) {
- break;
- }
- }
- }
-
-
- // no talk node, try to use default sprite instead (if any)
- if (!talkNodeFound) {
- BaseSprite *newSprite = _talkDef->getDefaultSprite(dir);
- if (newSprite) {
- if (newSprite != _currentSprite) {
- newSprite->reset();
- }
- _currentSprite = newSprite;
- } else {
- _currentSprite = NULL;
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSentence::canSkip() {
- // prevent accidental sentence skipping (TODO make configurable)
- return (_gameRef->_timer - _startTime) > 300;
-}
-
-} // 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/ad/ad_sentence.h"
+#include "engines/wintermute/ad/ad_talk_def.h"
+#include "engines/wintermute/ad/ad_talk_node.h"
+#include "engines/wintermute/ad/ad_game.h"
+#include "engines/wintermute/utils/path_util.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/sound/base_sound.h"
+#include "engines/wintermute/ad/ad_scene.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_file_manager.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdSentence, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdSentence::AdSentence(BaseGame *inGame) : BaseClass(inGame) {
+ _text = NULL;
+ _stances = NULL;
+ _tempStance = NULL;
+
+ _duration = 0;
+ _startTime = 0;
+ _currentStance = 0;
+
+ _font = NULL;
+
+ _pos.x = _pos.y = 0;
+ _width = _gameRef->_renderer->_width;
+
+ _align = (TTextAlign)TAL_CENTER;
+
+ _sound = NULL;
+ _soundStarted = false;
+
+ _talkDef = NULL;
+ _currentSprite = NULL;
+ _currentSkelAnim = NULL;
+ _fixedPos = false;
+ _freezable = true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSentence::~AdSentence() {
+ delete _sound;
+ delete[] _text;
+ delete[] _stances;
+ delete[] _tempStance;
+ delete _talkDef;
+ _sound = NULL;
+ _text = NULL;
+ _stances = NULL;
+ _tempStance = NULL;
+ _talkDef = NULL;
+
+ _currentSprite = NULL; // ref only
+ _currentSkelAnim = NULL;
+ _font = NULL; // ref only
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdSentence::setText(const char *text) {
+ if (_text) {
+ delete[] _text;
+ }
+ _text = new char[strlen(text) + 1];
+ if (_text) {
+ strcpy(_text, text);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdSentence::setStances(const char *stances) {
+ if (_stances) {
+ delete[] _stances;
+ }
+ if (stances) {
+ _stances = new char[strlen(stances) + 1];
+ if (_stances) {
+ strcpy(_stances, stances);
+ }
+ } else {
+ _stances = NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *AdSentence::getCurrentStance() {
+ return getStance(_currentStance);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *AdSentence::getNextStance() {
+ _currentStance++;
+ return getStance(_currentStance);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *AdSentence::getStance(int stance) {
+ if (_stances == NULL) {
+ return NULL;
+ }
+
+ if (_tempStance) {
+ delete[] _tempStance;
+ }
+ _tempStance = NULL;
+
+ char *start;
+ char *curr;
+ int pos;
+
+ if (stance == 0) {
+ start = _stances;
+ } else {
+ pos = 0;
+ start = NULL;
+ curr = _stances;
+ while (pos < stance) {
+ if (*curr == '\0') {
+ break;
+ }
+ if (*curr == ',') {
+ pos++;
+ }
+ curr++;
+ }
+ if (pos == stance) {
+ start = curr;
+ }
+ }
+
+ if (start == NULL) {
+ return NULL;
+ }
+
+ while (*start == ' ' && *start != ',' && *start != '\0') {
+ start++;
+ }
+
+ curr = start;
+ while (*curr != '\0' && *curr != ',') {
+ curr++;
+ }
+
+ while (curr > start && *(curr - 1) == ' ') {
+ curr--;
+ }
+
+ _tempStance = new char [curr - start + 1];
+ if (_tempStance) {
+ Common::strlcpy(_tempStance, start, curr - start + 1);
+ }
+
+ return _tempStance;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::display() {
+ if (!_font || !_text) {
+ return STATUS_FAILED;
+ }
+
+ if (_sound && !_soundStarted) {
+ _sound->play();
+ _soundStarted = true;
+ }
+
+ if (_gameRef->_subtitles) {
+ int x = _pos.x;
+ int y = _pos.y;
+
+ if (!_fixedPos) {
+ x = x - ((AdGame *)_gameRef)->_scene->getOffsetLeft();
+ y = y - ((AdGame *)_gameRef)->_scene->getOffsetTop();
+ }
+
+
+ x = MAX(x, 0);
+ x = MIN(x, _gameRef->_renderer->_width - _width);
+ y = MAX(y, 0);
+
+ _font->drawText((byte *)_text, x, y, _width, _align);
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdSentence::setSound(BaseSound *sound) {
+ if (!sound) {
+ return;
+ }
+ delete _sound;
+ _sound = sound;
+ _soundStarted = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::finish() {
+ if (_sound) {
+ _sound->stop();
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::persist(BasePersistenceManager *persistMgr) {
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+
+ persistMgr->transfer(TMEMBER_INT(_align));
+ persistMgr->transfer(TMEMBER(_currentStance));
+ persistMgr->transfer(TMEMBER(_currentSprite));
+ persistMgr->transfer(TMEMBER(_currentSkelAnim));
+ persistMgr->transfer(TMEMBER(_duration));
+ persistMgr->transfer(TMEMBER(_font));
+ persistMgr->transfer(TMEMBER(_pos));
+ persistMgr->transfer(TMEMBER(_sound));
+ persistMgr->transfer(TMEMBER(_soundStarted));
+ persistMgr->transfer(TMEMBER(_stances));
+ persistMgr->transfer(TMEMBER(_startTime));
+ persistMgr->transfer(TMEMBER(_talkDef));
+ persistMgr->transfer(TMEMBER(_tempStance));
+ persistMgr->transfer(TMEMBER(_text));
+ persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transfer(TMEMBER(_fixedPos));
+ persistMgr->transfer(TMEMBER(_freezable));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::setupTalkFile(const char *soundFilename) {
+ delete _talkDef;
+ _talkDef = NULL;
+ _currentSprite = NULL;
+
+ if (!soundFilename) {
+ return STATUS_OK;
+ }
+
+
+ AnsiString path = PathUtil::getDirectoryName(soundFilename);
+ AnsiString name = PathUtil::getFileNameWithoutExtension(soundFilename);
+
+ AnsiString talkDefFileName = PathUtil::combine(path, name + ".talk");
+
+ if (!BaseFileManager::getEngineInstance()->hasFile(talkDefFileName)) {
+ return STATUS_OK; // no talk def file found
+ }
+
+ _talkDef = new AdTalkDef(_gameRef);
+ if (!_talkDef || DID_FAIL(_talkDef->loadFile(talkDefFileName.c_str()))) {
+ delete _talkDef;
+ _talkDef = NULL;
+ return STATUS_FAILED;
+ }
+ //_gameRef->LOG(0, "Using .talk file: %s", TalkDefFile);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::update(TDirection dir) {
+ if (!_talkDef) {
+ return STATUS_OK;
+ }
+
+ uint32 currentTime;
+ // if sound is available, synchronize with sound, otherwise use timer
+
+ /*
+ if (_sound) CurrentTime = _sound->GetPositionTime();
+ else CurrentTime = _gameRef->_timer - _startTime;
+ */
+ currentTime = _gameRef->_timer - _startTime;
+
+ bool talkNodeFound = false;
+ for (uint32 i = 0; i < _talkDef->_nodes.size(); i++) {
+ if (_talkDef->_nodes[i]->isInTimeInterval(currentTime, dir)) {
+ talkNodeFound = true;
+
+ BaseSprite *newSprite = _talkDef->_nodes[i]->getSprite(dir);
+ if (newSprite != _currentSprite) {
+ newSprite->reset();
+ }
+ _currentSprite = newSprite;
+
+ if (!_talkDef->_nodes[i]->_playToEnd) {
+ break;
+ }
+ }
+ }
+
+
+ // no talk node, try to use default sprite instead (if any)
+ if (!talkNodeFound) {
+ BaseSprite *newSprite = _talkDef->getDefaultSprite(dir);
+ if (newSprite) {
+ if (newSprite != _currentSprite) {
+ newSprite->reset();
+ }
+ _currentSprite = newSprite;
+ } else {
+ _currentSprite = NULL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSentence::canSkip() {
+ // prevent accidental sentence skipping (TODO make configurable)
+ return (_gameRef->_timer - _startTime) > 300;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_sentence.h b/engines/wintermute/ad/ad_sentence.h
index 85be09094c..e7c94030b9 100644
--- a/engines/wintermute/ad/ad_sentence.h
+++ b/engines/wintermute/ad/ad_sentence.h
@@ -1,85 +1,85 @@
-/* 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_ADSENTENCE_H
-#define WINTERMUTE_ADSENTENCE_H
-
-
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/math/rect32.h"
-#include "engines/wintermute/dctypes.h" // Added by ClassView
-#include "common/rect.h"
-
-namespace Wintermute {
-class AdTalkDef;
-class BaseFont;
-class BaseSprite;
-class BaseSound;
-class AdSentence : public BaseClass {
-public:
- bool _freezable;
- bool _fixedPos;
- BaseSprite *_currentSprite;
- char *_currentSkelAnim;
- bool update(TDirection dir = DI_DOWN);
- bool setupTalkFile(const char *soundFilename);
- DECLARE_PERSISTENT(AdSentence, BaseClass)
- bool finish();
- void setSound(BaseSound *Sound);
- bool _soundStarted;
- BaseSound *_sound;
- TTextAlign _align;
- bool display();
- int _width;
- Point32 _pos;
- BaseFont *_font;
- char *getNextStance();
- char *getCurrentStance();
- void setStances(const char *stances);
- void setText(const char *text);
- int _currentStance;
- uint32 _startTime;
- char *_stances;
- char *_text;
- uint32 _duration;
- AdSentence(BaseGame *inGame);
- virtual ~AdSentence();
- AdTalkDef *_talkDef;
-
- bool canSkip();
-
-private:
- char *_tempStance;
- char *getStance(int stance);
-
-};
-
-} // 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_ADSENTENCE_H
+#define WINTERMUTE_ADSENTENCE_H
+
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/math/rect32.h"
+#include "engines/wintermute/dctypes.h" // Added by ClassView
+#include "common/rect.h"
+
+namespace Wintermute {
+class AdTalkDef;
+class BaseFont;
+class BaseSprite;
+class BaseSound;
+class AdSentence : public BaseClass {
+public:
+ bool _freezable;
+ bool _fixedPos;
+ BaseSprite *_currentSprite;
+ char *_currentSkelAnim;
+ bool update(TDirection dir = DI_DOWN);
+ bool setupTalkFile(const char *soundFilename);
+ DECLARE_PERSISTENT(AdSentence, BaseClass)
+ bool finish();
+ void setSound(BaseSound *Sound);
+ bool _soundStarted;
+ BaseSound *_sound;
+ TTextAlign _align;
+ bool display();
+ int _width;
+ Point32 _pos;
+ BaseFont *_font;
+ char *getNextStance();
+ char *getCurrentStance();
+ void setStances(const char *stances);
+ void setText(const char *text);
+ int _currentStance;
+ uint32 _startTime;
+ char *_stances;
+ char *_text;
+ uint32 _duration;
+ AdSentence(BaseGame *inGame);
+ virtual ~AdSentence();
+ AdTalkDef *_talkDef;
+
+ bool canSkip();
+
+private:
+ char *_tempStance;
+ char *getStance(int stance);
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_sprite_set.cpp b/engines/wintermute/ad/ad_sprite_set.cpp
index 5b605d6e32..c8cdec03c3 100644
--- a/engines/wintermute/ad/ad_sprite_set.cpp
+++ b/engines/wintermute/ad/ad_sprite_set.cpp
@@ -1,356 +1,356 @@
-/* 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/ad/ad_sprite_set.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/base_sprite.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdSpriteSet, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdSpriteSet::AdSpriteSet(BaseGame *inGame, BaseObject *owner) : BaseObject(inGame) {
- _owner = owner;
-
- for (int i = 0; i < NUM_DIRECTIONS; i++) {
- _sprites[i] = NULL;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdSpriteSet::~AdSpriteSet() {
- for (int i = 0; i < NUM_DIRECTIONS; i++) {
- delete _sprites[i];
- _sprites[i] = NULL;
- }
-
- _owner = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::loadFile(const char *filename, int lifeTime, TSpriteCacheType cacheType) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdSpriteSet::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing SPRITESET file '%s'", filename);
- }
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(SPRITESET)
-TOKEN_DEF(NAME)
-TOKEN_DEF(UP_LEFT)
-TOKEN_DEF(DOWN_LEFT)
-TOKEN_DEF(LEFT)
-TOKEN_DEF(UP_RIGHT)
-TOKEN_DEF(DOWN_RIGHT)
-TOKEN_DEF(RIGHT)
-TOKEN_DEF(UP)
-TOKEN_DEF(DOWN)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(SPRITESET)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(UP_LEFT)
- TOKEN_TABLE(DOWN_LEFT)
- TOKEN_TABLE(LEFT)
- TOKEN_TABLE(UP_RIGHT)
- TOKEN_TABLE(DOWN_RIGHT)
- TOKEN_TABLE(RIGHT)
- TOKEN_TABLE(UP)
- TOKEN_TABLE(DOWN)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITESET) {
- _gameRef->LOG(0, "'SPRITESET' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- BaseSprite *spr = NULL;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_LEFT:
- delete _sprites[DI_LEFT];
- _sprites[DI_LEFT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_LEFT] = spr;
- }
- break;
-
- case TOKEN_RIGHT:
- delete _sprites[DI_RIGHT];
- _sprites[DI_RIGHT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_RIGHT] = spr;
- }
- break;
-
- case TOKEN_UP:
- delete _sprites[DI_UP];
- _sprites[DI_UP] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_UP] = spr;
- }
- break;
-
- case TOKEN_DOWN:
- delete _sprites[DI_DOWN];
- _sprites[DI_DOWN] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_DOWN] = spr;
- }
- break;
-
- case TOKEN_UP_LEFT:
- delete _sprites[DI_UPLEFT];
- _sprites[DI_UPLEFT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_UPLEFT] = spr;
- }
- break;
-
- case TOKEN_UP_RIGHT:
- delete _sprites[DI_UPRIGHT];
- _sprites[DI_UPRIGHT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_UPRIGHT] = spr;
- }
- break;
-
- case TOKEN_DOWN_LEFT:
- delete _sprites[DI_DOWNLEFT];
- _sprites[DI_DOWNLEFT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_DOWNLEFT] = spr;
- }
- break;
-
- case TOKEN_DOWN_RIGHT:
- delete _sprites[DI_DOWNRIGHT];
- _sprites[DI_DOWNRIGHT] = NULL;
- spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
- cmd = PARSERR_GENERIC;
- } else {
- _sprites[DI_DOWNRIGHT] = spr;
- }
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in SPRITESET definition");
- return STATUS_FAILED;
- }
-
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading SPRITESET definition");
- if (spr) {
- delete spr;
- }
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_owner));
- for (int i = 0; i < NUM_DIRECTIONS; i++) {
- persistMgr->transfer("", &_sprites[i]);
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdSpriteSet::getSprite(TDirection direction) {
- int dir = (int)direction;
- if (dir < 0) {
- dir = 0;
- }
- if (dir >= NUM_DIRECTIONS) {
- dir = NUM_DIRECTIONS - 1;
- }
-
- BaseSprite *ret = NULL;
-
- // find nearest set sprite
- int numSteps = 0;
- for (int i = dir; i >= 0; i--) {
- if (_sprites[i] != NULL) {
- ret = _sprites[i];
- numSteps = dir - i;
- break;
- }
- }
-
- for (int i = dir; i < NUM_DIRECTIONS; i++) {
- if (_sprites[i] != NULL) {
- if (ret == NULL || numSteps > i - dir) {
- return _sprites[i];
- } else {
- return ret;
- }
- }
- }
-
- return ret;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "SPRITESET {\n");
- if (getName()) {
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- }
- for (int i = 0; i < NUM_DIRECTIONS; i++) {
- if (_sprites[i]) {
- switch (i) {
- case DI_UP:
- buffer->putTextIndent(indent + 2, "UP=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_UPRIGHT:
- buffer->putTextIndent(indent + 2, "UP_RIGHT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_RIGHT:
- buffer->putTextIndent(indent + 2, "RIGHT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_DOWNRIGHT:
- buffer->putTextIndent(indent + 2, "DOWN_RIGHT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_DOWN:
- buffer->putTextIndent(indent + 2, "DOWN=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_DOWNLEFT:
- buffer->putTextIndent(indent + 2, "DOWN_LEFT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_LEFT:
- buffer->putTextIndent(indent + 2, "LEFT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- case DI_UPLEFT:
- buffer->putTextIndent(indent + 2, "UP_LEFT=\"%s\"\n", _sprites[i]->getFilename());
- break;
- }
- }
- }
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::containsSprite(BaseSprite *sprite) {
- if (!sprite) {
- return false;
- }
-
- for (int i = 0; i < NUM_DIRECTIONS; i++) {
- if (_sprites[i] == sprite) {
- return true;
- }
- }
- return false;
-}
-
-} // 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/ad/ad_sprite_set.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/base_sprite.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdSpriteSet, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdSpriteSet::AdSpriteSet(BaseGame *inGame, BaseObject *owner) : BaseObject(inGame) {
+ _owner = owner;
+
+ for (int i = 0; i < NUM_DIRECTIONS; i++) {
+ _sprites[i] = NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdSpriteSet::~AdSpriteSet() {
+ for (int i = 0; i < NUM_DIRECTIONS; i++) {
+ delete _sprites[i];
+ _sprites[i] = NULL;
+ }
+
+ _owner = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSpriteSet::loadFile(const char *filename, int lifeTime, TSpriteCacheType cacheType) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdSpriteSet::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing SPRITESET file '%s'", filename);
+ }
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(SPRITESET)
+TOKEN_DEF(NAME)
+TOKEN_DEF(UP_LEFT)
+TOKEN_DEF(DOWN_LEFT)
+TOKEN_DEF(LEFT)
+TOKEN_DEF(UP_RIGHT)
+TOKEN_DEF(DOWN_RIGHT)
+TOKEN_DEF(RIGHT)
+TOKEN_DEF(UP)
+TOKEN_DEF(DOWN)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(SPRITESET)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(UP_LEFT)
+ TOKEN_TABLE(DOWN_LEFT)
+ TOKEN_TABLE(LEFT)
+ TOKEN_TABLE(UP_RIGHT)
+ TOKEN_TABLE(DOWN_RIGHT)
+ TOKEN_TABLE(RIGHT)
+ TOKEN_TABLE(UP)
+ TOKEN_TABLE(DOWN)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITESET) {
+ _gameRef->LOG(0, "'SPRITESET' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ BaseSprite *spr = NULL;
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_LEFT:
+ delete _sprites[DI_LEFT];
+ _sprites[DI_LEFT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_LEFT] = spr;
+ }
+ break;
+
+ case TOKEN_RIGHT:
+ delete _sprites[DI_RIGHT];
+ _sprites[DI_RIGHT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_RIGHT] = spr;
+ }
+ break;
+
+ case TOKEN_UP:
+ delete _sprites[DI_UP];
+ _sprites[DI_UP] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_UP] = spr;
+ }
+ break;
+
+ case TOKEN_DOWN:
+ delete _sprites[DI_DOWN];
+ _sprites[DI_DOWN] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_DOWN] = spr;
+ }
+ break;
+
+ case TOKEN_UP_LEFT:
+ delete _sprites[DI_UPLEFT];
+ _sprites[DI_UPLEFT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_UPLEFT] = spr;
+ }
+ break;
+
+ case TOKEN_UP_RIGHT:
+ delete _sprites[DI_UPRIGHT];
+ _sprites[DI_UPRIGHT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_UPRIGHT] = spr;
+ }
+ break;
+
+ case TOKEN_DOWN_LEFT:
+ delete _sprites[DI_DOWNLEFT];
+ _sprites[DI_DOWNLEFT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_DOWNLEFT] = spr;
+ }
+ break;
+
+ case TOKEN_DOWN_RIGHT:
+ delete _sprites[DI_DOWNRIGHT];
+ _sprites[DI_DOWNRIGHT] = NULL;
+ spr = new BaseSprite(_gameRef, _owner);
+ if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ cmd = PARSERR_GENERIC;
+ } else {
+ _sprites[DI_DOWNRIGHT] = spr;
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in SPRITESET definition");
+ return STATUS_FAILED;
+ }
+
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading SPRITESET definition");
+ if (spr) {
+ delete spr;
+ }
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSpriteSet::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_owner));
+ for (int i = 0; i < NUM_DIRECTIONS; i++) {
+ persistMgr->transfer("", &_sprites[i]);
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdSpriteSet::getSprite(TDirection direction) {
+ int dir = (int)direction;
+ if (dir < 0) {
+ dir = 0;
+ }
+ if (dir >= NUM_DIRECTIONS) {
+ dir = NUM_DIRECTIONS - 1;
+ }
+
+ BaseSprite *ret = NULL;
+
+ // find nearest set sprite
+ int numSteps = 0;
+ for (int i = dir; i >= 0; i--) {
+ if (_sprites[i] != NULL) {
+ ret = _sprites[i];
+ numSteps = dir - i;
+ break;
+ }
+ }
+
+ for (int i = dir; i < NUM_DIRECTIONS; i++) {
+ if (_sprites[i] != NULL) {
+ if (ret == NULL || numSteps > i - dir) {
+ return _sprites[i];
+ } else {
+ return ret;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSpriteSet::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "SPRITESET {\n");
+ if (getName()) {
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ }
+ for (int i = 0; i < NUM_DIRECTIONS; i++) {
+ if (_sprites[i]) {
+ switch (i) {
+ case DI_UP:
+ buffer->putTextIndent(indent + 2, "UP=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_UPRIGHT:
+ buffer->putTextIndent(indent + 2, "UP_RIGHT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_RIGHT:
+ buffer->putTextIndent(indent + 2, "RIGHT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_DOWNRIGHT:
+ buffer->putTextIndent(indent + 2, "DOWN_RIGHT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_DOWN:
+ buffer->putTextIndent(indent + 2, "DOWN=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_DOWNLEFT:
+ buffer->putTextIndent(indent + 2, "DOWN_LEFT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_LEFT:
+ buffer->putTextIndent(indent + 2, "LEFT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ case DI_UPLEFT:
+ buffer->putTextIndent(indent + 2, "UP_LEFT=\"%s\"\n", _sprites[i]->getFilename());
+ break;
+ }
+ }
+ }
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool AdSpriteSet::containsSprite(BaseSprite *sprite) {
+ if (!sprite) {
+ return false;
+ }
+
+ for (int i = 0; i < NUM_DIRECTIONS; i++) {
+ if (_sprites[i] == sprite) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_sprite_set.h b/engines/wintermute/ad/ad_sprite_set.h
index 3855114850..ba5da0ff2e 100644
--- a/engines/wintermute/ad/ad_sprite_set.h
+++ b/engines/wintermute/ad/ad_sprite_set.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_ADSPRITESET_H
-#define WINTERMUTE_ADSPRITESET_H
-
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-class BaseSprite;
-class AdSpriteSet : public BaseObject {
-public:
- bool containsSprite(BaseSprite *sprite);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
- BaseSprite *getSprite(TDirection direction);
- DECLARE_PERSISTENT(AdSpriteSet, BaseObject)
- BaseObject *_owner;
- AdSpriteSet(BaseGame *inGame, BaseObject *owner = NULL);
- virtual ~AdSpriteSet();
- bool loadFile(const char *filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
- bool loadBuffer(byte *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
- BaseSprite *_sprites[NUM_DIRECTIONS];
-};
-
-} // 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_ADSPRITESET_H
+#define WINTERMUTE_ADSPRITESET_H
+
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+class BaseSprite;
+class AdSpriteSet : public BaseObject {
+public:
+ bool containsSprite(BaseSprite *sprite);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
+ BaseSprite *getSprite(TDirection direction);
+ DECLARE_PERSISTENT(AdSpriteSet, BaseObject)
+ BaseObject *_owner;
+ AdSpriteSet(BaseGame *inGame, BaseObject *owner = NULL);
+ virtual ~AdSpriteSet();
+ bool loadFile(const char *filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
+ bool loadBuffer(byte *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
+ BaseSprite *_sprites[NUM_DIRECTIONS];
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_talk_def.cpp b/engines/wintermute/ad/ad_talk_def.cpp
index cd96345fc8..8cb489509b 100644
--- a/engines/wintermute/ad/ad_talk_def.cpp
+++ b/engines/wintermute/ad/ad_talk_def.cpp
@@ -1,285 +1,285 @@
-/* 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/ad/ad_talk_def.h"
-#include "engines/wintermute/ad/ad_talk_node.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/ad/ad_sprite_set.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/utils/utils.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdTalkDef, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkDef::AdTalkDef(BaseGame *inGame) : BaseObject(inGame) {
- _defaultSpriteFilename = NULL;
- _defaultSprite = NULL;
-
- _defaultSpriteSetFilename = NULL;
- _defaultSpriteSet = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkDef::~AdTalkDef() {
- for (uint32 i = 0; i < _nodes.size(); i++) {
- delete _nodes[i];
- }
- _nodes.clear();
-
- delete[] _defaultSpriteFilename;
- delete _defaultSprite;
- _defaultSpriteFilename = NULL;
- _defaultSprite = NULL;
-
- delete[] _defaultSpriteSetFilename;
- delete _defaultSpriteSet;
- _defaultSpriteSetFilename = NULL;
- _defaultSpriteSet = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdTalkDef::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing TALK file '%s'", filename);
- }
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(TALK)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(ACTION)
-TOKEN_DEF(DEFAULT_SPRITESET_FILE)
-TOKEN_DEF(DEFAULT_SPRITESET)
-TOKEN_DEF(DEFAULT_SPRITE)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(TALK)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(ACTION)
- TOKEN_TABLE(DEFAULT_SPRITESET_FILE)
- TOKEN_TABLE(DEFAULT_SPRITESET)
- TOKEN_TABLE(DEFAULT_SPRITE)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TALK) {
- _gameRef->LOG(0, "'TALK' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_ACTION: {
- AdTalkNode *node = new AdTalkNode(_gameRef);
- if (node && DID_SUCCEED(node->loadBuffer(params, false))) {
- _nodes.add(node);
- } else {
- delete node;
- node = NULL;
- cmd = PARSERR_GENERIC;
- }
- }
- break;
-
- case TOKEN_DEFAULT_SPRITE:
- BaseUtils::setString(&_defaultSpriteFilename, (char *)params);
- break;
-
- case TOKEN_DEFAULT_SPRITESET_FILE:
- BaseUtils::setString(&_defaultSpriteSetFilename, (char *)params);
- break;
-
- case TOKEN_DEFAULT_SPRITESET: {
- delete _defaultSpriteSet;
- _defaultSpriteSet = new AdSpriteSet(_gameRef);
- if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadBuffer(params, false))) {
- delete _defaultSpriteSet;
- _defaultSpriteSet = NULL;
- cmd = PARSERR_GENERIC;
- }
- }
- break;
-
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in TALK definition");
- return STATUS_FAILED;
- }
-
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading TALK definition");
- return STATUS_FAILED;
- }
-
- delete _defaultSprite;
- delete _defaultSpriteSet;
- _defaultSprite = NULL;
- _defaultSpriteSet = NULL;
-
- if (_defaultSpriteFilename) {
- _defaultSprite = new BaseSprite(_gameRef);
- if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
- return STATUS_FAILED;
- }
- }
-
- if (_defaultSpriteSetFilename) {
- _defaultSpriteSet = new AdSpriteSet(_gameRef);
- if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
- return STATUS_FAILED;
- }
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_defaultSprite));
- persistMgr->transfer(TMEMBER(_defaultSpriteFilename));
- persistMgr->transfer(TMEMBER(_defaultSpriteSet));
- persistMgr->transfer(TMEMBER(_defaultSpriteSetFilename));
-
- _nodes.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "TALK {\n");
- if (_defaultSpriteFilename) {
- buffer->putTextIndent(indent + 2, "DEFAULT_SPRITE=\"%s\"\n", _defaultSpriteFilename);
- }
-
- if (_defaultSpriteSetFilename) {
- buffer->putTextIndent(indent + 2, "DEFAULT_SPRITESET_FILE=\"%s\"\n", _defaultSpriteSetFilename);
- } else if (_defaultSpriteSet) {
- _defaultSpriteSet->saveAsText(buffer, indent + 2);
- }
-
- for (uint32 i = 0; i < _nodes.size(); i++) {
- _nodes[i]->saveAsText(buffer, indent + 2);
- buffer->putTextIndent(indent, "\n");
- }
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::loadDefaultSprite() {
- if (_defaultSpriteFilename && !_defaultSprite) {
- _defaultSprite = new BaseSprite(_gameRef);
- if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
- delete _defaultSprite;
- _defaultSprite = NULL;
- return STATUS_FAILED;
- } else {
- return STATUS_OK;
- }
- } else if (_defaultSpriteSetFilename && !_defaultSpriteSet) {
- _defaultSpriteSet = new AdSpriteSet(_gameRef);
- if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
- delete _defaultSpriteSet;
- _defaultSpriteSet = NULL;
- return STATUS_FAILED;
- } else {
- return STATUS_OK;
- }
- } else {
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdTalkDef::getDefaultSprite(TDirection dir) {
- loadDefaultSprite();
- if (_defaultSprite) {
- return _defaultSprite;
- } else if (_defaultSpriteSet) {
- return _defaultSpriteSet->getSprite(dir);
- } else {
- return NULL;
- }
-}
-
-} // 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/ad/ad_talk_def.h"
+#include "engines/wintermute/ad/ad_talk_node.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/ad/ad_sprite_set.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/utils/utils.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdTalkDef, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkDef::AdTalkDef(BaseGame *inGame) : BaseObject(inGame) {
+ _defaultSpriteFilename = NULL;
+ _defaultSprite = NULL;
+
+ _defaultSpriteSetFilename = NULL;
+ _defaultSpriteSet = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkDef::~AdTalkDef() {
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ delete _nodes[i];
+ }
+ _nodes.clear();
+
+ delete[] _defaultSpriteFilename;
+ delete _defaultSprite;
+ _defaultSpriteFilename = NULL;
+ _defaultSprite = NULL;
+
+ delete[] _defaultSpriteSetFilename;
+ delete _defaultSpriteSet;
+ _defaultSpriteSetFilename = NULL;
+ _defaultSpriteSet = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkDef::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdTalkDef::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing TALK file '%s'", filename);
+ }
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(TALK)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(ACTION)
+TOKEN_DEF(DEFAULT_SPRITESET_FILE)
+TOKEN_DEF(DEFAULT_SPRITESET)
+TOKEN_DEF(DEFAULT_SPRITE)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(TALK)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(ACTION)
+ TOKEN_TABLE(DEFAULT_SPRITESET_FILE)
+ TOKEN_TABLE(DEFAULT_SPRITESET)
+ TOKEN_TABLE(DEFAULT_SPRITE)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TALK) {
+ _gameRef->LOG(0, "'TALK' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_ACTION: {
+ AdTalkNode *node = new AdTalkNode(_gameRef);
+ if (node && DID_SUCCEED(node->loadBuffer(params, false))) {
+ _nodes.add(node);
+ } else {
+ delete node;
+ node = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ }
+ break;
+
+ case TOKEN_DEFAULT_SPRITE:
+ BaseUtils::setString(&_defaultSpriteFilename, (char *)params);
+ break;
+
+ case TOKEN_DEFAULT_SPRITESET_FILE:
+ BaseUtils::setString(&_defaultSpriteSetFilename, (char *)params);
+ break;
+
+ case TOKEN_DEFAULT_SPRITESET: {
+ delete _defaultSpriteSet;
+ _defaultSpriteSet = new AdSpriteSet(_gameRef);
+ if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadBuffer(params, false))) {
+ delete _defaultSpriteSet;
+ _defaultSpriteSet = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ }
+ break;
+
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in TALK definition");
+ return STATUS_FAILED;
+ }
+
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading TALK definition");
+ return STATUS_FAILED;
+ }
+
+ delete _defaultSprite;
+ delete _defaultSpriteSet;
+ _defaultSprite = NULL;
+ _defaultSpriteSet = NULL;
+
+ if (_defaultSpriteFilename) {
+ _defaultSprite = new BaseSprite(_gameRef);
+ if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
+ return STATUS_FAILED;
+ }
+ }
+
+ if (_defaultSpriteSetFilename) {
+ _defaultSpriteSet = new AdSpriteSet(_gameRef);
+ if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
+ return STATUS_FAILED;
+ }
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkDef::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_defaultSprite));
+ persistMgr->transfer(TMEMBER(_defaultSpriteFilename));
+ persistMgr->transfer(TMEMBER(_defaultSpriteSet));
+ persistMgr->transfer(TMEMBER(_defaultSpriteSetFilename));
+
+ _nodes.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkDef::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "TALK {\n");
+ if (_defaultSpriteFilename) {
+ buffer->putTextIndent(indent + 2, "DEFAULT_SPRITE=\"%s\"\n", _defaultSpriteFilename);
+ }
+
+ if (_defaultSpriteSetFilename) {
+ buffer->putTextIndent(indent + 2, "DEFAULT_SPRITESET_FILE=\"%s\"\n", _defaultSpriteSetFilename);
+ } else if (_defaultSpriteSet) {
+ _defaultSpriteSet->saveAsText(buffer, indent + 2);
+ }
+
+ for (uint32 i = 0; i < _nodes.size(); i++) {
+ _nodes[i]->saveAsText(buffer, indent + 2);
+ buffer->putTextIndent(indent, "\n");
+ }
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkDef::loadDefaultSprite() {
+ if (_defaultSpriteFilename && !_defaultSprite) {
+ _defaultSprite = new BaseSprite(_gameRef);
+ if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
+ delete _defaultSprite;
+ _defaultSprite = NULL;
+ return STATUS_FAILED;
+ } else {
+ return STATUS_OK;
+ }
+ } else if (_defaultSpriteSetFilename && !_defaultSpriteSet) {
+ _defaultSpriteSet = new AdSpriteSet(_gameRef);
+ if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
+ delete _defaultSpriteSet;
+ _defaultSpriteSet = NULL;
+ return STATUS_FAILED;
+ } else {
+ return STATUS_OK;
+ }
+ } else {
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdTalkDef::getDefaultSprite(TDirection dir) {
+ loadDefaultSprite();
+ if (_defaultSprite) {
+ return _defaultSprite;
+ } else if (_defaultSpriteSet) {
+ return _defaultSpriteSet->getSprite(dir);
+ } else {
+ return NULL;
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_def.h b/engines/wintermute/ad/ad_talk_def.h
index f748aa4e7a..d147212775 100644
--- a/engines/wintermute/ad/ad_talk_def.h
+++ b/engines/wintermute/ad/ad_talk_def.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_ADTALKDEF_H
-#define WINTERMUTE_ADTALKDEF_H
-
-#include "engines/wintermute/coll_templ.h"
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-class AdTalkNode;
-class AdSpriteSet;
-class AdTalkDef : public BaseObject {
-public:
- char *_defaultSpriteSetFilename;
- AdSpriteSet *_defaultSpriteSet;
- BaseSprite *getDefaultSprite(TDirection Dir);
- bool loadDefaultSprite();
- DECLARE_PERSISTENT(AdTalkDef, BaseObject)
-
- AdTalkDef(BaseGame *inGame);
- virtual ~AdTalkDef();
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- BaseArray<AdTalkNode *> _nodes;
- char *_defaultSpriteFilename;
- BaseSprite *_defaultSprite;
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
-};
-
-} // 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_ADTALKDEF_H
+#define WINTERMUTE_ADTALKDEF_H
+
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+class AdTalkNode;
+class AdSpriteSet;
+class AdTalkDef : public BaseObject {
+public:
+ char *_defaultSpriteSetFilename;
+ AdSpriteSet *_defaultSpriteSet;
+ BaseSprite *getDefaultSprite(TDirection Dir);
+ bool loadDefaultSprite();
+ DECLARE_PERSISTENT(AdTalkDef, BaseObject)
+
+ AdTalkDef(BaseGame *inGame);
+ virtual ~AdTalkDef();
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ BaseArray<AdTalkNode *> _nodes;
+ char *_defaultSpriteFilename;
+ BaseSprite *_defaultSprite;
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_talk_holder.cpp b/engines/wintermute/ad/ad_talk_holder.cpp
index 89d7bd8a46..1e4ec26459 100644
--- a/engines/wintermute/ad/ad_talk_holder.cpp
+++ b/engines/wintermute/ad/ad_talk_holder.cpp
@@ -1,402 +1,402 @@
-/* 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/ad/ad_talk_holder.h"
-#include "engines/wintermute/base/base_dynamic_buffer.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/base_game.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/base/base_engine.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdTalkHolder, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkHolder::AdTalkHolder(BaseGame *inGame) : AdObject(inGame) {
- _sprite = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkHolder::~AdTalkHolder() {
- delete _sprite;
- _sprite = NULL;
-
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- delete _talkSprites[i];
- }
- _talkSprites.clear();
-
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- delete _talkSpritesEx[i];
- }
- _talkSpritesEx.clear();
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdTalkHolder::getTalkStance(const char *stance) {
- BaseSprite *ret = NULL;
-
-
- // forced stance?
- if (_forcedTalkAnimName && !_forcedTalkAnimUsed) {
- _forcedTalkAnimUsed = true;
- delete _animSprite;
- _animSprite = new BaseSprite(_gameRef, this);
- if (_animSprite) {
- bool res = _animSprite->loadFile(_forcedTalkAnimName);
- if (DID_FAIL(res)) {
- _gameRef->LOG(res, "AdTalkHolder::GetTalkStance: error loading talk sprite (object:\"%s\" sprite:\"%s\")", getName(), _forcedTalkAnimName);
- delete _animSprite;
- _animSprite = NULL;
- } else {
- return _animSprite;
- }
- }
- }
-
-
- if (stance != NULL) {
- // search special talk stances
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- if (scumm_stricmp(_talkSpritesEx[i]->getName(), stance) == 0) {
- ret = _talkSpritesEx[i];
- break;
- }
- }
- if (ret == NULL) {
- // serach generic talk stances
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- if (scumm_stricmp(_talkSprites[i]->getName(), stance) == 0) {
- ret = _talkSprites[i];
- break;
- }
- }
- }
- }
-
- // not a valid stance? get a random one
- if (ret == NULL) {
- if (_talkSprites.size() < 1) {
- ret = _sprite;
- } else {
- // TODO: remember last
- int rnd = BaseEngine::instance().randInt(0, _talkSprites.size() - 1);
- ret = _talkSprites[rnd];
- }
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// high level scripting interface
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
- //////////////////////////////////////////////////////////////////////////
- // SetSprite
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "SetSprite") == 0) {
- stack->correctParams(1);
-
- ScValue *val = stack->pop();
-
- bool setCurrent = false;
- if (_currentSprite && _currentSprite == _sprite) {
- setCurrent = true;
- }
-
- delete _sprite;
- _sprite = NULL;
-
- if (val->isNULL()) {
- _sprite = NULL;
- if (setCurrent) {
- _currentSprite = NULL;
- }
- stack->pushBool(true);
- } else {
- const char *filename = val->getString();
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- script->runtimeError("SetSprite method failed for file '%s'", filename);
- stack->pushBool(false);
- } else {
- _sprite = spr;
- if (setCurrent) {
- _currentSprite = _sprite;
- }
- stack->pushBool(true);
- }
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetSprite
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetSprite") == 0) {
- stack->correctParams(0);
-
- if (!_sprite || !_sprite->getFilename()) {
- stack->pushNULL();
- } else {
- stack->pushString(_sprite->getFilename());
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GetSpriteObject
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "GetSpriteObject") == 0) {
- stack->correctParams(0);
-
- if (!_sprite) {
- stack->pushNULL();
- } else {
- stack->pushNative(_sprite, true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AddTalkSprite
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "AddTalkSprite") == 0) {
- stack->correctParams(2);
-
- const char *filename = stack->pop()->getString();
- bool ex = stack->pop()->getBool();
-
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- stack->pushBool(false);
- script->runtimeError("AddTalkSprite method failed for file '%s'", filename);
- } else {
- if (ex) {
- _talkSpritesEx.add(spr);
- } else {
- _talkSprites.add(spr);
- }
- stack->pushBool(true);
- }
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // RemoveTalkSprite
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "RemoveTalkSprite") == 0) {
- stack->correctParams(2);
-
- const char *filename = stack->pop()->getString();
- bool ex = stack->pop()->getBool();
-
- bool setCurrent = false;
- bool setTemp2 = false;
-
- if (ex) {
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- if (scumm_stricmp(_talkSpritesEx[i]->getFilename(), filename) == 0) {
- if (_currentSprite == _talkSpritesEx[i]) {
- setCurrent = true;
- }
- if (_tempSprite2 == _talkSpritesEx[i]) {
- setTemp2 = true;
- }
- delete _talkSpritesEx[i];
- _talkSpritesEx.remove_at(i);
- break;
- }
- }
- } else {
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- if (scumm_stricmp(_talkSprites[i]->getFilename(), filename) == 0) {
- if (_currentSprite == _talkSprites[i]) {
- setCurrent = true;
- }
- if (_tempSprite2 == _talkSprites[i]) {
- setTemp2 = true;
- }
- delete _talkSprites[i];
- _talkSprites.remove_at(i);
- break;
- }
- }
-
- }
-
- stack->pushBool(true);
- if (setCurrent) {
- _currentSprite = _sprite;
- }
- if (setTemp2) {
- _tempSprite2 = _sprite;
- }
-
- return STATUS_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // SetTalkSprite
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "SetTalkSprite") == 0) {
- stack->correctParams(2);
-
- const char *filename = stack->pop()->getString();
- bool ex = stack->pop()->getBool();
- bool setCurrent = false;
- bool setTemp2 = false;
-
- BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile(filename))) {
- stack->pushBool(false);
- script->runtimeError("SetTalkSprite method failed for file '%s'", filename);
- } else {
-
- // delete current
- if (ex) {
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- if (_talkSpritesEx[i] == _currentSprite) {
- setCurrent = true;
- }
- if (_talkSpritesEx[i] == _tempSprite2) {
- setTemp2 = true;
- }
- delete _talkSpritesEx[i];
- }
- _talkSpritesEx.clear();
- } else {
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- if (_talkSprites[i] == _currentSprite) {
- setCurrent = true;
- }
- if (_talkSprites[i] == _tempSprite2) {
- setTemp2 = true;
- }
- delete _talkSprites[i];
- }
- _talkSprites.clear();
- }
-
- // set new
- if (ex) {
- _talkSpritesEx.add(spr);
- } else {
- _talkSprites.add(spr);
- }
- stack->pushBool(true);
-
- if (setCurrent) {
- _currentSprite = spr;
- }
- if (setTemp2) {
- _tempSprite2 = spr;
- }
- }
- return STATUS_OK;
- } else {
- return AdObject::scCallMethod(script, stack, thisStack, name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdTalkHolder::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type (RO)
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("talk-holder");
- return _scValue;
- } else {
- return AdObject::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkHolder::scSetProperty(const char *name, ScValue *value) {
- /*
- //////////////////////////////////////////////////////////////////////////
- // Item
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Item")==0){
- SetItem(value->getString());
- return STATUS_OK;
- }
-
- else*/ return AdObject::scSetProperty(name, value);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-const char *AdTalkHolder::scToString() {
- return "[talk-holder object]";
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkHolder::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- for (uint32 i = 0; i < _talkSprites.size(); i++) {
- if (_talkSprites[i]->getFilename()) {
- buffer->putTextIndent(indent + 2, "TALK=\"%s\"\n", _talkSprites[i]->getFilename());
- }
- }
-
- for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
- if (_talkSpritesEx[i]->getFilename()) {
- buffer->putTextIndent(indent + 2, "TALK_SPECIAL=\"%s\"\n", _talkSpritesEx[i]->getFilename());
- }
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkHolder::persist(BasePersistenceManager *persistMgr) {
- AdObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_sprite));
- _talkSprites.persist(persistMgr);
- _talkSpritesEx.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/ad/ad_talk_holder.h"
+#include "engines/wintermute/base/base_dynamic_buffer.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/base_game.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/base/base_engine.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdTalkHolder, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkHolder::AdTalkHolder(BaseGame *inGame) : AdObject(inGame) {
+ _sprite = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkHolder::~AdTalkHolder() {
+ delete _sprite;
+ _sprite = NULL;
+
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ delete _talkSprites[i];
+ }
+ _talkSprites.clear();
+
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ delete _talkSpritesEx[i];
+ }
+ _talkSpritesEx.clear();
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdTalkHolder::getTalkStance(const char *stance) {
+ BaseSprite *ret = NULL;
+
+
+ // forced stance?
+ if (_forcedTalkAnimName && !_forcedTalkAnimUsed) {
+ _forcedTalkAnimUsed = true;
+ delete _animSprite;
+ _animSprite = new BaseSprite(_gameRef, this);
+ if (_animSprite) {
+ bool res = _animSprite->loadFile(_forcedTalkAnimName);
+ if (DID_FAIL(res)) {
+ _gameRef->LOG(res, "AdTalkHolder::GetTalkStance: error loading talk sprite (object:\"%s\" sprite:\"%s\")", getName(), _forcedTalkAnimName);
+ delete _animSprite;
+ _animSprite = NULL;
+ } else {
+ return _animSprite;
+ }
+ }
+ }
+
+
+ if (stance != NULL) {
+ // search special talk stances
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ if (scumm_stricmp(_talkSpritesEx[i]->getName(), stance) == 0) {
+ ret = _talkSpritesEx[i];
+ break;
+ }
+ }
+ if (ret == NULL) {
+ // serach generic talk stances
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ if (scumm_stricmp(_talkSprites[i]->getName(), stance) == 0) {
+ ret = _talkSprites[i];
+ break;
+ }
+ }
+ }
+ }
+
+ // not a valid stance? get a random one
+ if (ret == NULL) {
+ if (_talkSprites.size() < 1) {
+ ret = _sprite;
+ } else {
+ // TODO: remember last
+ int rnd = BaseEngine::instance().randInt(0, _talkSprites.size() - 1);
+ ret = _talkSprites[rnd];
+ }
+ }
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // SetSprite
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "SetSprite") == 0) {
+ stack->correctParams(1);
+
+ ScValue *val = stack->pop();
+
+ bool setCurrent = false;
+ if (_currentSprite && _currentSprite == _sprite) {
+ setCurrent = true;
+ }
+
+ delete _sprite;
+ _sprite = NULL;
+
+ if (val->isNULL()) {
+ _sprite = NULL;
+ if (setCurrent) {
+ _currentSprite = NULL;
+ }
+ stack->pushBool(true);
+ } else {
+ const char *filename = val->getString();
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ script->runtimeError("SetSprite method failed for file '%s'", filename);
+ stack->pushBool(false);
+ } else {
+ _sprite = spr;
+ if (setCurrent) {
+ _currentSprite = _sprite;
+ }
+ stack->pushBool(true);
+ }
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSprite
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetSprite") == 0) {
+ stack->correctParams(0);
+
+ if (!_sprite || !_sprite->getFilename()) {
+ stack->pushNULL();
+ } else {
+ stack->pushString(_sprite->getFilename());
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSpriteObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetSpriteObject") == 0) {
+ stack->correctParams(0);
+
+ if (!_sprite) {
+ stack->pushNULL();
+ } else {
+ stack->pushNative(_sprite, true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddTalkSprite
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "AddTalkSprite") == 0) {
+ stack->correctParams(2);
+
+ const char *filename = stack->pop()->getString();
+ bool ex = stack->pop()->getBool();
+
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ stack->pushBool(false);
+ script->runtimeError("AddTalkSprite method failed for file '%s'", filename);
+ } else {
+ if (ex) {
+ _talkSpritesEx.add(spr);
+ } else {
+ _talkSprites.add(spr);
+ }
+ stack->pushBool(true);
+ }
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveTalkSprite
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RemoveTalkSprite") == 0) {
+ stack->correctParams(2);
+
+ const char *filename = stack->pop()->getString();
+ bool ex = stack->pop()->getBool();
+
+ bool setCurrent = false;
+ bool setTemp2 = false;
+
+ if (ex) {
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ if (scumm_stricmp(_talkSpritesEx[i]->getFilename(), filename) == 0) {
+ if (_currentSprite == _talkSpritesEx[i]) {
+ setCurrent = true;
+ }
+ if (_tempSprite2 == _talkSpritesEx[i]) {
+ setTemp2 = true;
+ }
+ delete _talkSpritesEx[i];
+ _talkSpritesEx.remove_at(i);
+ break;
+ }
+ }
+ } else {
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ if (scumm_stricmp(_talkSprites[i]->getFilename(), filename) == 0) {
+ if (_currentSprite == _talkSprites[i]) {
+ setCurrent = true;
+ }
+ if (_tempSprite2 == _talkSprites[i]) {
+ setTemp2 = true;
+ }
+ delete _talkSprites[i];
+ _talkSprites.remove_at(i);
+ break;
+ }
+ }
+
+ }
+
+ stack->pushBool(true);
+ if (setCurrent) {
+ _currentSprite = _sprite;
+ }
+ if (setTemp2) {
+ _tempSprite2 = _sprite;
+ }
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetTalkSprite
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetTalkSprite") == 0) {
+ stack->correctParams(2);
+
+ const char *filename = stack->pop()->getString();
+ bool ex = stack->pop()->getBool();
+ bool setCurrent = false;
+ bool setTemp2 = false;
+
+ BaseSprite *spr = new BaseSprite(_gameRef, this);
+ if (!spr || DID_FAIL(spr->loadFile(filename))) {
+ stack->pushBool(false);
+ script->runtimeError("SetTalkSprite method failed for file '%s'", filename);
+ } else {
+
+ // delete current
+ if (ex) {
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ if (_talkSpritesEx[i] == _currentSprite) {
+ setCurrent = true;
+ }
+ if (_talkSpritesEx[i] == _tempSprite2) {
+ setTemp2 = true;
+ }
+ delete _talkSpritesEx[i];
+ }
+ _talkSpritesEx.clear();
+ } else {
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ if (_talkSprites[i] == _currentSprite) {
+ setCurrent = true;
+ }
+ if (_talkSprites[i] == _tempSprite2) {
+ setTemp2 = true;
+ }
+ delete _talkSprites[i];
+ }
+ _talkSprites.clear();
+ }
+
+ // set new
+ if (ex) {
+ _talkSpritesEx.add(spr);
+ } else {
+ _talkSprites.add(spr);
+ }
+ stack->pushBool(true);
+
+ if (setCurrent) {
+ _currentSprite = spr;
+ }
+ if (setTemp2) {
+ _tempSprite2 = spr;
+ }
+ }
+ return STATUS_OK;
+ } else {
+ return AdObject::scCallMethod(script, stack, thisStack, name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdTalkHolder::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("talk-holder");
+ return _scValue;
+ } else {
+ return AdObject::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkHolder::scSetProperty(const char *name, ScValue *value) {
+ /*
+ //////////////////////////////////////////////////////////////////////////
+ // Item
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Item")==0){
+ SetItem(value->getString());
+ return STATUS_OK;
+ }
+
+ else*/ return AdObject::scSetProperty(name, value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *AdTalkHolder::scToString() {
+ return "[talk-holder object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkHolder::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ for (uint32 i = 0; i < _talkSprites.size(); i++) {
+ if (_talkSprites[i]->getFilename()) {
+ buffer->putTextIndent(indent + 2, "TALK=\"%s\"\n", _talkSprites[i]->getFilename());
+ }
+ }
+
+ for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
+ if (_talkSpritesEx[i]->getFilename()) {
+ buffer->putTextIndent(indent + 2, "TALK_SPECIAL=\"%s\"\n", _talkSpritesEx[i]->getFilename());
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkHolder::persist(BasePersistenceManager *persistMgr) {
+ AdObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_sprite));
+ _talkSprites.persist(persistMgr);
+ _talkSpritesEx.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_holder.h b/engines/wintermute/ad/ad_talk_holder.h
index 906c469b32..ce10364b3d 100644
--- a/engines/wintermute/ad/ad_talk_holder.h
+++ b/engines/wintermute/ad/ad_talk_holder.h
@@ -1,57 +1,57 @@
-/* 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_ADTALKHOLDER_H
-#define WINTERMUTE_ADTALKHOLDER_H
-
-#include "engines/wintermute/ad/ad_object.h"
-
-namespace Wintermute {
-
-class AdTalkHolder : public AdObject {
-public:
- DECLARE_PERSISTENT(AdTalkHolder, AdObject)
- virtual BaseSprite *getTalkStance(const char *stance);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- BaseSprite *_sprite;
- BaseArray<BaseSprite *> _talkSprites;
- BaseArray<BaseSprite *> _talkSpritesEx;
- AdTalkHolder(BaseGame *inGame);
- virtual ~AdTalkHolder();
-
- // scripting interface
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *value);
- virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
- virtual const char *scToString();
-
-};
-
-} // 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_ADTALKHOLDER_H
+#define WINTERMUTE_ADTALKHOLDER_H
+
+#include "engines/wintermute/ad/ad_object.h"
+
+namespace Wintermute {
+
+class AdTalkHolder : public AdObject {
+public:
+ DECLARE_PERSISTENT(AdTalkHolder, AdObject)
+ virtual BaseSprite *getTalkStance(const char *stance);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ BaseSprite *_sprite;
+ BaseArray<BaseSprite *> _talkSprites;
+ BaseArray<BaseSprite *> _talkSpritesEx;
+ AdTalkHolder(BaseGame *inGame);
+ virtual ~AdTalkHolder();
+
+ // scripting interface
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+ virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
+ virtual const char *scToString();
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_talk_node.cpp b/engines/wintermute/ad/ad_talk_node.cpp
index 6d793f483c..b43a2b288e 100644
--- a/engines/wintermute/ad/ad_talk_node.cpp
+++ b/engines/wintermute/ad/ad_talk_node.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/ad/ad_talk_node.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/ad/ad_sprite_set.h"
-#include "engines/wintermute/utils/utils.h"
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdTalkNode, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkNode::AdTalkNode(BaseGame *inGame) : BaseClass(inGame) {
- _sprite = NULL;
- _spriteFilename = NULL;
- _spriteSet = NULL;
- _spriteSetFilename = NULL;
- _comment = NULL;
-
- _startTime = _endTime = 0;
- _playToEnd = false;
- _preCache = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdTalkNode::~AdTalkNode() {
- delete[] _spriteFilename;
- delete _sprite;
- delete[] _spriteSetFilename;
- delete _spriteSet;
- delete _comment;
- _spriteFilename = NULL;
- _sprite = NULL;
- _spriteSetFilename = NULL;
- _spriteSet = NULL;
- _comment = NULL;
-}
-
-
-
-TOKEN_DEF_START
-TOKEN_DEF(ACTION)
-TOKEN_DEF(SPRITESET_FILE)
-TOKEN_DEF(SPRITESET)
-TOKEN_DEF(SPRITE)
-TOKEN_DEF(START_TIME)
-TOKEN_DEF(END_TIME)
-TOKEN_DEF(COMMENT)
-TOKEN_DEF(PRECACHE)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(ACTION)
- TOKEN_TABLE(SPRITESET_FILE)
- TOKEN_TABLE(SPRITESET)
- TOKEN_TABLE(SPRITE)
- TOKEN_TABLE(START_TIME)
- TOKEN_TABLE(END_TIME)
- TOKEN_TABLE(COMMENT)
- TOKEN_TABLE(PRECACHE)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTION) {
- _gameRef->LOG(0, "'ACTION' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- _endTime = 0;
- _playToEnd = false;
- _preCache = false;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_SPRITE:
- BaseUtils::setString(&_spriteFilename, (char *)params);
- break;
-
- case TOKEN_SPRITESET_FILE:
- BaseUtils::setString(&_spriteSetFilename, (char *)params);
- break;
-
- case TOKEN_SPRITESET: {
- delete _spriteSet;
- _spriteSet = new AdSpriteSet(_gameRef);
- if (!_spriteSet || DID_FAIL(_spriteSet->loadBuffer(params, false))) {
- delete _spriteSet;
- _spriteSet = NULL;
- cmd = PARSERR_GENERIC;
- }
- }
- break;
-
- case TOKEN_START_TIME:
- parser.scanStr((char *)params, "%d", &_startTime);
- break;
-
- case TOKEN_END_TIME:
- parser.scanStr((char *)params, "%d", &_endTime);
- break;
-
- case TOKEN_PRECACHE:
- parser.scanStr((char *)params, "%b", &_preCache);
- break;
-
- case TOKEN_COMMENT:
- if (_gameRef->_editorMode) {
- BaseUtils::setString(&_comment, (char *)params);
- }
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in ACTION definition");
- return STATUS_FAILED;
- }
-
- if (cmd == PARSERR_GENERIC) {
- _gameRef->LOG(0, "Error loading ACTION definition");
- return STATUS_FAILED;
- }
-
- if (_endTime == 0) {
- _playToEnd = true;
- } else {
- _playToEnd = false;
- }
-
- if (_preCache && _spriteFilename) {
- delete _sprite;
- _sprite = new BaseSprite(_gameRef);
- if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
- return STATUS_FAILED;
- }
- }
-
- if (_preCache && _spriteSetFilename) {
- delete _spriteSet;
- _spriteSet = new AdSpriteSet(_gameRef);
- if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
- return STATUS_FAILED;
- }
- }
-
- return STATUS_OK;
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_comment));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_endTime));
- persistMgr->transfer(TMEMBER(_playToEnd));
- persistMgr->transfer(TMEMBER(_sprite));
- persistMgr->transfer(TMEMBER(_spriteFilename));
- persistMgr->transfer(TMEMBER(_spriteSet));
- persistMgr->transfer(TMEMBER(_spriteSetFilename));
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "ACTION {\n");
- if (_comment) {
- buffer->putTextIndent(indent + 2, "COMMENT=\"%s\"\n", _comment);
- }
- buffer->putTextIndent(indent + 2, "START_TIME=%d\n", _startTime);
- if (!_playToEnd) {
- buffer->putTextIndent(indent + 2, "END_TIME=%d\n", _endTime);
- }
- if (_spriteFilename) {
- buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _spriteFilename);
- }
- if (_spriteSetFilename) {
- buffer->putTextIndent(indent + 2, "SPRITESET_FILE=\"%s\"\n", _spriteSetFilename);
- } else if (_spriteSet) {
- _spriteSet->saveAsText(buffer, indent + 2);
- }
- if (_preCache) {
- buffer->putTextIndent(indent + 2, "PRECACHE=\"%s\"\n", _preCache ? "TRUE" : "FALSE");
- }
-
- BaseClass::saveAsText(buffer, indent + 2);
-
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::loadSprite() {
- if (_spriteFilename && !_sprite) {
- _sprite = new BaseSprite(_gameRef);
- if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
- delete _sprite;
- _sprite = NULL;
- return STATUS_FAILED;
- } else {
- return STATUS_OK;
- }
- } else if (_spriteSetFilename && !_spriteSet) {
- _spriteSet = new AdSpriteSet(_gameRef);
- if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
- delete _spriteSet;
- _spriteSet = NULL;
- return STATUS_FAILED;
- } else {
- return STATUS_OK;
- }
- } else {
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::isInTimeInterval(uint32 time, TDirection dir) {
- if (time >= _startTime) {
- if (_playToEnd) {
- if ((_spriteFilename && _sprite == NULL) || (_sprite && _sprite->_finished == false)) {
- return true;
- } else if ((_spriteSetFilename && _spriteSet == NULL) || (_spriteSet && _spriteSet->getSprite(dir) && _spriteSet->getSprite(dir)->_finished == false)) {
- return true;
- } else {
- return false;
- }
- } else {
- return _endTime >= time;
- }
- } else {
- return false;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseSprite *AdTalkNode::getSprite(TDirection dir) {
- loadSprite();
- if (_sprite) {
- return _sprite;
- } else if (_spriteSet) {
- return _spriteSet->getSprite(dir);
- } else {
- return NULL;
- }
-}
-
-} // 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/ad/ad_talk_node.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/ad/ad_sprite_set.h"
+#include "engines/wintermute/utils/utils.h"
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdTalkNode, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkNode::AdTalkNode(BaseGame *inGame) : BaseClass(inGame) {
+ _sprite = NULL;
+ _spriteFilename = NULL;
+ _spriteSet = NULL;
+ _spriteSetFilename = NULL;
+ _comment = NULL;
+
+ _startTime = _endTime = 0;
+ _playToEnd = false;
+ _preCache = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdTalkNode::~AdTalkNode() {
+ delete[] _spriteFilename;
+ delete _sprite;
+ delete[] _spriteSetFilename;
+ delete _spriteSet;
+ delete _comment;
+ _spriteFilename = NULL;
+ _sprite = NULL;
+ _spriteSetFilename = NULL;
+ _spriteSet = NULL;
+ _comment = NULL;
+}
+
+
+
+TOKEN_DEF_START
+TOKEN_DEF(ACTION)
+TOKEN_DEF(SPRITESET_FILE)
+TOKEN_DEF(SPRITESET)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(START_TIME)
+TOKEN_DEF(END_TIME)
+TOKEN_DEF(COMMENT)
+TOKEN_DEF(PRECACHE)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(ACTION)
+ TOKEN_TABLE(SPRITESET_FILE)
+ TOKEN_TABLE(SPRITESET)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(START_TIME)
+ TOKEN_TABLE(END_TIME)
+ TOKEN_TABLE(COMMENT)
+ TOKEN_TABLE(PRECACHE)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTION) {
+ _gameRef->LOG(0, "'ACTION' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ _endTime = 0;
+ _playToEnd = false;
+ _preCache = false;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_SPRITE:
+ BaseUtils::setString(&_spriteFilename, (char *)params);
+ break;
+
+ case TOKEN_SPRITESET_FILE:
+ BaseUtils::setString(&_spriteSetFilename, (char *)params);
+ break;
+
+ case TOKEN_SPRITESET: {
+ delete _spriteSet;
+ _spriteSet = new AdSpriteSet(_gameRef);
+ if (!_spriteSet || DID_FAIL(_spriteSet->loadBuffer(params, false))) {
+ delete _spriteSet;
+ _spriteSet = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ }
+ break;
+
+ case TOKEN_START_TIME:
+ parser.scanStr((char *)params, "%d", &_startTime);
+ break;
+
+ case TOKEN_END_TIME:
+ parser.scanStr((char *)params, "%d", &_endTime);
+ break;
+
+ case TOKEN_PRECACHE:
+ parser.scanStr((char *)params, "%b", &_preCache);
+ break;
+
+ case TOKEN_COMMENT:
+ if (_gameRef->_editorMode) {
+ BaseUtils::setString(&_comment, (char *)params);
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in ACTION definition");
+ return STATUS_FAILED;
+ }
+
+ if (cmd == PARSERR_GENERIC) {
+ _gameRef->LOG(0, "Error loading ACTION definition");
+ return STATUS_FAILED;
+ }
+
+ if (_endTime == 0) {
+ _playToEnd = true;
+ } else {
+ _playToEnd = false;
+ }
+
+ if (_preCache && _spriteFilename) {
+ delete _sprite;
+ _sprite = new BaseSprite(_gameRef);
+ if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
+ return STATUS_FAILED;
+ }
+ }
+
+ if (_preCache && _spriteSetFilename) {
+ delete _spriteSet;
+ _spriteSet = new AdSpriteSet(_gameRef);
+ if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
+ return STATUS_FAILED;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkNode::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_comment));
+ persistMgr->transfer(TMEMBER(_startTime));
+ persistMgr->transfer(TMEMBER(_endTime));
+ persistMgr->transfer(TMEMBER(_playToEnd));
+ persistMgr->transfer(TMEMBER(_sprite));
+ persistMgr->transfer(TMEMBER(_spriteFilename));
+ persistMgr->transfer(TMEMBER(_spriteSet));
+ persistMgr->transfer(TMEMBER(_spriteSetFilename));
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkNode::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "ACTION {\n");
+ if (_comment) {
+ buffer->putTextIndent(indent + 2, "COMMENT=\"%s\"\n", _comment);
+ }
+ buffer->putTextIndent(indent + 2, "START_TIME=%d\n", _startTime);
+ if (!_playToEnd) {
+ buffer->putTextIndent(indent + 2, "END_TIME=%d\n", _endTime);
+ }
+ if (_spriteFilename) {
+ buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _spriteFilename);
+ }
+ if (_spriteSetFilename) {
+ buffer->putTextIndent(indent + 2, "SPRITESET_FILE=\"%s\"\n", _spriteSetFilename);
+ } else if (_spriteSet) {
+ _spriteSet->saveAsText(buffer, indent + 2);
+ }
+ if (_preCache) {
+ buffer->putTextIndent(indent + 2, "PRECACHE=\"%s\"\n", _preCache ? "TRUE" : "FALSE");
+ }
+
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkNode::loadSprite() {
+ if (_spriteFilename && !_sprite) {
+ _sprite = new BaseSprite(_gameRef);
+ if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
+ delete _sprite;
+ _sprite = NULL;
+ return STATUS_FAILED;
+ } else {
+ return STATUS_OK;
+ }
+ } else if (_spriteSetFilename && !_spriteSet) {
+ _spriteSet = new AdSpriteSet(_gameRef);
+ if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
+ delete _spriteSet;
+ _spriteSet = NULL;
+ return STATUS_FAILED;
+ } else {
+ return STATUS_OK;
+ }
+ } else {
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdTalkNode::isInTimeInterval(uint32 time, TDirection dir) {
+ if (time >= _startTime) {
+ if (_playToEnd) {
+ if ((_spriteFilename && _sprite == NULL) || (_sprite && _sprite->_finished == false)) {
+ return true;
+ } else if ((_spriteSetFilename && _spriteSet == NULL) || (_spriteSet && _spriteSet->getSprite(dir) && _spriteSet->getSprite(dir)->_finished == false)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return _endTime >= time;
+ }
+ } else {
+ return false;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseSprite *AdTalkNode::getSprite(TDirection dir) {
+ loadSprite();
+ if (_sprite) {
+ return _sprite;
+ } else if (_spriteSet) {
+ return _spriteSet->getSprite(dir);
+ } else {
+ return NULL;
+ }
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_node.h b/engines/wintermute/ad/ad_talk_node.h
index 863f6d0a3b..7dfd861f85 100644
--- a/engines/wintermute/ad/ad_talk_node.h
+++ b/engines/wintermute/ad/ad_talk_node.h
@@ -1,63 +1,63 @@
-/* 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_ADTALKNODE_H
-#define WINTERMUTE_ADTALKNODE_H
-
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/base/base.h"
-
-namespace Wintermute {
-class AdSpriteSet;
-class BaseSprite;
-class AdTalkNode : public BaseClass {
-public:
- char *_spriteSetFilename;
- AdSpriteSet *_spriteSet;
- BaseSprite *getSprite(TDirection dir);
- bool isInTimeInterval(uint32 time, TDirection dir);
- bool loadSprite();
- DECLARE_PERSISTENT(AdTalkNode, BaseClass)
-
- AdTalkNode(BaseGame *inGame);
- virtual ~AdTalkNode();
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
- char *_spriteFilename;
- BaseSprite *_sprite;
- uint32 _startTime;
- uint32 _endTime;
- bool _playToEnd;
- bool _preCache;
- char *_comment;
-
-};
-
-} // 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_ADTALKNODE_H
+#define WINTERMUTE_ADTALKNODE_H
+
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/base/base.h"
+
+namespace Wintermute {
+class AdSpriteSet;
+class BaseSprite;
+class AdTalkNode : public BaseClass {
+public:
+ char *_spriteSetFilename;
+ AdSpriteSet *_spriteSet;
+ BaseSprite *getSprite(TDirection dir);
+ bool isInTimeInterval(uint32 time, TDirection dir);
+ bool loadSprite();
+ DECLARE_PERSISTENT(AdTalkNode, BaseClass)
+
+ AdTalkNode(BaseGame *inGame);
+ virtual ~AdTalkNode();
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
+ char *_spriteFilename;
+ BaseSprite *_sprite;
+ uint32 _startTime;
+ uint32 _endTime;
+ bool _playToEnd;
+ bool _preCache;
+ char *_comment;
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_types.h b/engines/wintermute/ad/ad_types.h
index 8db20bfc02..ae5882f4ee 100644
--- a/engines/wintermute/ad/ad_types.h
+++ b/engines/wintermute/ad/ad_types.h
@@ -1,107 +1,107 @@
-/* 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_ADTYPES_H
-#define WINTERMUTE_ADTYPES_H
-
-namespace Wintermute {
-
-typedef enum {
- GAME_NORMAL,
- GAME_WAITING_RESPONSE
-} TGameStateEx;
-
-typedef enum {
- OBJECT_ENTITY,
- OBJECT_REGION,
- OBJECT_ACTOR,
- OBJECT_NONE
-} TObjectType;
-
-typedef enum {
- ENTITY_NORMAL,
- ENTITY_SOUND
-} TEntityType;
-
-typedef enum {
- STATE_NONE,
- STATE_IDLE,
- STATE_PLAYING_ANIM,
- STATE_READY,
- STATE_FOLLOWING_PATH,
- STATE_SEARCHING_PATH,
- STATE_WAITING_PATH,
- STATE_TURNING_LEFT,
- STATE_TURNING_RIGHT,
- STATE_TURNING,
- STATE_TALKING,
- STATE_DIRECT_CONTROL,
- STATE_PLAYING_ANIM_SET
-} TObjectState;
-
-typedef enum {
- DIRECT_WALK_NONE,
- DIRECT_WALK_FW,
- DIRECT_WALK_BK
-} TDirectWalkMode;
-
-typedef enum {
- DIRECT_TURN_NONE,
- DIRECT_TURN_CW,
- DIRECT_TURN_CCW
-} TDirectTurnMode;
-
-typedef enum {
- RESPONSE_TEXT,
- RESPONSE_ICON
-} TResponseStyle;
-
-typedef enum {
- RESPONSE_ALWAYS,
- RESPONSE_ONCE,
- RESPONSE_ONCE_GAME
-} TResponseType;
-
-
-typedef enum {
- TALK_SKIP_LEFT = 0,
- TALK_SKIP_RIGHT = 1,
- TALK_SKIP_BOTH = 2,
- TALK_SKIP_NONE = 3
-} TTalkSkipButton;
-
-typedef enum {
- GEOM_WAYPOINT,
- GEOM_WALKPLANE,
- GEOM_BLOCKED,
- GEOM_GENERIC
-} TGeomNodeType;
-
-} // 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_ADTYPES_H
+#define WINTERMUTE_ADTYPES_H
+
+namespace Wintermute {
+
+typedef enum {
+ GAME_NORMAL,
+ GAME_WAITING_RESPONSE
+} TGameStateEx;
+
+typedef enum {
+ OBJECT_ENTITY,
+ OBJECT_REGION,
+ OBJECT_ACTOR,
+ OBJECT_NONE
+} TObjectType;
+
+typedef enum {
+ ENTITY_NORMAL,
+ ENTITY_SOUND
+} TEntityType;
+
+typedef enum {
+ STATE_NONE,
+ STATE_IDLE,
+ STATE_PLAYING_ANIM,
+ STATE_READY,
+ STATE_FOLLOWING_PATH,
+ STATE_SEARCHING_PATH,
+ STATE_WAITING_PATH,
+ STATE_TURNING_LEFT,
+ STATE_TURNING_RIGHT,
+ STATE_TURNING,
+ STATE_TALKING,
+ STATE_DIRECT_CONTROL,
+ STATE_PLAYING_ANIM_SET
+} TObjectState;
+
+typedef enum {
+ DIRECT_WALK_NONE,
+ DIRECT_WALK_FW,
+ DIRECT_WALK_BK
+} TDirectWalkMode;
+
+typedef enum {
+ DIRECT_TURN_NONE,
+ DIRECT_TURN_CW,
+ DIRECT_TURN_CCW
+} TDirectTurnMode;
+
+typedef enum {
+ RESPONSE_TEXT,
+ RESPONSE_ICON
+} TResponseStyle;
+
+typedef enum {
+ RESPONSE_ALWAYS,
+ RESPONSE_ONCE,
+ RESPONSE_ONCE_GAME
+} TResponseType;
+
+
+typedef enum {
+ TALK_SKIP_LEFT = 0,
+ TALK_SKIP_RIGHT = 1,
+ TALK_SKIP_BOTH = 2,
+ TALK_SKIP_NONE = 3
+} TTalkSkipButton;
+
+typedef enum {
+ GEOM_WAYPOINT,
+ GEOM_WALKPLANE,
+ GEOM_BLOCKED,
+ GEOM_GENERIC
+} TGeomNodeType;
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/ad/ad_waypoint_group.cpp b/engines/wintermute/ad/ad_waypoint_group.cpp
index 8da62c9115..984ed75aeb 100644
--- a/engines/wintermute/ad/ad_waypoint_group.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group.cpp
@@ -1,270 +1,270 @@
-/* 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/ad/ad_waypoint_group.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_dynamic_buffer.h"
-#include "engines/wintermute/base/scriptables/script_value.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_region.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include <limits.h>
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(AdWaypointGroup, false)
-
-//////////////////////////////////////////////////////////////////////////
-AdWaypointGroup::AdWaypointGroup(BaseGame *inGame) : BaseObject(inGame) {
- _active = true;
- _editorSelectedPoint = -1;
- _lastMimicScale = -1;
- _lastMimicX = _lastMimicY = INT_MIN;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-AdWaypointGroup::~AdWaypointGroup() {
- cleanup();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void AdWaypointGroup::cleanup() {
- for (uint32 i = 0; i < _points.size(); i++) {
- delete _points[i];
- }
- _points.clear();
- _editorSelectedPoint = -1;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "AdWaypointGroup::LoadFile failed for file '%s'", filename);
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename);
-
- if (DID_FAIL(ret = loadBuffer(buffer, true))) {
- _gameRef->LOG(0, "Error parsing WAYPOINTS file '%s'", filename);
- }
-
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(WAYPOINTS)
-TOKEN_DEF(TEMPLATE)
-TOKEN_DEF(NAME)
-TOKEN_DEF(POINT)
-TOKEN_DEF(EDITOR_SELECTED_POINT)
-TOKEN_DEF(EDITOR_SELECTED)
-TOKEN_DEF(PROPERTY)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(WAYPOINTS)
- TOKEN_TABLE(TEMPLATE)
- TOKEN_TABLE(NAME)
- TOKEN_TABLE(POINT)
- TOKEN_TABLE(EDITOR_SELECTED_POINT)
- TOKEN_TABLE(EDITOR_SELECTED)
- TOKEN_TABLE(PROPERTY)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE_END
-
- byte *params;
- int cmd;
- BaseParser parser;
-
- if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WAYPOINTS) {
- _gameRef->LOG(0, "'WAYPOINTS' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = params;
- }
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
- cmd = PARSERR_GENERIC;
- }
- break;
-
- case TOKEN_NAME:
- setName((char *)params);
- break;
-
- case TOKEN_POINT: {
- int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
- _points.add(new BasePoint(x, y));
- }
- break;
-
- case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
- break;
-
- case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
- break;
-
- case TOKEN_PROPERTY:
- parseProperty(params, false);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty(params, false);
- break;
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in WAYPOINTS definition");
- return STATUS_FAILED;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::saveAsText(BaseDynamicBuffer *buffer, int indent) {
- buffer->putTextIndent(indent, "WAYPOINTS {\n");
- buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
- buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
- buffer->putTextIndent(indent + 2, "EDITOR_SELECTED_POINT=%d\n", _editorSelectedPoint);
-
- if (_scProp) {
- _scProp->saveAsText(buffer, indent + 2);
- }
- BaseClass::saveAsText(buffer, indent + 2);
-
- for (uint32 i = 0; i < _points.size(); i++) {
- buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
- }
-
- buffer->putTextIndent(indent, "}\n");
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
- persistMgr->transfer(TMEMBER(_lastMimicX));
- persistMgr->transfer(TMEMBER(_lastMimicY));
- _points.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-ScValue *AdWaypointGroup::scGetProperty(const char *name) {
- _scValue->setNULL();
-
- //////////////////////////////////////////////////////////////////////////
- // Type
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Type") == 0) {
- _scValue->setString("waypoint-group");
- return _scValue;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- else if (strcmp(name, "Active") == 0) {
- _scValue->setBool(_active);
- return _scValue;
- } else {
- return BaseObject::scGetProperty(name);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::scSetProperty(const char *name, ScValue *value) {
- //////////////////////////////////////////////////////////////////////////
- // Active
- //////////////////////////////////////////////////////////////////////////
- if (strcmp(name, "Active") == 0) {
- _active = value->getBool();
- return STATUS_OK;
- }
-
- else {
- return BaseObject::scSetProperty(name, value);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::mimic(AdWaypointGroup *wpt, float scale, int argX, int argY) {
- if (scale == _lastMimicScale && argX == _lastMimicX && argY == _lastMimicY) {
- return STATUS_OK;
- }
-
- cleanup();
-
- for (uint32 i = 0; i < wpt->_points.size(); i++) {
- int x = (int)((float)wpt->_points[i]->x * scale / 100.0f);
- int y = (int)((float)wpt->_points[i]->y * scale / 100.0f);
-
- _points.add(new BasePoint(x + argX, y + argY));
- }
-
- _lastMimicScale = scale;
- _lastMimicX = argX;
- _lastMimicY = argY;
-
- 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/ad/ad_waypoint_group.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_dynamic_buffer.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_region.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include <limits.h>
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(AdWaypointGroup, false)
+
+//////////////////////////////////////////////////////////////////////////
+AdWaypointGroup::AdWaypointGroup(BaseGame *inGame) : BaseObject(inGame) {
+ _active = true;
+ _editorSelectedPoint = -1;
+ _lastMimicScale = -1;
+ _lastMimicX = _lastMimicY = INT_MIN;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AdWaypointGroup::~AdWaypointGroup() {
+ cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void AdWaypointGroup::cleanup() {
+ for (uint32 i = 0; i < _points.size(); i++) {
+ delete _points[i];
+ }
+ _points.clear();
+ _editorSelectedPoint = -1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::loadFile(const char *filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "AdWaypointGroup::LoadFile failed for file '%s'", filename);
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename);
+
+ if (DID_FAIL(ret = loadBuffer(buffer, true))) {
+ _gameRef->LOG(0, "Error parsing WAYPOINTS file '%s'", filename);
+ }
+
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(WAYPOINTS)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(POINT)
+TOKEN_DEF(EDITOR_SELECTED_POINT)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(WAYPOINTS)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(POINT)
+ TOKEN_TABLE(EDITOR_SELECTED_POINT)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ BaseParser parser;
+
+ if (complete) {
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WAYPOINTS) {
+ _gameRef->LOG(0, "'WAYPOINTS' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = params;
+ }
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (DID_FAIL(loadFile((char *)params))) {
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NAME:
+ setName((char *)params);
+ break;
+
+ case TOKEN_POINT: {
+ int x, y;
+ parser.scanStr((char *)params, "%d,%d", &x, &y);
+ _points.add(new BasePoint(x, y));
+ }
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.scanStr((char *)params, "%b", &_editorSelected);
+ break;
+
+ case TOKEN_EDITOR_SELECTED_POINT:
+ parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ break;
+
+ case TOKEN_PROPERTY:
+ parseProperty(params, false);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in WAYPOINTS definition");
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::saveAsText(BaseDynamicBuffer *buffer, int indent) {
+ buffer->putTextIndent(indent, "WAYPOINTS {\n");
+ buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
+ buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
+ buffer->putTextIndent(indent + 2, "EDITOR_SELECTED_POINT=%d\n", _editorSelectedPoint);
+
+ if (_scProp) {
+ _scProp->saveAsText(buffer, indent + 2);
+ }
+ BaseClass::saveAsText(buffer, indent + 2);
+
+ for (uint32 i = 0; i < _points.size(); i++) {
+ buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
+ }
+
+ buffer->putTextIndent(indent, "}\n");
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transfer(TMEMBER(_editorSelectedPoint));
+ persistMgr->transfer(TMEMBER(_lastMimicScale));
+ persistMgr->transfer(TMEMBER(_lastMimicX));
+ persistMgr->transfer(TMEMBER(_lastMimicY));
+ _points.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+ScValue *AdWaypointGroup::scGetProperty(const char *name) {
+ _scValue->setNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ _scValue->setString("waypoint-group");
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Active") == 0) {
+ _scValue->setBool(_active);
+ return _scValue;
+ } else {
+ return BaseObject::scGetProperty(name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::scSetProperty(const char *name, ScValue *value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Active") == 0) {
+ _active = value->getBool();
+ return STATUS_OK;
+ }
+
+ else {
+ return BaseObject::scSetProperty(name, value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool AdWaypointGroup::mimic(AdWaypointGroup *wpt, float scale, int argX, int argY) {
+ if (scale == _lastMimicScale && argX == _lastMimicX && argY == _lastMimicY) {
+ return STATUS_OK;
+ }
+
+ cleanup();
+
+ for (uint32 i = 0; i < wpt->_points.size(); i++) {
+ int x = (int)((float)wpt->_points[i]->x * scale / 100.0f);
+ int y = (int)((float)wpt->_points[i]->y * scale / 100.0f);
+
+ _points.add(new BasePoint(x + argX, y + argY));
+ }
+
+ _lastMimicScale = scale;
+ _lastMimicX = argX;
+ _lastMimicY = argY;
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_waypoint_group.h b/engines/wintermute/ad/ad_waypoint_group.h
index a83c942652..5cf6da1d1a 100644
--- a/engines/wintermute/ad/ad_waypoint_group.h
+++ b/engines/wintermute/ad/ad_waypoint_group.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_ADWAYPOINTGROUP_H
-#define WINTERMUTE_ADWAYPOINTGROUP_H
-
-#include "engines/wintermute/base/base_object.h"
-
-namespace Wintermute {
-class BasePoint;
-class AdWaypointGroup : public BaseObject {
-public:
- float _lastMimicScale;
- int _lastMimicX;
- int _lastMimicY;
- void cleanup();
- bool mimic(AdWaypointGroup *wpt, float scale = 100.0f, int x = 0, int y = 0);
- DECLARE_PERSISTENT(AdWaypointGroup, BaseObject)
- virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
- bool _active;
- AdWaypointGroup(BaseGame *inGame);
- bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- virtual ~AdWaypointGroup();
- BaseArray<BasePoint *> _points;
- int _editorSelectedPoint;
- virtual ScValue *scGetProperty(const char *name);
- virtual bool scSetProperty(const char *name, ScValue *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_ADWAYPOINTGROUP_H
+#define WINTERMUTE_ADWAYPOINTGROUP_H
+
+#include "engines/wintermute/base/base_object.h"
+
+namespace Wintermute {
+class BasePoint;
+class AdWaypointGroup : public BaseObject {
+public:
+ float _lastMimicScale;
+ int _lastMimicX;
+ int _lastMimicY;
+ void cleanup();
+ bool mimic(AdWaypointGroup *wpt, float scale = 100.0f, int x = 0, int y = 0);
+ DECLARE_PERSISTENT(AdWaypointGroup, BaseObject)
+ virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
+ bool _active;
+ AdWaypointGroup(BaseGame *inGame);
+ bool loadFile(const char *filename);
+ bool loadBuffer(byte *buffer, bool complete = true);
+ virtual ~AdWaypointGroup();
+ BaseArray<BasePoint *> _points;
+ int _editorSelectedPoint;
+ virtual ScValue *scGetProperty(const char *name);
+ virtual bool scSetProperty(const char *name, ScValue *value);
+};
+
+} // end of namespace Wintermute
+
+#endif