2009-08-04 13:27:04 +00:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2010-10-06 00:44:08 +00:00
|
|
|
#include "asylum/views/scene.h"
|
2010-11-03 04:27:47 +00:00
|
|
|
|
2010-11-04 22:19:02 +00:00
|
|
|
#include "asylum/resources/actionlist.h"
|
2010-10-06 00:44:08 +00:00
|
|
|
#include "asylum/resources/actor.h"
|
2010-11-03 04:29:56 +00:00
|
|
|
#include "asylum/resources/encounters.h"
|
2010-11-05 04:14:46 +00:00
|
|
|
#include "asylum/resources/object.h"
|
|
|
|
#include "asylum/resources/polygons.h"
|
2010-11-04 22:19:02 +00:00
|
|
|
#include "asylum/resources/special.h"
|
2010-11-05 04:14:46 +00:00
|
|
|
#include "asylum/resources/worldstats.h"
|
2010-11-03 04:27:47 +00:00
|
|
|
|
2010-10-06 00:44:08 +00:00
|
|
|
#include "asylum/system/config.h"
|
2010-11-05 04:14:46 +00:00
|
|
|
#include "asylum/system/cursor.h"
|
|
|
|
#include "asylum/system/graphics.h"
|
|
|
|
#include "asylum/system/screen.h"
|
|
|
|
#include "asylum/system/speech.h"
|
|
|
|
#include "asylum/system/text.h"
|
|
|
|
|
2010-11-08 21:08:50 +00:00
|
|
|
#include "asylum/views/scenetitle.h"
|
|
|
|
|
2010-11-05 04:14:46 +00:00
|
|
|
#include "asylum/asylum.h"
|
|
|
|
#include "asylum/respack.h"
|
2010-11-03 04:27:47 +00:00
|
|
|
#include "asylum/staticres.h"
|
|
|
|
|
2010-11-05 04:14:46 +00:00
|
|
|
#include "common/file.h"
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
namespace Asylum {
|
|
|
|
|
|
|
|
#define SCREEN_EDGES 40
|
|
|
|
#define SCROLL_STEP 10
|
|
|
|
|
|
|
|
int g_debugPolygons;
|
2010-11-04 22:14:44 +00:00
|
|
|
int g_debugObjects;
|
2009-12-05 20:51:46 +00:00
|
|
|
int g_debugScrolling;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2010-11-16 14:24:27 +00:00
|
|
|
Scene::Scene(AsylumEngine *engine): _vm(engine), _ev(NULL),
|
2010-11-09 00:58:34 +00:00
|
|
|
_actions(NULL), _special(NULL), _speech(NULL), _title(NULL), _polygons(NULL), _ws(NULL) {
|
|
|
|
|
|
|
|
// Initialize data
|
|
|
|
_packId = kResourcePackInvalid;
|
|
|
|
_playerActorIdx = 0;
|
|
|
|
_titleLoaded = false;
|
|
|
|
_walking = false;
|
|
|
|
_leftClick = false;
|
|
|
|
_rightButton = false;
|
|
|
|
_isActive = false;
|
2010-11-27 00:03:04 +00:00
|
|
|
_globalDirection = kDirectionN;
|
2010-11-09 00:58:34 +00:00
|
|
|
|
|
|
|
// Graphics
|
|
|
|
_bgResource = NULL;
|
|
|
|
_background = NULL;
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Scene::~Scene() {
|
2010-11-09 00:58:34 +00:00
|
|
|
// Unload the associated resources
|
|
|
|
getResource()->unload(_packId);
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
delete _actions;
|
2010-11-16 14:24:27 +00:00
|
|
|
//delete _blowUp;
|
|
|
|
delete _special;
|
|
|
|
delete _speech;
|
|
|
|
delete _title;
|
|
|
|
delete _polygons;
|
|
|
|
delete _ws;
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
delete _bgResource;
|
2010-11-16 14:24:27 +00:00
|
|
|
_background = NULL;
|
2010-11-08 21:09:13 +00:00
|
|
|
|
2010-11-16 14:24:27 +00:00
|
|
|
// Zero passed pointers
|
|
|
|
_vm = NULL;
|
|
|
|
_ev = NULL;
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::enter(ResourcePackId packId) {
|
|
|
|
_vm->setGameFlag(kGameFlagScriptProcessing);
|
|
|
|
|
|
|
|
getCursor()->hide();
|
|
|
|
|
|
|
|
_playerActorIdx = 0;
|
|
|
|
|
|
|
|
// Load the scene data
|
|
|
|
load(packId);
|
|
|
|
|
|
|
|
// Set wheel indices
|
2010-11-09 03:04:33 +00:00
|
|
|
_ws->setWheelObjects();
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
// Adjust object priority
|
|
|
|
if (_ws->objects.size() > 0) {
|
|
|
|
int32 priority = 4091;
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < _ws->objects.size(); i++) {
|
|
|
|
Object *object = _ws->objects[i];
|
|
|
|
object->setPriority(priority);
|
|
|
|
object->flags &= ~kObjectFlagC000;
|
|
|
|
priority -= 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the cursor to magnifying glass
|
|
|
|
getCursor()->set(_ws->curMagnifyingGlass);
|
|
|
|
getCursor()->show();
|
|
|
|
|
|
|
|
// Clear the graphic queue
|
|
|
|
getScreen()->clearGraphicsInQueue();
|
|
|
|
|
|
|
|
_ws->sceneRectIdx = 0;
|
|
|
|
_ws->motionStatus = 1;
|
|
|
|
|
|
|
|
// Update current player bounding rectangle
|
|
|
|
Actor *player = getActor();
|
|
|
|
Common::Rect *boundingRect = player->getBoundingRect();
|
2010-11-16 14:24:57 +00:00
|
|
|
boundingRect->bottom = (int16)player->getPoint2()->y;
|
|
|
|
boundingRect->right = (int16)(player->getPoint2()->x * 2);
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
// Adjust scene bounding rect
|
|
|
|
_ws->boundingRect = Common::Rect(195, 115, 445 - boundingRect->right, 345 - boundingRect->bottom);
|
|
|
|
|
|
|
|
// Hide actor
|
|
|
|
player->hide();
|
2010-11-16 14:24:46 +00:00
|
|
|
player->enable();
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
// Update current player coordinates
|
2010-11-16 14:24:57 +00:00
|
|
|
player->getPoint1()->x -= player->getPoint2()->x;
|
|
|
|
player->getPoint1()->y -= player->getPoint2()->y;
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
// Update all other actors
|
|
|
|
if (_ws->actors.size() > 1) {
|
|
|
|
for (uint32 i = 1; i < _ws->actors.size(); i++) {
|
|
|
|
Actor *actor = _ws->actors[i];
|
|
|
|
|
|
|
|
actor->hide();
|
2010-11-27 00:03:04 +00:00
|
|
|
actor->setDirection(kDirectionNO);
|
2010-11-16 14:24:46 +00:00
|
|
|
actor->enable();
|
2010-11-08 21:09:13 +00:00
|
|
|
|
2010-11-16 14:24:57 +00:00
|
|
|
actor->getPoint1()->x -= actor->getPoint2()->x;
|
|
|
|
actor->getPoint1()->y -= actor->getPoint2()->y;
|
2010-11-08 21:09:13 +00:00
|
|
|
|
2010-11-16 14:24:57 +00:00
|
|
|
actor->getBoundingRect()->bottom = (int16)actor->getPoint2()->y;
|
|
|
|
actor->getBoundingRect()->right = (int16)(2 * actor->getPoint2()->x);
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Queue scene script
|
|
|
|
if (_ws->scriptIndex)
|
|
|
|
_actions->queueScript(_ws->scriptIndex, 0);
|
|
|
|
|
|
|
|
// Clear the graphic queue (FIXME: not sure why we need to do this again)
|
|
|
|
getScreen()->clearGraphicsInQueue();
|
|
|
|
|
2010-11-28 01:27:07 +00:00
|
|
|
// Load transparency tables
|
|
|
|
getScreen()->setupTransTables(3, _ws->cellShadeMask1, _ws->cellShadeMask2, _ws->cellShadeMask3);
|
|
|
|
getScreen()->selectTransTable(1);
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
// Setup font
|
|
|
|
getText()->loadFont(_ws->font1);
|
|
|
|
|
|
|
|
// Play scene intro dialog
|
|
|
|
playIntroSpeech();
|
|
|
|
|
|
|
|
// Set actor type
|
|
|
|
_ws->actorType = actorType[_ws->chapter];
|
|
|
|
|
|
|
|
// Play intro music
|
|
|
|
ResourceId musicId = kResourceNone;
|
2010-11-10 12:08:38 +00:00
|
|
|
if (_ws->musicCurrentResourceIndex != kMusicStopped && _ws->chapter != kChapter1)
|
2010-11-08 21:09:13 +00:00
|
|
|
musicId = MAKE_RESOURCE(kResourcePackMusic, _ws->musicCurrentResourceIndex);
|
|
|
|
|
|
|
|
getSound()->playMusic(musicId);
|
|
|
|
|
|
|
|
// Update global values
|
2010-11-16 14:24:46 +00:00
|
|
|
_vm->lastScreenUpdate = 1;
|
|
|
|
getSharedData()->setFlag(kFlagScene1, true);
|
2010-11-08 21:09:13 +00:00
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
player->setLastScreenUpdate(_vm->screenUpdateCount);
|
|
|
|
player->enable();
|
2010-11-08 21:09:13 +00:00
|
|
|
|
|
|
|
if (_ws->chapter == kChapter9) {
|
|
|
|
changePlayer(1);
|
2010-11-27 00:02:55 +00:00
|
|
|
_ws->nextPlayer = kActorInvalid;
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
|
2010-11-10 20:45:19 +00:00
|
|
|
activate();
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::load(ResourcePackId packId) {
|
2010-11-09 00:58:40 +00:00
|
|
|
// Setup resource manager
|
2010-11-08 21:08:56 +00:00
|
|
|
_packId = packId;
|
2010-11-09 00:58:40 +00:00
|
|
|
getResource()->setMusicPackId(packId);
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
char filename[10];
|
2010-11-08 21:08:56 +00:00
|
|
|
sprintf(filename, SCENE_FILE_MASK, _packId);
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
char sceneTag[6];
|
|
|
|
Common::File* fd = new Common::File;
|
2009-09-09 22:50:34 +00:00
|
|
|
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!Common::File::exists(filename))
|
2009-09-19 12:24:53 +00:00
|
|
|
error("Scene file doesn't exist %s", filename);
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
fd->open(filename);
|
2009-08-06 00:04:09 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
if (!fd->isOpen())
|
|
|
|
error("Failed to load scene file %s", filename);
|
|
|
|
|
|
|
|
fd->read(sceneTag, 6);
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
if (Common::String(sceneTag, 6) != "DFISCN")
|
2009-09-19 12:24:53 +00:00
|
|
|
error("The file isn't recognized as scene %s", filename);
|
|
|
|
|
2009-09-19 17:43:35 +00:00
|
|
|
_ws = new WorldStats(fd, this);
|
2009-09-19 12:24:53 +00:00
|
|
|
_polygons = new Polygons(fd);
|
2010-11-05 00:35:51 +00:00
|
|
|
_actions = new ActionList(_vm);
|
|
|
|
_actions->load(fd);
|
2009-09-19 12:24:53 +00:00
|
|
|
|
|
|
|
fd->close();
|
|
|
|
delete fd;
|
|
|
|
|
2010-11-08 21:09:02 +00:00
|
|
|
_speech = new Speech(_vm);
|
2009-09-19 12:24:53 +00:00
|
|
|
|
2009-09-25 01:05:23 +00:00
|
|
|
// TODO
|
|
|
|
// This will have to be re-initialized elsewhere due to
|
|
|
|
// the title screen overwriting the font
|
2010-11-08 21:09:02 +00:00
|
|
|
_vm->text()->loadFont(_ws->font1);
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2010-11-08 21:09:02 +00:00
|
|
|
_bgResource = new GraphicResource(_vm, _ws->backgroundImage);
|
2010-01-13 11:53:51 +00:00
|
|
|
//_blowUp = 0;
|
2010-11-16 14:24:27 +00:00
|
|
|
_background = NULL;
|
2009-08-19 22:19:25 +00:00
|
|
|
_leftClick = false;
|
|
|
|
_rightButton = false;
|
|
|
|
_isActive = false;
|
2010-11-16 14:24:46 +00:00
|
|
|
//_skipDrawScene = false;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
g_debugPolygons = 0;
|
2010-11-04 22:14:44 +00:00
|
|
|
g_debugObjects = 0;
|
2009-12-05 20:51:46 +00:00
|
|
|
g_debugScrolling = 0;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
//_globalX = _globalY = 0;
|
2010-11-03 04:27:55 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
// TODO figure out what field_120 is used for
|
|
|
|
_ws->field_120 = -1;
|
|
|
|
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 a = 0; a < _ws->actors.size(); a++)
|
2010-11-03 04:29:52 +00:00
|
|
|
_ws->actors[a]->setLastScreenUpdate(_vm->getTick());
|
2009-11-24 11:25:30 +00:00
|
|
|
|
|
|
|
// TODO: init action list
|
|
|
|
|
2010-11-08 21:08:50 +00:00
|
|
|
_title = new SceneTitle(_vm);
|
2009-11-24 11:25:30 +00:00
|
|
|
_titleLoaded = false;
|
2010-11-04 22:19:02 +00:00
|
|
|
|
|
|
|
_special = new Special(_vm);
|
2009-11-24 11:25:30 +00:00
|
|
|
}
|
|
|
|
|
2010-11-04 22:19:02 +00:00
|
|
|
Actor* Scene::getActor(ActorIndex index) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::getActor] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-04 22:19:02 +00:00
|
|
|
ActorIndex computedIndex = (index != -1) ? index : _playerActorIdx;
|
|
|
|
|
2010-11-16 14:24:27 +00:00
|
|
|
if (computedIndex < 0 || computedIndex >= (int16)_ws->actors.size())
|
2010-11-04 22:19:02 +00:00
|
|
|
error("[Scene::getActor] Invalid actor index: %d ([0-%d] allowed)", computedIndex, _ws->actors.size() - 1);
|
|
|
|
|
|
|
|
return _ws->actors[computedIndex];
|
2009-11-24 11:00:45 +00:00
|
|
|
}
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
void Scene::setScenePosition(int x, int y) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::setScenePosition] WorldStats not initialized properly!");
|
|
|
|
|
|
|
|
if (!_bgResource)
|
|
|
|
error("[Scene::setScenePosition] Scene resources not initialized properly!");
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
GraphicFrame *bg = _bgResource->getFrame(0);
|
2009-09-18 23:44:54 +00:00
|
|
|
//_startX = x;
|
|
|
|
//_startY = y;
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
int32 *targetX = &_ws->coordinates[0];
|
|
|
|
int32 *targetY = &_ws->coordinates[1];
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
*targetX = x;
|
|
|
|
*targetY = y;
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetX < 0)
|
|
|
|
*targetX = 0;
|
|
|
|
if (*targetX > (bg->surface.w - 640))
|
|
|
|
*targetX = bg->surface.w - 640;
|
|
|
|
|
|
|
|
|
|
|
|
if (*targetY < 0)
|
|
|
|
*targetY = 0;
|
|
|
|
if (*targetY > (bg->surface.h - 480))
|
|
|
|
*targetY = bg->surface.h - 480;
|
2009-08-04 13:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::handleEvent(Common::Event *event, bool doUpdate) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::handleEvent] WorldStats not initialized properly!");
|
|
|
|
|
|
|
|
if (!_title)
|
|
|
|
error("[Scene::handleEvent] Scene title not initialized properly!");
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
_ev = event;
|
|
|
|
|
|
|
|
switch (_ev->type) {
|
|
|
|
|
|
|
|
case Common::EVENT_MOUSEMOVE:
|
2010-12-01 19:21:21 +00:00
|
|
|
//if (getCursor())
|
|
|
|
//getCursor()->move(_ev->mouse.x, _ev->mouse.y);
|
2009-08-04 13:27:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_LBUTTONUP:
|
2010-11-03 04:28:35 +00:00
|
|
|
//if (_actions->doesAllowInput())
|
2009-08-04 13:27:04 +00:00
|
|
|
_leftClick = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_RBUTTONUP:
|
2010-11-03 04:28:35 +00:00
|
|
|
//if (_actions->doesAllowInput()) {
|
2009-08-04 13:27:04 +00:00
|
|
|
// TODO This isn't always going to be the magnifying glass
|
|
|
|
// Should check the current pointer region to identify the type
|
|
|
|
// of cursor to use
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(_ws->curMagnifyingGlass);
|
2009-08-04 13:27:04 +00:00
|
|
|
_rightButton = false;
|
2010-11-03 04:28:35 +00:00
|
|
|
//}
|
2009-08-04 13:27:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_RBUTTONDOWN:
|
2010-11-03 04:28:35 +00:00
|
|
|
//if (_actions->doesAllowInput())
|
2009-08-04 13:27:04 +00:00
|
|
|
_rightButton = true;
|
|
|
|
break;
|
2009-12-06 17:06:14 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2010-11-03 04:27:41 +00:00
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
}
|
|
|
|
|
2009-12-29 21:38:00 +00:00
|
|
|
// FIXME just updating because a left click event
|
|
|
|
// is caught causes animation speeds to change. This needs
|
|
|
|
// to be addressed
|
2010-11-08 21:09:22 +00:00
|
|
|
if (!doUpdate)
|
|
|
|
return;
|
2009-08-19 21:51:43 +00:00
|
|
|
|
2010-11-03 04:29:37 +00:00
|
|
|
if (Config.showSceneLoading) {
|
|
|
|
if (!_titleLoaded) {
|
|
|
|
_title->update(_vm->getTick());
|
|
|
|
if (_title->loadingComplete()) {
|
|
|
|
_titleLoaded = true;
|
2010-11-10 20:45:19 +00:00
|
|
|
activate();
|
2010-11-03 04:29:37 +00:00
|
|
|
}
|
|
|
|
return;
|
2009-09-25 01:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 04:29:37 +00:00
|
|
|
|
2010-11-08 21:09:22 +00:00
|
|
|
if (update())
|
2009-09-21 19:11:49 +00:00
|
|
|
return;
|
2009-08-19 21:51:43 +00:00
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
// TODO: check game quality
|
|
|
|
drawScene();
|
2009-08-19 21:51:43 +00:00
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
//TODO: other process stuffs from sub 0040AE30
|
2009-11-22 21:15:09 +00:00
|
|
|
|
2010-11-08 21:09:22 +00:00
|
|
|
|
|
|
|
if (_speech->getSoundResourceId() != 0) {
|
|
|
|
if (_vm->sound()->isPlaying(_speech->getSoundResourceId())) {
|
2009-12-29 21:38:00 +00:00
|
|
|
_speech->prepareSpeech();
|
|
|
|
} else {
|
2010-11-08 21:09:22 +00:00
|
|
|
_speech->resetResourceIds();
|
2010-11-03 04:28:19 +00:00
|
|
|
_vm->clearGameFlag(kGameFlag219);
|
2009-12-29 21:38:00 +00:00
|
|
|
}
|
2010-11-08 21:09:22 +00:00
|
|
|
}
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-10 20:45:19 +00:00
|
|
|
void Scene::activate() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::activate] WorldStats not initialized properly!");
|
|
|
|
|
|
|
|
if (!_bgResource)
|
|
|
|
error("[Scene::activate] Scene resources not initialized properly!");
|
|
|
|
|
2010-11-10 20:45:19 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// FIXME: get rid of this?
|
|
|
|
|
|
|
|
_isActive = true;
|
|
|
|
getScreen()->setPalette(_ws->currentPaletteId);
|
2010-11-28 19:24:59 +00:00
|
|
|
getScreen()->draw(_ws->backgroundImage, 0, _ws->xLeft, _ws->yTop, 0);
|
2010-11-10 20:45:19 +00:00
|
|
|
}
|
|
|
|
|
2010-11-09 03:04:33 +00:00
|
|
|
bool Scene::update() {
|
2010-11-03 04:29:37 +00:00
|
|
|
#ifdef DEBUG_SCENE_TIMES
|
2010-11-03 04:28:14 +00:00
|
|
|
#define MESURE_TICKS(func) { \
|
|
|
|
int32 startTick =_vm->getTick(); \
|
|
|
|
func(); \
|
|
|
|
debugC(kDebugLevelScene, #func " Time: %d", _vm->getTick() - startTick); \
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define MESURE_TICKS(func) func();
|
|
|
|
#endif
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-03 04:28:14 +00:00
|
|
|
// Update each part of the scene
|
|
|
|
MESURE_TICKS(updateMouse);
|
|
|
|
MESURE_TICKS(updateActors);
|
2010-11-04 22:14:44 +00:00
|
|
|
MESURE_TICKS(updateObjects);
|
2010-11-03 04:28:14 +00:00
|
|
|
MESURE_TICKS(updateAmbientSounds);
|
|
|
|
MESURE_TICKS(updateMusic);
|
|
|
|
MESURE_TICKS(updateScreen);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
// Update Debug
|
|
|
|
if (g_debugPolygons)
|
|
|
|
debugShowPolygons();
|
2010-11-04 22:14:44 +00:00
|
|
|
if (g_debugObjects)
|
|
|
|
debugShowObjects();
|
2009-12-05 20:51:46 +00:00
|
|
|
|
2010-11-09 03:04:33 +00:00
|
|
|
return _actions->process();
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2009-09-09 11:14:42 +00:00
|
|
|
void Scene::updateMouse() {
|
2009-12-23 12:13:41 +00:00
|
|
|
Common::Rect actorPos;
|
|
|
|
Common::Point pt;
|
|
|
|
Actor *act = getActor();
|
|
|
|
|
|
|
|
// The code below was from
|
|
|
|
// .text:0040A1B0 getCharacterScreenPosition()
|
|
|
|
// which was only ever called at this point, so
|
|
|
|
// inlining it for simplicity
|
2010-11-16 14:24:57 +00:00
|
|
|
pt.x = (int16)(act->getPoint1()->x -_ws->xLeft);
|
|
|
|
pt.y = (int16)(act->getPoint1()->y -_ws->yTop);
|
2009-09-09 11:14:42 +00:00
|
|
|
|
2010-11-08 21:08:56 +00:00
|
|
|
if (_packId != 2 || _playerActorIdx != 10) {
|
2009-12-23 12:13:41 +00:00
|
|
|
actorPos.left = pt.x + 20;
|
|
|
|
actorPos.top = pt.y;
|
2010-11-16 14:24:57 +00:00
|
|
|
actorPos.right = (int16)(pt.x + 2 * act->getPoint2()->x);
|
|
|
|
actorPos.bottom = (int16)(pt.y + act->getPoint2()->y);
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
actorPos.left = pt.x + 50;
|
|
|
|
actorPos.top = pt.y + 60;
|
2010-11-16 14:24:57 +00:00
|
|
|
actorPos.right = (int16)(pt.x + getActor(10)->getPoint2()->x + 10);
|
|
|
|
actorPos.bottom = (int16)(pt.y + getActor(10)->getPoint2()->y - 20);
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
|
2010-11-13 18:51:06 +00:00
|
|
|
ActorDirection dir = kDirectionInvalid;
|
2009-09-09 11:14:42 +00:00
|
|
|
bool done = false;
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x < actorPos.left) {
|
|
|
|
if (getCursor()->position().y >= actorPos.top) {
|
|
|
|
if (getCursor()->position().y > actorPos.bottom) {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getDirection() == 2) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().y - actorPos.bottom > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionSO;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionS) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.left - getCursor()->position().x > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionSO;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionSO;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getDirection() == 1) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().y - actorPos.top > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionO;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionSO) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.bottom - getCursor()->position().y > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionO;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionO;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getDirection()) {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionO) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.top - getCursor()->position().y > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNO;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNO;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.left - getCursor()->position().x > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNO;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
if (!done && getCursor()->position().x <= actorPos.right) {
|
|
|
|
if (getCursor()->position().y >= actorPos.top) {
|
|
|
|
if (getCursor()->position().y > actorPos.bottom) {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionSO) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x - actorPos.left > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionS;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionSE) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.right - getCursor()->position().x > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionS;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionS;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionNO) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x - actorPos.left > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionN;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionNE) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.right - getCursor()->position().x > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionN;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionN;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
if (!done && getCursor()->position().y < actorPos.top) {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getDirection()) {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionE) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.top - getCursor()->position().y > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNE;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNE;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x - actorPos.right > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionNE;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
if (!done && getCursor()->position().y <= actorPos.bottom) {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionSE) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (actorPos.bottom - getCursor()->position().y > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionE;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
if (act->getDirection() == kDirectionNE) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().y - actorPos.top > 10)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionE;
|
2009-09-09 11:14:42 +00:00
|
|
|
} else {
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionE;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-11-27 00:03:04 +00:00
|
|
|
if (!done && act->getDirection() == kDirectionS) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x - actorPos.right <= 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
done = true;
|
|
|
|
if (!done)
|
2010-11-27 00:03:04 +00:00
|
|
|
dir = kDirectionSE;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
|
2010-11-27 00:03:04 +00:00
|
|
|
if (!done && (act->getDirection() != kDirectionE || getCursor()->position().y - actorPos.bottom > 10))
|
|
|
|
dir = kDirectionSE;
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
handleMouseUpdate(dir, actorPos);
|
2010-01-13 11:53:51 +00:00
|
|
|
|
2009-12-23 12:13:41 +00:00
|
|
|
if (dir >= 0) {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getStatus() == 1 || act->getStatus() == 12)
|
2010-11-03 04:27:55 +00:00
|
|
|
act->setDirection(dir);
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::handleMouseUpdate(int direction, Common::Rect rect) {
|
|
|
|
int16 rlimit = rect.right - 10;
|
2010-11-03 04:28:42 +00:00
|
|
|
ResourceId newGraphicResourceId;
|
2009-12-23 12:13:41 +00:00
|
|
|
HitType type = kHitNone;
|
|
|
|
|
|
|
|
// TODO if encounter_flag03
|
2010-11-08 21:09:13 +00:00
|
|
|
if (0 && getCursor()->graphicResourceId != _ws->curTalkNPC)
|
|
|
|
getCursor()->set(_ws->curTalkNPC, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
Actor *act = getActor(); // get the player actor reference
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
// XXX field_11 seems to have something to do with
|
|
|
|
// whether the event manager is handling a right mouse down
|
|
|
|
// event
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->field_11 & 2) {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getStatus() == 1 || act->getStatus() == 12) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (direction >= 0) {
|
2010-11-08 21:09:02 +00:00
|
|
|
newGraphicResourceId = (ResourceId)(_ws->curScrollUp + direction);
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(newGraphicResourceId, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getStatus() == 6 || act->getStatus() == 10) {
|
2010-11-03 04:28:42 +00:00
|
|
|
newGraphicResourceId = _ws->curHand;
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(newGraphicResourceId, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
} else {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getField638()) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x >= rect.left && getCursor()->position().x <= rlimit &&
|
|
|
|
getCursor()->position().y >= rect.top && getCursor()->position().y <= rect.bottom &&
|
|
|
|
hitTestActor(getCursor()->position())) {
|
2009-12-23 12:13:41 +00:00
|
|
|
// TODO LOTS of work here, because apparently we need to use
|
|
|
|
// field_638 as an index into _ws->field_D6AC8, which is not
|
|
|
|
// yet defined as part of worldstats, but according to IDA, is:
|
|
|
|
// 000D6A88 field_D6A88 dd 16 dup(?)
|
|
|
|
// so this is an array that is initialized as part of the scene
|
|
|
|
// loading process. Need to investigate further ...
|
|
|
|
warning("Something...");
|
|
|
|
} else {
|
|
|
|
// TODO pass a reference to hitType so it can be populated by
|
|
|
|
// hitTestScene
|
2010-11-08 21:09:13 +00:00
|
|
|
newGraphicResourceId = hitTestScene(getCursor()->position(), type);
|
2010-11-19 03:41:35 +00:00
|
|
|
if (newGraphicResourceId != (ResourceId)-1) {
|
2009-12-23 12:13:41 +00:00
|
|
|
warning ("Can't set mouse cursor, field_D6AC8 not handled ... yet");
|
|
|
|
// TODO
|
2010-11-03 04:28:42 +00:00
|
|
|
// check if _ws->field_D6AC8[act->field_638] != newGraphicResourceId
|
2009-12-23 12:13:41 +00:00
|
|
|
// if false, set mouse cursor
|
|
|
|
} else {
|
|
|
|
// TODO _ws->field_D6B08 stuff, then set cursor
|
|
|
|
warning ("Can't set mouse cursor, field_D6B08 not handled ... yet");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return; // return result;
|
|
|
|
}
|
2010-11-08 21:09:13 +00:00
|
|
|
int32 targetIdx = hitTest(getCursor()->position(), type);
|
2010-01-13 11:53:51 +00:00
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
//printf ("Mouse X(%d)/Y(%d) = %d\n", getCursor()->position().x, getCursor()->position().y, type);
|
|
|
|
if (getCursor()->position().x >= rect.left && getCursor()->position().x <= rlimit &&
|
|
|
|
getCursor()->position().y >= rect.top && getCursor()->position().y <= rect.bottom &&
|
|
|
|
hitTestActor(getCursor()->position())) {
|
2010-11-03 04:29:18 +00:00
|
|
|
if (act->getReaction(0)) {
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(_ws->curGrabPointer, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-01-13 11:53:51 +00:00
|
|
|
if (targetIdx == -1) {
|
2010-11-08 21:09:02 +00:00
|
|
|
if (_ws->chapter != kChapter2 || _playerActorIdx != 10) {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->flags)
|
|
|
|
getCursor()->set(_ws->curMagnifyingGlass, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
} else {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->flags)
|
|
|
|
getCursor()->set(_ws->curTalkNPC2, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-05-12 10:24:59 +00:00
|
|
|
int32 targetUpdateType = 0;
|
2009-12-23 12:13:41 +00:00
|
|
|
switch (type) {
|
|
|
|
case kHitActionArea:
|
2010-11-03 04:28:35 +00:00
|
|
|
targetUpdateType = _ws->actions[targetIdx]->actionType;
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
2010-11-04 22:14:44 +00:00
|
|
|
case kHitObject:
|
|
|
|
targetUpdateType = _ws->objects[targetIdx]->actionType;
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
case kHitActor:
|
2010-11-03 04:29:18 +00:00
|
|
|
targetUpdateType = getActor(targetIdx)->getStatus();
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// TODO LOBYTE(hitType)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
if (targetUpdateType & 1 && getCursor()->flags != 2) {
|
|
|
|
getCursor()->set(_ws->curMagnifyingGlass, 0, 2);
|
2010-01-13 11:53:51 +00:00
|
|
|
} else {
|
|
|
|
if (targetUpdateType & 4) {
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(_ws->curHand, 0, 2);
|
2010-01-13 11:53:51 +00:00
|
|
|
} else {
|
|
|
|
if (targetUpdateType & 2) {
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(_ws->curTalkNPC, 0, 2);
|
2010-01-13 11:53:51 +00:00
|
|
|
} else {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (targetUpdateType & 0x10 && getCursor()->flags != 2) {
|
|
|
|
getCursor()->set(_ws->curTalkNPC2, 0, 2);
|
2010-01-13 11:53:51 +00:00
|
|
|
} else {
|
2010-11-08 21:09:02 +00:00
|
|
|
if (_ws->chapter != kChapter2 && _playerActorIdx != 10) {
|
2010-11-08 21:09:13 +00:00
|
|
|
getCursor()->set(_ws->curMagnifyingGlass, 0, 0);
|
2010-01-13 11:53:51 +00:00
|
|
|
} else {
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->flags)
|
|
|
|
getCursor()->set(_ws->curTalkNPC2, 0, 2);
|
2010-01-13 11:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
int32 Scene::hitTestObject(const Common::Point pt) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::hitTestObject] WorldStats not initialized properly!");
|
|
|
|
|
2009-12-23 12:13:41 +00:00
|
|
|
int32 targetIdx = -1;
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 i = 0; i < _ws->objects.size(); i++) {
|
2010-11-04 22:14:44 +00:00
|
|
|
Object *object = _ws->objects[i];
|
|
|
|
if (object->isOnScreen())
|
|
|
|
if (object->getPolygonIndex())
|
|
|
|
if (hitTestPixel(object->getResourceId(), object->getFrameIndex(), pt.x, pt.y, object->flags & 0x1000)) {
|
2009-12-23 12:13:41 +00:00
|
|
|
targetIdx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return targetIdx;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 Scene::hitTest(const Common::Point pt, HitType &type) {
|
2009-12-23 12:13:41 +00:00
|
|
|
type = kHitNone;
|
2010-11-04 22:14:44 +00:00
|
|
|
int32 targetIdx = hitTestObject(pt);
|
2009-12-23 12:13:41 +00:00
|
|
|
if (targetIdx == -1) {
|
2010-01-13 11:53:51 +00:00
|
|
|
targetIdx = hitTestActionArea(pt);
|
2009-12-23 12:13:41 +00:00
|
|
|
if (targetIdx == -1) {
|
2010-11-13 18:51:15 +00:00
|
|
|
if (hitTestActor(pt)) {
|
|
|
|
targetIdx = _playerActorIdx;
|
2009-12-23 12:13:41 +00:00
|
|
|
type = kHitActor;
|
2010-11-13 18:51:15 +00:00
|
|
|
}
|
2009-12-23 12:13:41 +00:00
|
|
|
} else {
|
|
|
|
type = kHitActionArea;
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-04 22:14:44 +00:00
|
|
|
type = kHitObject;
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
return targetIdx;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 Scene::hitTestActionArea(const Common::Point pt) {
|
|
|
|
int32 targetIdx = findActionArea(Common::Point(_ws->xLeft + pt.x, _ws->yTop + pt.y));
|
2009-12-23 12:13:41 +00:00
|
|
|
|
2010-11-03 04:28:35 +00:00
|
|
|
if ( targetIdx == -1 || !(_ws->actions[targetIdx]->actionType & 0x17))
|
2010-01-13 11:53:51 +00:00
|
|
|
targetIdx = -1;
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
return targetIdx;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 Scene::findActionArea(const Common::Point pt) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::findActionArea] WorldStats not initialized properly!");
|
|
|
|
|
|
|
|
if (!_polygons)
|
|
|
|
error("[Scene::findActionArea] Polygons not initialized properly!");
|
|
|
|
|
2009-12-23 12:13:41 +00:00
|
|
|
// TODO
|
|
|
|
// This is a VERY loose implementation of the target
|
|
|
|
// function, as this doesn't do any of the flag checking
|
|
|
|
// the original did
|
|
|
|
int32 targetIdx = -1;
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 i = 0; i < _ws->actions.size(); i++) {
|
2010-11-03 04:28:35 +00:00
|
|
|
ActionArea *a = _ws->actions[i];
|
|
|
|
PolyDefinitions p = _polygons->entries[a->polyIdx];
|
2010-01-13 11:53:51 +00:00
|
|
|
if (p.contains(pt.x, pt.y)) {
|
2009-12-23 12:13:41 +00:00
|
|
|
targetIdx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return targetIdx;
|
|
|
|
}
|
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
int32 Scene::isInActionArea(const Common::Point &pt, ActionArea *area) {
|
|
|
|
error("[Scene::isInActionArea] Not implemented!");
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:02 +00:00
|
|
|
ResourceId Scene::hitTestScene(const Common::Point pt, HitType &type) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::hitTestScene] WorldStats not initialized properly!");
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 top = pt.x + _ws->xLeft;
|
|
|
|
int32 left = pt.y + _ws->yTop;
|
2009-12-23 12:13:41 +00:00
|
|
|
type = kHitNone;
|
|
|
|
|
2010-11-08 21:09:02 +00:00
|
|
|
ResourceId result = (ResourceId)findActionArea(Common::Point(top, left));
|
2009-12-23 12:13:41 +00:00
|
|
|
|
2010-11-19 03:41:35 +00:00
|
|
|
if (result != (ResourceId)-1) {
|
2010-11-03 04:29:47 +00:00
|
|
|
if (LOBYTE(_ws->actions[result]->actionType) & 8) {
|
2009-12-23 12:13:41 +00:00
|
|
|
type = kHitActionArea;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// TODO object and actor checks
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
bool Scene::hitTestActor(const Common::Point pt) {
|
2009-12-23 12:13:41 +00:00
|
|
|
Actor *act = getActor();
|
2010-01-13 11:53:51 +00:00
|
|
|
Common::Point actPos;
|
|
|
|
getActorPosition(act, &actPos);
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
int32 hitFrame;
|
2010-11-03 04:29:43 +00:00
|
|
|
if (act->getFrameIndex() >= act->getFrameCount())
|
|
|
|
hitFrame = 2 * act->getFrameIndex() - act->getFrameCount() - 1;
|
2009-12-23 12:13:41 +00:00
|
|
|
else
|
2010-11-03 04:29:43 +00:00
|
|
|
hitFrame = act->getFrameIndex();
|
2009-12-23 12:13:41 +00:00
|
|
|
|
2010-11-03 04:29:18 +00:00
|
|
|
return hitTestPixel(act->getResourceId(),
|
2009-12-23 12:13:41 +00:00
|
|
|
hitFrame,
|
2010-11-16 14:24:57 +00:00
|
|
|
pt.x - act->getPoint()->x - actPos.x,
|
|
|
|
pt.y - act->getPoint()->y - actPos.y,
|
2010-11-03 04:29:18 +00:00
|
|
|
(act->getDirection() >= 0));
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 04:28:42 +00:00
|
|
|
bool Scene::hitTestPixel(ResourceId resourceId, int32 frame, int16 x, int16 y, bool flipped) {
|
2009-12-23 12:13:41 +00:00
|
|
|
// TODO this gets a bit funky with the "flipped" calculations for x intersection
|
|
|
|
// The below is a pretty basic intersection test for proof of concept
|
2010-11-13 18:51:11 +00:00
|
|
|
return GraphicResource::getFrameRect(_vm, resourceId, frame).contains(x, y);
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
void Scene::changePlayer(ActorIndex index) {
|
2010-11-09 03:04:33 +00:00
|
|
|
error("[Scene::changePlayer] not implemented");
|
2010-01-13 11:53:51 +00:00
|
|
|
}
|
2010-11-03 04:28:14 +00:00
|
|
|
|
|
|
|
void Scene::updateActors() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::updateActors] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-03 04:29:32 +00:00
|
|
|
for (uint32 i = 0; i < _ws->actors.size(); i++)
|
|
|
|
_ws->actors[i]->update();
|
2010-11-03 04:28:14 +00:00
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
void Scene::updateObjects() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::updateObjects] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
for (uint32 i = 0; i < _ws->objects.size(); i++)
|
|
|
|
_ws->objects[i]->update();
|
2009-08-18 21:07:40 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 22:19:25 +00:00
|
|
|
void Scene::updateAmbientSounds() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::updateAmbientSounds] WorldStats not initialized properly!");
|
|
|
|
|
2009-12-04 06:15:51 +00:00
|
|
|
if (Config.performance <= 3)
|
|
|
|
return;
|
2009-09-20 21:10:43 +00:00
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 i = 0; i < _ws->numAmbientSound; i++) {
|
2009-12-04 06:15:51 +00:00
|
|
|
bool processSound = true;
|
|
|
|
int panning = 0;
|
|
|
|
int volume = 0;
|
2009-09-20 21:10:43 +00:00
|
|
|
AmbientSoundItem *snd = &_ws->ambientSounds[i];
|
2009-12-04 06:15:51 +00:00
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 f = 0; f < 6; f++) {
|
2010-11-03 04:28:19 +00:00
|
|
|
GameFlag gameFlag = snd->flagNum[f];
|
2009-09-20 21:10:43 +00:00
|
|
|
if (gameFlag >= 0) {
|
|
|
|
if (_vm->isGameFlagNotSet(gameFlag)) {
|
2009-12-04 06:15:51 +00:00
|
|
|
processSound = false;
|
2009-09-20 21:10:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-03 04:28:19 +00:00
|
|
|
if (_vm->isGameFlagSet((GameFlag)-gameFlag)) {
|
2009-12-04 06:15:51 +00:00
|
|
|
processSound = false;
|
|
|
|
break;
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 06:15:51 +00:00
|
|
|
if (processSound) {
|
2010-11-03 04:28:42 +00:00
|
|
|
if (_vm->sound()->isPlaying(snd->resourceId)) {
|
2009-09-20 21:10:43 +00:00
|
|
|
if (snd->field_0) {
|
2009-12-04 06:15:51 +00:00
|
|
|
// TODO optimize
|
|
|
|
// This adjustment only uses the actor at
|
|
|
|
// index zero, but it's supposed to loop through
|
|
|
|
// all available actors as well (I think)
|
|
|
|
volume = calculateVolumeAdjustment(snd, getActor(0));
|
|
|
|
if (volume <= 0) {
|
|
|
|
if (volume < -10000)
|
|
|
|
volume = -10000;
|
2010-11-03 04:28:42 +00:00
|
|
|
// TODO setSoundVolume(snd->resourceId, volume);
|
2009-12-04 06:15:51 +00:00
|
|
|
} else
|
2010-11-03 04:28:42 +00:00
|
|
|
; // TODO setSoundVolume(snd->resourceId, 0);
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-11-03 04:29:47 +00:00
|
|
|
int loflag = BYTE1(snd->flags);
|
2009-09-20 21:10:43 +00:00
|
|
|
if (snd->field_0) {
|
|
|
|
; // TODO calculate panning at point
|
|
|
|
} else {
|
|
|
|
panning = 0;
|
|
|
|
}
|
|
|
|
if (snd->field_0 == 0) {
|
2009-12-04 14:48:59 +00:00
|
|
|
volume = -(snd->field_C ^ 2);
|
2009-09-20 21:10:43 +00:00
|
|
|
} else {
|
2009-12-04 14:48:59 +00:00
|
|
|
volume = calculateVolumeAdjustment(snd, getActor(0));
|
|
|
|
volume += Config.ambientVolume;
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2009-12-04 14:48:59 +00:00
|
|
|
if (loflag & 2) {
|
|
|
|
int tmpVol = volume;
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(10000) < 10) {
|
2009-09-20 21:10:43 +00:00
|
|
|
if (snd->field_0) {
|
2010-11-08 21:09:02 +00:00
|
|
|
_vm->sound()->playSound(snd->resourceId, false, volume, panning);
|
2009-09-20 21:10:43 +00:00
|
|
|
} else {
|
2009-12-04 14:48:59 +00:00
|
|
|
// FIXME will this even work?
|
2010-11-03 04:27:47 +00:00
|
|
|
tmpVol += (vm()->getRandom(500)) * (((vm()->getRandom(100) >= 50) - 1) & 2) - 1;
|
2009-12-04 14:48:59 +00:00
|
|
|
if (tmpVol <= -10000)
|
|
|
|
volume = -10000;
|
|
|
|
if (volume >= 0)
|
|
|
|
tmpVol = 0;
|
2009-09-20 21:10:43 +00:00
|
|
|
else
|
2009-12-04 14:48:59 +00:00
|
|
|
if (tmpVol <= -10000)
|
|
|
|
tmpVol = -10000;
|
2010-11-10 20:45:19 +00:00
|
|
|
getSound()->playSound(snd->resourceId, false, tmpVol, vm()->getRandom(20001) - 10000);
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2009-12-06 17:06:14 +00:00
|
|
|
}
|
2009-12-04 14:48:59 +00:00
|
|
|
} else {
|
|
|
|
if (loflag & 4) {
|
|
|
|
// TODO panning array stuff
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2009-12-04 14:48:59 +00:00
|
|
|
}
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2009-12-04 06:15:51 +00:00
|
|
|
} else {
|
2010-11-03 04:28:42 +00:00
|
|
|
if (_vm->sound()->isPlaying(snd->resourceId))
|
2010-11-10 12:08:50 +00:00
|
|
|
_vm->sound()->stop(snd->resourceId);
|
2009-12-04 06:15:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32 Scene::calculateVolumeAdjustment(AmbientSoundItem *snd, Actor *act) {
|
2010-03-12 11:48:28 +00:00
|
|
|
//int32 x, y;
|
2009-12-04 06:15:51 +00:00
|
|
|
if (snd->field_10) {
|
2010-03-12 11:48:28 +00:00
|
|
|
/* FIXME properly handle global x/y
|
2009-12-04 06:15:51 +00:00
|
|
|
if (g_object_x == -1) {
|
2010-11-16 14:24:57 +00:00
|
|
|
x = snd->x - act->getPoint1()->x - act->getPoint2()->x;
|
|
|
|
y = snd->y - act->getPoint1()->y - act->getPoint2()->y;
|
2009-12-04 06:15:51 +00:00
|
|
|
} else {
|
|
|
|
x = snd->x - g_object_x;
|
|
|
|
y = snd->y - g_object_y;
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2010-03-12 11:48:28 +00:00
|
|
|
*/
|
2009-12-04 06:15:51 +00:00
|
|
|
|
|
|
|
// FIXME vol = sub_432CA0(x ^ 2 + y ^ 2);
|
|
|
|
// Just assigning an arbitrary value for the
|
|
|
|
// time being
|
|
|
|
int vol = 5000;
|
|
|
|
if (100 / snd->field_C)
|
|
|
|
vol = vol / (100 / snd->field_C);
|
|
|
|
else
|
|
|
|
vol = snd->field_C;
|
|
|
|
vol = (vol - snd->field_C) ^ 2;
|
|
|
|
if (vol <= 10000)
|
|
|
|
vol = -vol;
|
|
|
|
else
|
|
|
|
vol = -10000;
|
|
|
|
|
|
|
|
return vol;
|
|
|
|
} else {
|
|
|
|
return -(snd->field_C ^ 2);
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
2009-08-19 22:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::updateMusic() {
|
2010-11-11 14:25:30 +00:00
|
|
|
//warning("[Scene::updateMusic] not implemented!");
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 04:28:14 +00:00
|
|
|
void Scene::updateScreen() {
|
|
|
|
if (g_debugScrolling) { // DEBUG ScreenScrolling
|
|
|
|
debugScreenScrolling(_bgResource->getFrame(0));
|
|
|
|
} else {
|
|
|
|
updateAdjustScreen();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-08 21:09:13 +00:00
|
|
|
void Scene::playIntroSpeech() {
|
2010-11-09 03:04:33 +00:00
|
|
|
ResourceId resourceId;
|
|
|
|
|
|
|
|
switch (_packId) {
|
|
|
|
default:
|
|
|
|
resourceId = (ResourceId)_packId;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kResourcePackCourtyardAndChapel:
|
|
|
|
resourceId = getSpeech()->playScene(4, 3);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kResourcePackCave:
|
|
|
|
resourceId = getSpeech()->playScene(4, 6);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kResourcePackLaboratory:
|
|
|
|
resourceId = getSpeech()->playScene(4, 7);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-11-16 14:24:54 +00:00
|
|
|
getScreen()->clear();
|
2010-11-09 03:04:33 +00:00
|
|
|
|
|
|
|
// TODO do palette fade and wait until sound is done
|
|
|
|
warning("[Scene::playIntroSpeech] Missing palette fade and wait!");
|
2010-11-08 21:09:13 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 22:19:25 +00:00
|
|
|
void Scene::updateAdjustScreen() {
|
2010-03-12 11:48:28 +00:00
|
|
|
Actor *act = getActor();
|
|
|
|
int32 newXLeft = -1;
|
|
|
|
int32 newYTop = -1;
|
|
|
|
Common::Rect b = _ws->boundingRect;
|
2009-09-13 00:01:57 +00:00
|
|
|
|
2009-09-19 21:00:18 +00:00
|
|
|
if (_ws->motionStatus == 1) {
|
2010-11-16 14:24:57 +00:00
|
|
|
int32 posX = act->getPoint1()->x - _ws->xLeft;
|
|
|
|
int32 posY = act->getPoint1()->y - _ws->yTop;
|
2010-03-12 11:48:28 +00:00
|
|
|
|
|
|
|
if (posX < b.left || posX > b.right) {
|
|
|
|
int32 newRBounds = posX - b.right;
|
|
|
|
newXLeft = newRBounds + _ws->xLeft;
|
|
|
|
_ws->xLeft += newRBounds;
|
2009-09-13 00:01:57 +00:00
|
|
|
}
|
2010-03-12 11:48:28 +00:00
|
|
|
|
|
|
|
if (posY < b.top || posY > b.bottom) {
|
|
|
|
int32 newBBounds = posY - b.bottom;
|
|
|
|
newYTop = newBBounds + _ws->yTop;
|
|
|
|
_ws->yTop += newBBounds;
|
2009-09-13 00:01:57 +00:00
|
|
|
}
|
2010-03-12 11:48:28 +00:00
|
|
|
|
|
|
|
if (newXLeft < 0)
|
|
|
|
newXLeft = _ws->xLeft = 0;
|
|
|
|
|
|
|
|
if (newXLeft > _ws->width - 640)
|
|
|
|
newXLeft = _ws->xLeft = _ws->width - 640;
|
|
|
|
|
|
|
|
if (newYTop < 0)
|
|
|
|
newYTop = _ws->yTop = 0;
|
|
|
|
|
|
|
|
if (newYTop > _ws->height - 480)
|
|
|
|
newYTop = _ws->yTop = _ws->height - 480;
|
2009-09-13 00:01:57 +00:00
|
|
|
} else {
|
2010-03-12 11:48:28 +00:00
|
|
|
// TODO
|
2009-09-13 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
2010-03-12 11:48:28 +00:00
|
|
|
uint8 rectIndex = _ws->sceneRectIdx;
|
|
|
|
b = _ws->sceneRects[rectIndex];
|
|
|
|
|
|
|
|
if (newXLeft < b.left)
|
|
|
|
newXLeft = _ws->xLeft = b.left;
|
|
|
|
|
|
|
|
if (newYTop < b.top)
|
|
|
|
newYTop = _ws->yTop = b.top;
|
|
|
|
|
|
|
|
if (newXLeft + 639 > b.right)
|
|
|
|
newXLeft = _ws->xLeft = b.right - 639;
|
|
|
|
|
|
|
|
if (newYTop + 479 > b.bottom)
|
|
|
|
newYTop = _ws->yTop = b.bottom - 479;
|
|
|
|
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
bool Scene::updateSceneCoordinates(int32 tX, int32 tY, int32 A0, bool checkSceneCoords, int32 *param) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::updateSceneCoordinates] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-03 04:28:35 +00:00
|
|
|
Common::Rect *sr = &_ws->sceneRects[_ws->sceneRectIdx];
|
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
int32 *targetX = &_ws->coordinates[0];
|
|
|
|
int32 *targetY = &_ws->coordinates[1];
|
|
|
|
int32 *coord3 = &_ws->coordinates[2];
|
|
|
|
|
|
|
|
*targetX = tX;
|
|
|
|
*targetY = tY;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
*coord3 = A0;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
|
|
|
// Adjust coordinates
|
|
|
|
if (checkSceneCoords)
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetX + 640 > _ws->width)
|
|
|
|
*targetX = _ws->width - 640;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetX < sr->left)
|
|
|
|
*targetX = sr->left;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetY < sr->top)
|
|
|
|
*targetY = sr->top;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetX + 640 > sr->right)
|
|
|
|
*targetX = sr->right - 640;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetY + 480 < sr->bottom)
|
|
|
|
*targetY = sr->bottom - 480;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
|
|
|
if (checkSceneCoords)
|
2010-11-05 13:36:24 +00:00
|
|
|
if (*targetY + 480 > _ws->height)
|
|
|
|
*targetY = _ws->height - 480;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
|
|
|
// Adjust scene offsets & coordinates
|
2010-11-16 14:24:46 +00:00
|
|
|
getSharedData()->setSceneOffset(0);
|
|
|
|
getSharedData()->setSceneXLeft(_ws->xLeft);
|
|
|
|
getSharedData()->setSceneYTop(_ws->yTop);
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
int32 diffX = *targetX - _ws->xLeft;
|
|
|
|
int32 diffY = *targetY - _ws->yTop;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
|
|
|
if (abs(diffX) <= abs(diffY)) {
|
2010-11-05 13:36:24 +00:00
|
|
|
if (_ws->yTop > *targetY)
|
|
|
|
*coord3 = -*coord3;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
getSharedData()->setSceneOffsetAdd(Common::Rational(*coord3, diffY) * diffX);
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (param != NULL && abs(diffY) <= abs(*coord3)) {
|
|
|
|
*targetX = -1;
|
2010-11-03 04:28:35 +00:00
|
|
|
*param = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-05 13:36:24 +00:00
|
|
|
if (_ws->xLeft > *targetX)
|
|
|
|
*coord3 = -*coord3;
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
getSharedData()->setSceneOffsetAdd(Common::Rational(*coord3, diffX) * diffY);
|
2010-11-03 04:28:35 +00:00
|
|
|
|
2010-11-05 13:36:24 +00:00
|
|
|
if (param != NULL && abs(diffX) <= abs(*coord3)) {
|
|
|
|
*targetX = -1;
|
2010-11-03 04:28:35 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Scene drawing
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
int Scene::drawScene() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::drawScene] WorldStats not initialized properly!");
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
_vm->screen()->clearGraphicsInQueue();
|
|
|
|
|
2010-12-01 19:21:21 +00:00
|
|
|
if (getSharedData()->getFlag(kFlagRedraw)) {
|
2010-11-16 14:24:54 +00:00
|
|
|
_vm->screen()->clear();
|
2009-09-21 19:11:49 +00:00
|
|
|
} else {
|
|
|
|
// Draw scene background
|
2010-11-28 19:24:59 +00:00
|
|
|
_vm->screen()->draw(_ws->backgroundImage, 0, -_ws->xLeft, -_ws->yTop, 0);
|
2009-12-05 20:51:46 +00:00
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
// Draw actors on the update list
|
|
|
|
buildUpdateList();
|
2010-11-03 04:29:47 +00:00
|
|
|
processUpdateList();
|
2010-11-03 04:29:43 +00:00
|
|
|
|
2010-11-08 21:09:02 +00:00
|
|
|
if (_ws->chapter == kChapter11)
|
2010-11-03 04:29:43 +00:00
|
|
|
checkVisibleActorsPriority();
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
// Queue updates
|
|
|
|
for (uint32 i = 0; i < _ws->actors.size(); i++)
|
|
|
|
_ws->actors[i]->draw();
|
2009-11-14 03:46:38 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
for (uint32 i = 0; i < _ws->objects.size(); i++)
|
|
|
|
_ws->objects[i]->draw();
|
2010-11-03 04:29:43 +00:00
|
|
|
|
|
|
|
Actor *player = getActor();
|
|
|
|
if (player->getStatus() == kActorStatus6 || player->getStatus() == kActorStatus10)
|
2010-11-20 22:43:16 +00:00
|
|
|
player->updateAndDraw();
|
2010-11-03 04:29:43 +00:00
|
|
|
else
|
|
|
|
player->setNumberFlag01(0);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
_vm->screen()->drawGraphicsInQueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
bool Scene::updateListCompare(const UpdateItem &item1, const UpdateItem &item2) {
|
|
|
|
return item1.priority - item2.priority;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::buildUpdateList() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::buildUpdateList] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
_updateList.clear();
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < _ws->actors.size(); i++) {
|
|
|
|
Actor *actor = _ws->actors[i];
|
|
|
|
|
|
|
|
if (actor->isVisible()) {
|
|
|
|
UpdateItem item;
|
|
|
|
item.index = i;
|
2010-11-16 14:24:57 +00:00
|
|
|
item.priority = actor->getPoint1()->y + actor->getPoint2()->y;
|
2010-11-03 04:29:43 +00:00
|
|
|
|
|
|
|
_updateList.push_back(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort the list (the original uses qsort, so we may have to revert to that if our sort isn't behaving the same)
|
|
|
|
Common::sort(_updateList.begin(), _updateList.end(), &Scene::updateListCompare);
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
void Scene::processUpdateList() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::processUpdateList] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
for (uint32 i = 0; i < _updateList.size(); i++) {
|
|
|
|
Actor *actor = getActor(_updateList[i].index);
|
|
|
|
int32 priority = _updateList[i].priority;
|
|
|
|
Common::Point point;
|
|
|
|
|
|
|
|
// Check priority
|
|
|
|
if (priority < 0) {
|
|
|
|
actor->setPriority(abs(priority));
|
2009-11-14 03:46:38 +00:00
|
|
|
continue;
|
2010-11-03 04:29:47 +00:00
|
|
|
}
|
2009-11-14 03:46:38 +00:00
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
actor->setPriority(3);
|
|
|
|
|
|
|
|
if (actor->getField944() == 1 || actor->getField944() == 4) {
|
|
|
|
actor->setPriority(1);
|
|
|
|
} else {
|
|
|
|
actor->setField938(1);
|
|
|
|
actor->setField934(0);
|
2010-11-16 14:24:57 +00:00
|
|
|
point.x = actor->getPoint1()->x + actor->getPoint2()->x;
|
|
|
|
point.y = actor->getPoint1()->y + actor->getPoint2()->y;
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-16 14:24:57 +00:00
|
|
|
int32 bottomRight = actor->getBoundingRect()->bottom + actor->getPoint1()->y + 4;
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-16 14:24:46 +00:00
|
|
|
if (_ws->chapter == kChapter11 && _updateList[i].index != getPlayerIndex())
|
2010-11-03 04:29:47 +00:00
|
|
|
bottomRight += 20;
|
|
|
|
|
|
|
|
// Our actor rect
|
2010-11-16 14:24:57 +00:00
|
|
|
Common::Rect actorRect(actor->getPoint1()->x, actor->getPoint1()->y, actor->getPoint1()->x + actor->getBoundingRect()->right, bottomRight);
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// Process objects
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 j = 0; j < _ws->objects.size(); j++) {
|
2010-11-04 22:14:44 +00:00
|
|
|
Object *object = _ws->objects[i];
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// Skip hidden objects
|
|
|
|
if (!object->isOnScreen())
|
2010-11-03 04:29:47 +00:00
|
|
|
continue;
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// Rect for the object
|
|
|
|
Common::Rect objectRect(object->x, object->y, object->x + object->getBoundingRect()->right, object->y + object->getBoundingRect()->bottom);
|
2010-11-03 04:29:43 +00:00
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
// Check that the rects are contained
|
2010-11-04 22:14:44 +00:00
|
|
|
if (!objectRect.contains(actorRect)) {
|
|
|
|
if (BYTE1(object->flags) & kObjectFlag20)
|
|
|
|
if (!(BYTE1(object->flags) & kObjectFlag80))
|
|
|
|
object->flags = BYTE1(object->flags) | kObjectFlag40;
|
2010-11-03 04:29:43 +00:00
|
|
|
continue;
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// Check if it intersects with either the object rect or the related polygon
|
2010-11-03 04:29:47 +00:00
|
|
|
bool intersects = false;
|
2010-11-04 22:14:44 +00:00
|
|
|
if (object->flags & kObjectFlag2) {
|
|
|
|
intersects = pointIntersectsRect(point, *object->getRect());
|
2009-09-21 19:11:49 +00:00
|
|
|
} else {
|
2010-11-04 22:14:44 +00:00
|
|
|
if (object->flags & kObjectFlag40) {
|
|
|
|
PolyDefinitions *poly = &_polygons->entries[object->getPolygonIndex()];
|
2010-11-16 14:24:17 +00:00
|
|
|
if (point.x > 0 && point.y > 0 && poly->count() > 0)
|
2010-11-03 04:29:47 +00:00
|
|
|
intersects = poly->contains(point);
|
2010-11-03 04:29:43 +00:00
|
|
|
else
|
2010-11-04 22:14:44 +00:00
|
|
|
warning ("[drawActorsAndObjects] trying to find intersection of uninitialized point");
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// Adjust object flags
|
|
|
|
if (BYTE1(object->flags) & kObjectFlag80 || intersects) {
|
|
|
|
if (BYTE1(object->flags) & kObjectFlag20)
|
|
|
|
object->flags = (BYTE1(object->flags) & 0xBF) | kObjectFlag80;
|
2010-11-03 04:29:47 +00:00
|
|
|
} else {
|
2010-11-04 22:14:44 +00:00
|
|
|
if (BYTE1(object->flags) & kObjectFlag20) {
|
|
|
|
object->flags = BYTE1(object->flags) | kObjectFlag40;
|
2010-11-03 04:29:47 +00:00
|
|
|
}
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
2010-11-03 04:29:47 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
if (object->flags & kObjectFlag4) {
|
2010-11-03 04:29:47 +00:00
|
|
|
if (intersects && LOBYTE(actor->flags) & kActorFlagMasked) {
|
|
|
|
error("[Scene::processUpdateList] Assigning mask to masked character [%s]", actor->getName());
|
|
|
|
} else {
|
2010-11-28 23:35:38 +00:00
|
|
|
object->adjustCoordinates(&point);
|
2010-11-04 22:14:44 +00:00
|
|
|
actor->setObjectIndex(j);
|
2010-11-03 04:29:47 +00:00
|
|
|
actor->flags |= kActorFlagMasked;
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (intersects) {
|
2010-11-04 22:14:44 +00:00
|
|
|
if (actor->getPriority() < object->getPriority()) {
|
2010-11-03 04:29:47 +00:00
|
|
|
actor->setField934(1);
|
2010-11-04 22:14:44 +00:00
|
|
|
actor->setPriority(object->getPriority() + 3);
|
2010-11-03 04:29:47 +00:00
|
|
|
|
|
|
|
if (_updateList[i].index > _updateList[0].index) {
|
|
|
|
error("[Scene::processUpdateList] list update not implemented!");
|
|
|
|
}
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
} else {
|
2010-11-04 22:14:44 +00:00
|
|
|
if (actor->getPriority() > object->getPriority() || actor->getPriority() == 1) {
|
2010-11-03 04:29:47 +00:00
|
|
|
actor->setField934(1);
|
2010-11-04 22:14:44 +00:00
|
|
|
actor->setPriority(object->getPriority() - 1);
|
2010-11-03 04:29:47 +00:00
|
|
|
|
|
|
|
if (_updateList[i].index > _updateList[0].index) {
|
|
|
|
error("[Scene::processUpdateList] list update not implemented!");
|
|
|
|
}
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-04 22:14:44 +00:00
|
|
|
} // end processing objects
|
2010-11-03 04:29:47 +00:00
|
|
|
|
|
|
|
// Update all other actors
|
|
|
|
for (uint32 k = 0; k < _updateList.size(); k++) {
|
|
|
|
Actor *actor2 = getActor(_updateList[k].index);
|
|
|
|
|
|
|
|
if (actor2->isVisible() && actor2->getField944() != 1 && actor2->getField944() != 4 && _updateList[k].index != _updateList[i].index) {
|
|
|
|
|
2010-11-16 14:24:57 +00:00
|
|
|
Common::Rect actor2Rect(actor2->getPoint1()->x, actor2->getPoint1()->y, actor2->getPoint1()->x + actor2->getBoundingRect()->right, actor2->getPoint1()->y + actor2->getBoundingRect()->bottom);
|
2010-11-03 04:29:47 +00:00
|
|
|
|
|
|
|
if (actor2Rect.contains(actorRect)) {
|
|
|
|
|
|
|
|
// Inferior
|
2010-11-16 14:24:57 +00:00
|
|
|
if ((actor2->getPoint1()->y + actor2->getPoint2()->y) > (actor->getPoint1()->y + actor->getPoint2()->y)) {
|
2010-11-03 04:29:47 +00:00
|
|
|
if (actor->getPriority() <= actor2->getPriority()) {
|
|
|
|
if (actor->getField934() || actor2->getNumberValue01()) {
|
|
|
|
if (!actor2->getNumberValue01())
|
|
|
|
actor2->setPriority(actor->getPriority() - 1);
|
|
|
|
} else {
|
|
|
|
actor->setPriority(actor2->getPriority() + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Superior
|
2010-11-16 14:24:57 +00:00
|
|
|
if ((actor2->getPoint1()->y + actor2->getPoint2()->y) < (actor->getPoint1()->y + actor->getPoint2()->y)) {
|
2010-11-03 04:29:47 +00:00
|
|
|
if (actor->getPriority() >= actor2->getPriority()) {
|
|
|
|
if (actor->getField934() || actor2->getNumberValue01()) {
|
|
|
|
if (!actor2->getNumberValue01())
|
|
|
|
actor2->setPriority(actor->getPriority() + 1);
|
|
|
|
} else {
|
|
|
|
actor->setPriority(actor2->getPriority() - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (actor->getField974())
|
|
|
|
getActor(actor->getField980())->setPriority(-actor->getPriority());
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
2010-11-03 04:29:47 +00:00
|
|
|
} // end processing actors
|
|
|
|
|
|
|
|
|
|
|
|
// Go through the list from the end
|
|
|
|
if (_updateList.size() > 1) {
|
|
|
|
for (int i = _ws->actors.size() - 1; i >= 0; --i) {
|
|
|
|
Actor *actor = _ws->actors[i];
|
|
|
|
|
|
|
|
// Skip hidden actors
|
|
|
|
if (!actor->isVisible())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (actor->getField944() != 1 && actor->getField944() != 4) {
|
|
|
|
error("[Scene::processUpdateList] list update not implemented!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:56 +00:00
|
|
|
void Scene::checkVisibleActorsPriority() {
|
|
|
|
error("[Scene::checkVisibleActorsPriority] not implemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::adjustActorPriority(ActorIndex index) {
|
|
|
|
error("[Scene::adjustActorPriority] not implemented");
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Helpers
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool Scene::pointIntersectsRect(Common::Point point, Common::Rect rect) {
|
|
|
|
if (rect.top || rect.left || rect.bottom || rect.right) {
|
|
|
|
Common::Rational res((rect.bottom - rect.top) * (point.x - rect.left), rect.right - rect.left);
|
|
|
|
|
|
|
|
return (bool)(point.y > rect.top ? 1 + res.toInt() : res.toInt());
|
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2010-11-03 04:29:47 +00:00
|
|
|
return true;
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:43 +00:00
|
|
|
void Scene::getActorPosition(Actor *actor, Common::Point *pt) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::getActorPosition] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-16 14:24:57 +00:00
|
|
|
pt->x = actor->getPoint1()->x - _ws->xLeft;
|
|
|
|
pt->y = actor->getPoint1()->y - _ws->yTop;
|
2010-11-03 04:29:43 +00:00
|
|
|
}
|
2009-08-19 21:51:43 +00:00
|
|
|
// ----------------------------------
|
|
|
|
// ---------- SCREEN REGION -----------
|
|
|
|
// ----------------------------------
|
|
|
|
|
|
|
|
void Scene::copyToBackBufferClipped(Graphics::Surface *surface, int x, int y) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::copyToBackBufferClipped] WorldStats not initialized properly!");
|
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
Common::Rect screenRect(_ws->xLeft, _ws->yTop, _ws->xLeft + 640, _ws->yTop + 480);
|
2009-08-19 21:51:43 +00:00
|
|
|
Common::Rect animRect(x, y, x + surface->w, y + surface->h);
|
|
|
|
animRect.clip(screenRect);
|
|
|
|
|
|
|
|
if (!animRect.isEmpty()) {
|
|
|
|
// Translate anim rectangle
|
2009-12-05 20:51:46 +00:00
|
|
|
animRect.translate(-(int16)_ws->xLeft, -(int16)_ws->yTop);
|
2009-08-19 21:51:43 +00:00
|
|
|
|
|
|
|
int startX = animRect.right == 640 ? 0 : surface->w - animRect.width();
|
|
|
|
int startY = animRect.bottom == 480 ? 0 : surface->h - animRect.height();
|
|
|
|
|
|
|
|
if (surface->w > 640)
|
2009-12-05 20:51:46 +00:00
|
|
|
startX = _ws->xLeft;
|
2009-08-19 21:51:43 +00:00
|
|
|
if (surface->h > 480)
|
2009-12-05 20:51:46 +00:00
|
|
|
startY = _ws->yTop;
|
2009-08-19 21:51:43 +00:00
|
|
|
|
2009-09-19 17:43:35 +00:00
|
|
|
_vm->screen()->copyToBackBufferWithTransparency(
|
2009-09-21 19:11:49 +00:00
|
|
|
((byte*)surface->pixels) +
|
|
|
|
startY * surface->pitch +
|
|
|
|
startX * surface->bytesPerPixel,
|
|
|
|
surface->pitch,
|
|
|
|
animRect.left,
|
|
|
|
animRect.top,
|
|
|
|
animRect.width(),
|
|
|
|
animRect.height());
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------
|
|
|
|
// ---------- DEBUG REGION -----------
|
|
|
|
// ----------------------------------
|
|
|
|
|
|
|
|
void Scene::debugScreenScrolling(GraphicFrame *bg) {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::debugScreenScrolling] WorldStats not initialized properly!");
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
// Horizontal scrolling
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().x < SCREEN_EDGES && _ws->xLeft >= SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->xLeft -= SCROLL_STEP;
|
2010-11-08 21:09:13 +00:00
|
|
|
else if (getCursor()->position().x > 640 - SCREEN_EDGES && _ws->xLeft <= bg->surface.w - 640 - SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->xLeft += SCROLL_STEP;
|
2009-08-19 21:51:43 +00:00
|
|
|
|
|
|
|
// Vertical scrolling
|
2010-11-08 21:09:13 +00:00
|
|
|
if (getCursor()->position().y < SCREEN_EDGES && _ws->yTop >= SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->yTop -= SCROLL_STEP;
|
2010-11-08 21:09:13 +00:00
|
|
|
else if (getCursor()->position().y > 480 - SCREEN_EDGES && _ws->yTop <= bg->surface.h - 480 - SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->yTop += SCROLL_STEP;
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// WALK REGION DEBUG
|
|
|
|
void Scene::debugShowWalkRegion(PolyDefinitions *poly) {
|
|
|
|
Graphics::Surface surface;
|
|
|
|
surface.create(poly->boundingRect.right - poly->boundingRect.left + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
poly->boundingRect.bottom - poly->boundingRect.top + 1,
|
|
|
|
1);
|
2009-08-19 21:51:43 +00:00
|
|
|
|
|
|
|
// Draw all lines in Polygon
|
2010-11-16 14:24:17 +00:00
|
|
|
for (uint32 i = 0; i < poly->count(); i++) {
|
2009-08-19 21:51:43 +00:00
|
|
|
surface.drawLine(
|
2009-09-21 19:11:49 +00:00
|
|
|
poly->points[i].x - poly->boundingRect.left,
|
|
|
|
poly->points[i].y - poly->boundingRect.top,
|
2010-11-16 14:24:17 +00:00
|
|
|
poly->points[(i+1) % poly->count()].x - poly->boundingRect.left,
|
|
|
|
poly->points[(i+1) % poly->count()].y - poly->boundingRect.top, 0x3A);
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
copyToBackBufferClipped(&surface, poly->boundingRect.left, poly->boundingRect.top);
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
|
|
|
|
// POLYGONS DEBUG
|
|
|
|
void Scene::debugShowPolygons() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_polygons)
|
|
|
|
error("[Scene::debugShowPolygons] Polygons not initialized properly!");
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 p = 0; p < _polygons->numEntries; p++) {
|
2009-08-19 21:51:43 +00:00
|
|
|
Graphics::Surface surface;
|
2009-09-19 12:24:53 +00:00
|
|
|
PolyDefinitions poly = _polygons->entries[p];
|
2009-08-19 21:51:43 +00:00
|
|
|
surface.create(poly.boundingRect.right - poly.boundingRect.left + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
poly.boundingRect.bottom - poly.boundingRect.top + 1,
|
|
|
|
1);
|
|
|
|
|
2009-08-19 21:51:43 +00:00
|
|
|
// Draw all lines in Polygon
|
2010-11-16 14:24:17 +00:00
|
|
|
for (uint32 i = 0; i < poly.count(); i++) {
|
2009-08-19 21:51:43 +00:00
|
|
|
surface.drawLine(
|
2009-09-21 19:11:49 +00:00
|
|
|
poly.points[i].x - poly.boundingRect.left,
|
|
|
|
poly.points[i].y - poly.boundingRect.top,
|
2010-11-16 14:24:17 +00:00
|
|
|
poly.points[(i+1) % poly.count()].x - poly.boundingRect.left,
|
|
|
|
poly.points[(i+1) % poly.count()].y - poly.boundingRect.top, 0xFF);
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-08-19 21:51:43 +00:00
|
|
|
copyToBackBufferClipped(&surface, poly.boundingRect.left, poly.boundingRect.top);
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// OBJECT DEBUGGING
|
|
|
|
void Scene::debugShowObjects() {
|
2010-11-16 14:24:27 +00:00
|
|
|
if (!_ws)
|
|
|
|
error("[Scene::debugShowObjects] WorldStats not initialized properly!");
|
|
|
|
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 p = 0; p < _ws->objects.size(); p++) {
|
2009-08-19 21:51:43 +00:00
|
|
|
Graphics::Surface surface;
|
2010-11-04 22:14:44 +00:00
|
|
|
Object *object = _ws->objects[p];
|
2009-08-19 21:51:43 +00:00
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
if (object->flags & 0x20) {
|
|
|
|
surface.create(object->getBoundingRect()->right - object->getBoundingRect()->left + 1,
|
|
|
|
object->getBoundingRect()->bottom - object->getBoundingRect()->top + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
1);
|
2010-11-04 22:14:44 +00:00
|
|
|
surface.frameRect(*object->getBoundingRect(), 0x22);
|
|
|
|
copyToBackBufferClipped(&surface, object->x, object->y);
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-04 22:14:44 +00:00
|
|
|
// ACTOR DEBUGGING
|
2009-09-20 19:21:59 +00:00
|
|
|
void Scene::debugShowActors() {
|
2010-11-07 19:36:21 +00:00
|
|
|
for (uint32 p = 0; p < _ws->actors.size(); p++) {
|
2009-09-20 19:21:59 +00:00
|
|
|
Graphics::Surface surface;
|
2010-11-03 04:28:35 +00:00
|
|
|
Actor *a = _ws->actors[p];
|
2009-09-20 19:21:59 +00:00
|
|
|
|
2010-11-03 04:28:35 +00:00
|
|
|
if (a->flags & 2) {
|
2010-11-03 04:29:18 +00:00
|
|
|
surface.create(a->getBoundingRect()->right - a->getBoundingRect()->left + 1,
|
|
|
|
a->getBoundingRect()->bottom - a->getBoundingRect()->top + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
1);
|
2010-11-03 04:29:18 +00:00
|
|
|
surface.frameRect(*a->getBoundingRect(), 0x22);
|
2010-11-16 14:24:57 +00:00
|
|
|
copyToBackBufferClipped(&surface, a->getPoint()->x, a->getPoint()->y);
|
2009-09-20 19:21:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:08 +00:00
|
|
|
int Scene::processActor(int *x, int *param) {
|
|
|
|
error("[Scene::processActor] not implemented!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::updatePalette(int32 param) {
|
|
|
|
error("[Scene::updatePalette] not implemented!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::makeGreyPalette() {
|
|
|
|
error("[Scene::makeGreyPalette] not implemented!");
|
|
|
|
}
|
|
|
|
|
2010-11-03 04:29:18 +00:00
|
|
|
void Scene::resetActor0() {
|
|
|
|
error("[Scene::resetActor0] not implemented!");
|
|
|
|
}
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
} // end of namespace Asylum
|