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-10-06 00:44:08 +00:00
|
|
|
#include "asylum/resources/actor.h"
|
2010-11-03 04:27:47 +00:00
|
|
|
|
2010-10-06 00:44:08 +00:00
|
|
|
#include "asylum/system/config.h"
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2010-11-03 04:27:47 +00:00
|
|
|
#include "asylum/staticres.h"
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
namespace Asylum {
|
|
|
|
|
|
|
|
#define SCREEN_EDGES 40
|
|
|
|
#define SCROLL_STEP 10
|
|
|
|
|
|
|
|
int g_debugPolygons;
|
|
|
|
int g_debugBarriers;
|
2009-12-05 20:51:46 +00:00
|
|
|
int g_debugScrolling;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
Scene::Scene(uint8 sceneIdx, AsylumEngine *engine): _vm(engine) {
|
2009-09-19 12:24:53 +00:00
|
|
|
_sceneIdx = sceneIdx;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
char filename[10];
|
|
|
|
sprintf(filename, SCENE_FILE_MASK, sceneIdx);
|
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
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
if (!fd->exists(filename))
|
|
|
|
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
|
|
|
// jump to game polygons data
|
|
|
|
fd->seek(0xE8686);
|
|
|
|
_polygons = new Polygons(fd);
|
|
|
|
// jump to action list data
|
|
|
|
fd->seek(0xE868E + _polygons->size * _polygons->numEntries);
|
2009-09-19 13:31:00 +00:00
|
|
|
_actions = new ActionList(fd, this);
|
2009-09-19 12:24:53 +00:00
|
|
|
|
|
|
|
fd->close();
|
|
|
|
delete fd;
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
_speech = new Speech(this);
|
2009-09-25 01:05:23 +00:00
|
|
|
_resPack = new ResourcePack(sceneIdx);
|
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
|
2009-12-29 21:38:00 +00:00
|
|
|
_vm->text()->loadFont(_resPack, _ws->font1);
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-09-19 12:24:53 +00:00
|
|
|
char musPackFileName[10];
|
2009-11-11 09:51:36 +00:00
|
|
|
sprintf(musPackFileName, MUSIC_FILE_MASK, sceneIdx);
|
2009-09-19 12:24:53 +00:00
|
|
|
_musPack = new ResourcePack(musPackFileName);
|
|
|
|
|
2009-12-29 21:38:00 +00:00
|
|
|
_bgResource = new GraphicResource(_resPack, _ws->backgroundImage);
|
2010-01-13 11:53:51 +00:00
|
|
|
//_blowUp = 0;
|
|
|
|
_cursor = 0;
|
2009-08-19 22:19:25 +00:00
|
|
|
_background = 0;
|
|
|
|
_leftClick = false;
|
|
|
|
_rightButton = false;
|
|
|
|
_isActive = false;
|
2009-09-21 19:11:49 +00:00
|
|
|
_skipDrawScene = 0;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
g_debugPolygons = 0;
|
|
|
|
g_debugBarriers = 0;
|
|
|
|
g_debugScrolling = 0;
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
// TODO figure out what field_120 is used for
|
|
|
|
_ws->field_120 = -1;
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 a = 0; a < _ws->numActors; a++) {
|
2009-11-24 11:25:30 +00:00
|
|
|
_ws->actors[a].tickValue1 = _vm->getTick();
|
|
|
|
// FIXME This is a hack just to get the current resource
|
|
|
|
// pack and scene into the actor instance(s)
|
|
|
|
_ws->actors[a].setResourcePack(_resPack);
|
|
|
|
_ws->actors[a].setScene(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: init action list
|
|
|
|
|
|
|
|
_titleLoaded = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::initialize() {
|
|
|
|
_vm->setGameFlag(183);
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
_playerActorIdx = 0;
|
|
|
|
|
|
|
|
if (_ws->numBarriers > 0) {
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 priority = 0x0FFB;
|
|
|
|
for (int32 b = 0; b < _ws->numBarriers; b++) {
|
2009-09-21 19:11:49 +00:00
|
|
|
Barrier *barrier = &_ws->barriers[b];
|
|
|
|
barrier->priority = priority;
|
|
|
|
barrier->flags &= 0xFFFF3FFF;
|
|
|
|
priority -= 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
Cursor::create(_cursor, _resPack, _ws->curMagnifyingGlass);
|
2009-12-23 12:13:41 +00:00
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
_ws->sceneRectIdx = 0;
|
2009-11-24 11:46:58 +00:00
|
|
|
_vm->screen()->clearScreen(); // XXX was clearGraphicsInQueue()
|
2009-09-21 19:11:49 +00:00
|
|
|
_ws->motionStatus = 1;
|
|
|
|
|
2009-11-17 02:00:35 +00:00
|
|
|
Actor *actor = getActor();
|
|
|
|
actor->boundingRect.bottom = actor->y2;
|
2009-11-24 11:25:30 +00:00
|
|
|
actor->boundingRect.right = actor->x2 * 2;
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
_ws->boundingRect = Common::Rect(195,
|
|
|
|
115,
|
|
|
|
445 - actor->boundingRect.right,
|
|
|
|
345 - actor->boundingRect.bottom);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
actor->flags |= 1;
|
|
|
|
updateActorDirection(_playerActorIdx, 4);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
if (_ws->numActors > 1) {
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 a = 1; a < _ws->numActors; a++) {
|
2009-11-17 02:00:35 +00:00
|
|
|
Actor *act = &_ws->actors[a];
|
|
|
|
act->flags |= 1;
|
|
|
|
act->direction = 1;
|
2009-11-24 11:25:30 +00:00
|
|
|
updateActorDirection(a, 4);
|
2009-11-17 02:00:35 +00:00
|
|
|
act->x1 -= act->x2;
|
|
|
|
act->y1 -= act->y2;
|
|
|
|
act->boundingRect.bottom = act->y2;
|
|
|
|
act->boundingRect.right = 2 * act->x2;
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 actionIdx = _ws->actionListIdx;
|
2009-11-27 02:02:00 +00:00
|
|
|
if (actionIdx)
|
2009-11-27 14:36:27 +00:00
|
|
|
_actions->queueScript(actionIdx, 0);
|
2009-11-27 02:02:00 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
// XXX not sure why we need to do this again
|
|
|
|
_vm->screen()->clearScreen();
|
|
|
|
// TODO loadTransTables(3, field_64/68/7C)
|
|
|
|
// TODO setTransTable(1)
|
2009-12-29 21:38:00 +00:00
|
|
|
_vm->text()->loadFont(_resPack, _ws->font1);
|
2009-11-24 11:25:30 +00:00
|
|
|
// TODO preloadGraphics() .text:00410F10
|
|
|
|
// TODO sound_sub(sceneNumber) .text:0040E750
|
|
|
|
_ws->actorType = actorType[_ws->numChapter];
|
2009-11-27 02:02:00 +00:00
|
|
|
|
|
|
|
startMusic();
|
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
_vm->tempTick07 = 1;
|
2009-11-27 02:02:00 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
// TODO sceneRectChangedFlag = 1;
|
2009-11-27 02:02:00 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
actor->tickValue1= _vm->getTick();
|
|
|
|
// XXX This initialization was already done earlier,
|
|
|
|
// so I'm not sure why we need to do it again. Investigate.
|
|
|
|
updateActorDirectionDefault(_playerActorIdx);
|
2009-11-27 02:02:00 +00:00
|
|
|
|
2009-11-24 11:25:30 +00:00
|
|
|
if (_ws->numChapter == 9) {
|
|
|
|
// TODO changeActorIndex(1); .text:00405140
|
|
|
|
_ws->field_E860C = -1;
|
|
|
|
}
|
2009-08-04 13:27:04 +00:00
|
|
|
}
|
|
|
|
|
2009-11-27 02:02:00 +00:00
|
|
|
void Scene::startMusic() {
|
|
|
|
// TODO musicCacheOk check as part of if
|
|
|
|
int musicId = 0;
|
|
|
|
if (_ws->musicCurrentResId != -666 && _ws->numChapter != 1)
|
|
|
|
musicId = _ws->musicResId - 0x7FFE0000;
|
|
|
|
_vm->sound()->playMusic(_musPack, musicId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
Scene::~Scene() {
|
2009-09-19 12:24:53 +00:00
|
|
|
delete _ws;
|
|
|
|
delete _polygons;
|
|
|
|
delete _actions;
|
|
|
|
|
2009-09-01 02:49:02 +00:00
|
|
|
delete _cursor;
|
2009-08-04 13:27:04 +00:00
|
|
|
delete _bgResource;
|
|
|
|
delete _musPack;
|
|
|
|
delete _resPack;
|
2010-01-13 11:53:51 +00:00
|
|
|
//delete _blowUp;
|
2009-09-25 01:05:23 +00:00
|
|
|
|
|
|
|
// TODO we can probably dispose of the title resource once the
|
|
|
|
// _titleLoaded flag has been set, as opposed to in the
|
|
|
|
// scene destructor
|
|
|
|
#ifdef SHOW_SCENE_LOADING
|
|
|
|
delete _title;
|
|
|
|
#endif
|
2009-09-19 12:24:53 +00:00
|
|
|
}
|
2009-08-04 13:27:04 +00:00
|
|
|
|
2009-11-24 11:00:45 +00:00
|
|
|
Actor* Scene::getActor(int index) {
|
|
|
|
return &_ws->actors[(index != -1) ? index : _playerActorIdx];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::updateActorDirection(int actorIndex, int param) {
|
|
|
|
Actor *actor = getActor(actorIndex);
|
|
|
|
GraphicResource *gra;
|
|
|
|
|
|
|
|
switch (param) {
|
|
|
|
case 16:
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[15];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
if (_ws->numChapter > 2) {
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actorIndex > 12)
|
|
|
|
actor->grResId = actor->grResTable[30];
|
|
|
|
if (_playerActorIdx == actorIndex) {
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameNum = gra->getFrameCount() - 1;
|
|
|
|
delete gra;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (actorIndex == 11) {
|
|
|
|
// TODO check a global variable (that likely
|
|
|
|
// relates to direction) to see if it's > 4,
|
|
|
|
// and if so, subtract it from 8. Then use this
|
|
|
|
// to set actor[11].grResId
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME I know this seems wasteful, but it's how the
|
|
|
|
// original worked. I guess this is to set the framecount
|
|
|
|
// regardless of the actorIndex value, though it assumes
|
|
|
|
// the actor's grResId has been set.
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
// TODO Refactor, because this is identical to case 16,
|
|
|
|
// other than a different grResTable index
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[10];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
// TODO Check if there is an encounter currently
|
|
|
|
// active (via the global at .data:00543504)
|
|
|
|
// FIXME skipping for now
|
|
|
|
if (0) {
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandomBit() == 1 && defaultActorDirectionLoaded(actorIndex, 15)) {
|
2009-11-24 11:00:45 +00:00
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[15];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
} else {
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[10];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
case 6:
|
|
|
|
case 14:
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[15];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 12:
|
|
|
|
// TODO check if sceneNumber == 2 && actorIndex == _playerActorInde
|
|
|
|
// && actor->field_40 equals/doesn't equal a bunch of values,
|
|
|
|
// then set direction like other cases
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 13:
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[actor->direction];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[actor->direction];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
// TODO set word_446EE4 to -1. This global seems to
|
|
|
|
// be used with screen blitting
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
case 19:
|
|
|
|
// TODO check if the actor's name is equal to
|
|
|
|
// "Big Crow"???
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (_ws->numChapter == 2 && actorIndex == 10 && _vm->isGameFlagSet(279)) {
|
|
|
|
Actor *act0 = getActor(0);
|
|
|
|
act0->x1 = actor->x2 + actor->x1 - act0->x2;
|
|
|
|
act0->y1 = actor->y2 + actor->y1 - act0->y2;
|
|
|
|
act0->direction = 4;
|
|
|
|
_playerActorIdx = 0;
|
|
|
|
// TODO disableCharacterVisible(actorIndex)
|
|
|
|
// TODO enableActorVisible(0)
|
|
|
|
_vm->clearGameFlag(279);
|
|
|
|
// TODO some cursor update
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
case 10:
|
|
|
|
case 17:
|
|
|
|
actor->frameNum = 0;
|
|
|
|
if (actor->direction > 4)
|
|
|
|
actor->direction = 8 - actor->direction;
|
|
|
|
actor->grResId = actor->grResTable[20];
|
|
|
|
gra = new GraphicResource(_resPack, actor->grResId);
|
|
|
|
actor->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
actor->updateType = param;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::updateActorDirectionDefault(int actorIndex) {
|
|
|
|
if (actorIndex == -1)
|
|
|
|
actorIndex = _playerActorIdx;
|
|
|
|
updateActorDirection(actorIndex, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Scene::defaultActorDirectionLoaded(int actorIndex, int grResTableIdx) {
|
|
|
|
Actor *actor = getActor(actorIndex);
|
|
|
|
return actor->grResTable[grResTableIdx] != actor->grResTable[5];
|
2009-09-09 22:50:34 +00:00
|
|
|
}
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
void Scene::enterScene() {
|
2009-09-25 01:05:23 +00:00
|
|
|
#ifdef SHOW_SCENE_LOADING
|
|
|
|
if (!_titleLoaded) {
|
|
|
|
_title = new SceneTitle(this);
|
|
|
|
// disable input polling
|
2010-11-03 04:27:41 +00:00
|
|
|
_actions->_allowInput = false;
|
2009-09-25 01:05:23 +00:00
|
|
|
} else {
|
|
|
|
#endif
|
2009-12-29 21:38:00 +00:00
|
|
|
_vm->screen()->setPalette(_resPack, _ws->palette);
|
2009-09-25 01:05:23 +00:00
|
|
|
_background = _bgResource->getFrame(0);
|
|
|
|
_vm->screen()->copyToBackBuffer(
|
2009-12-05 20:51:46 +00:00
|
|
|
((byte *)_background->surface.pixels) + _ws->yTop * _background->surface.w + _ws->xLeft, _background->surface.w,
|
2009-09-25 01:05:23 +00:00
|
|
|
0, 0, 640, 480);
|
|
|
|
|
|
|
|
// FIXME
|
|
|
|
// I don't know that this is the right way to initialize the cursor
|
|
|
|
// when the scene is started. Check against the original to see
|
|
|
|
// when the cursor is initalized, and then how it reacts to the
|
|
|
|
// show_cursor opcode
|
2010-01-13 11:53:51 +00:00
|
|
|
Cursor::create(_cursor, _resPack, _ws->curMagnifyingGlass);
|
2009-09-25 01:05:23 +00:00
|
|
|
_cursor->show();
|
|
|
|
|
2009-11-27 02:02:00 +00:00
|
|
|
startMusic();
|
|
|
|
|
2009-09-25 01:05:23 +00:00
|
|
|
_walking = false;
|
|
|
|
#ifdef SHOW_SCENE_LOADING
|
|
|
|
}
|
|
|
|
#endif
|
2009-08-04 13:27:04 +00:00
|
|
|
_isActive = true;
|
|
|
|
}
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
void Scene::setScenePosition(int x, int y) {
|
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
|
|
|
_ws->targetX = x;
|
|
|
|
_ws->targetY = y;
|
|
|
|
|
2009-09-19 21:00:18 +00:00
|
|
|
if (_ws->targetX < 0)
|
|
|
|
_ws->targetX = 0;
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_ws->targetX > (bg->surface.w - 640))
|
2009-09-19 21:00:18 +00:00
|
|
|
_ws->targetX = bg->surface.w - 640;
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
|
2009-09-19 21:00:18 +00:00
|
|
|
if (_ws->targetY < 0)
|
|
|
|
_ws->targetY = 0;
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_ws->targetY > (bg->surface.h - 480))
|
2009-09-19 21:00:18 +00:00
|
|
|
_ws->targetY = bg->surface.h - 480;
|
2009-08-04 13:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::handleEvent(Common::Event *event, bool doUpdate) {
|
|
|
|
_ev = event;
|
|
|
|
|
|
|
|
switch (_ev->type) {
|
|
|
|
|
|
|
|
case Common::EVENT_MOUSEMOVE:
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor)
|
|
|
|
_cursor->move(_ev->mouse.x, _ev->mouse.y);
|
2009-08-04 13:27:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_LBUTTONUP:
|
2010-11-03 04:27:41 +00:00
|
|
|
if (_actions->doesAllowInput())
|
2009-08-04 13:27:04 +00:00
|
|
|
_leftClick = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_RBUTTONUP:
|
2010-11-03 04:27:41 +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-01-13 11:53:51 +00:00
|
|
|
Cursor::create(_cursor, _resPack, _ws->curMagnifyingGlass);
|
2009-08-04 13:27:04 +00:00
|
|
|
_rightButton = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Common::EVENT_RBUTTONDOWN:
|
2010-11-03 04:27:41 +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
|
|
|
|
if (doUpdate) // || _leftClick)
|
2009-08-04 13:27:04 +00:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2009-08-19 21:51:43 +00:00
|
|
|
// -------------------------------------------
|
|
|
|
// ---------- PROCESS SCENE REGION -----------
|
|
|
|
// -------------------------------------------
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
void Scene::update() {
|
2009-09-25 01:05:23 +00:00
|
|
|
#ifdef SHOW_SCENE_LOADING
|
|
|
|
if (!_titleLoaded) {
|
2009-11-17 02:00:35 +00:00
|
|
|
_title->update(_vm->getTick());
|
2009-09-25 01:05:23 +00:00
|
|
|
if (_title->loadingComplete()) {
|
|
|
|
_titleLoaded = true;
|
|
|
|
enterScene();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2009-09-21 19:11:49 +00:00
|
|
|
if (updateScene())
|
|
|
|
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
|
|
|
|
2009-12-29 21:38:00 +00:00
|
|
|
if (_speech->_soundResIdx != 0) {
|
|
|
|
if (_vm->sound()->isPlaying(_speech->_soundResIdx)) {
|
|
|
|
_speech->prepareSpeech();
|
|
|
|
} else {
|
|
|
|
_speech->_textResIdx = 0;
|
|
|
|
_speech->_soundResIdx = 0;
|
|
|
|
_vm->clearGameFlag(219);
|
|
|
|
}
|
|
|
|
}
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 22:19:25 +00:00
|
|
|
int Scene::updateScene() {
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 startTick = 0;
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Mouse
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2010-01-13 11:53:51 +00:00
|
|
|
updateMouse();
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "UpdateMouse Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Actors
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 a = 0; a < _ws->numActors; a++)
|
2009-09-21 19:11:49 +00:00
|
|
|
updateActor(a);
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "UpdateActors Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Barriers
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2009-11-11 09:51:36 +00:00
|
|
|
updateBarriers();
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "UpdateBarriers Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Ambient Sounds
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
updateAmbientSounds();
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "UpdateAmbientSounds Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Music
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
updateMusic();
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "UpdateMusic Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
// Adjust Screen
|
2009-11-17 02:00:35 +00:00
|
|
|
startTick = _vm->getTick();
|
2010-11-03 04:27:41 +00:00
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
if (g_debugScrolling) { // DEBUG ScreenScrolling
|
|
|
|
debugScreenScrolling(_bgResource->getFrame(0));
|
|
|
|
} else {
|
|
|
|
updateAdjustScreen();
|
|
|
|
}
|
2009-11-17 02:00:35 +00:00
|
|
|
debugC(kDebugLevelScene, "AdjustScreenStart Time: %d", _vm->getTick() - startTick);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-12-05 20:51:46 +00:00
|
|
|
// Update Debug
|
|
|
|
if (g_debugPolygons)
|
|
|
|
debugShowPolygons();
|
|
|
|
if (g_debugBarriers)
|
|
|
|
debugShowBarriers();
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
if (_actions->process())
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
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
|
|
|
|
pt.x = act->x1 -_ws->xLeft;
|
|
|
|
pt.y = act->y1 -_ws->yTop;
|
2009-09-09 11:14:42 +00:00
|
|
|
|
|
|
|
if (_sceneIdx != 2 || _playerActorIdx != 10) {
|
2009-12-23 12:13:41 +00:00
|
|
|
actorPos.left = pt.x + 20;
|
|
|
|
actorPos.top = pt.y;
|
|
|
|
actorPos.right = pt.x + 2 * act->x2;
|
|
|
|
actorPos.bottom = pt.y + act->y2;
|
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;
|
|
|
|
actorPos.right = pt.x + getActor(10)->x2 + 10;
|
|
|
|
actorPos.bottom = pt.y + getActor(10)->y2 - 20;
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int dir = -1;
|
|
|
|
bool done = false;
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x < actorPos.left) {
|
|
|
|
if (_cursor->position().y >= actorPos.top) {
|
|
|
|
if (_cursor->position().y > actorPos.bottom) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 2) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().y - actorPos.bottom > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 3;
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 4) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.left - _cursor->position().x > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 3;
|
|
|
|
} else {
|
|
|
|
dir = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 1) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().y - actorPos.top > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 2;
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 3) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.bottom - _cursor->position().y > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 2;
|
|
|
|
} else {
|
|
|
|
dir = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction) {
|
|
|
|
if (act->direction == 2) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.top - _cursor->position().y > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 1;
|
|
|
|
} else {
|
|
|
|
dir = 1;
|
|
|
|
}
|
|
|
|
} else {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.left - _cursor->position().x > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (!done && _cursor->position().x <= actorPos.right) {
|
|
|
|
if (_cursor->position().y >= actorPos.top) {
|
|
|
|
if (_cursor->position().y > actorPos.bottom) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 3) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x - actorPos.left > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 4;
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 5) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.right - _cursor->position().x > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 4;
|
|
|
|
} else {
|
|
|
|
dir = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 1) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x - actorPos.left > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 0;
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 7) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.right - _cursor->position().x > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 0;
|
|
|
|
} else {
|
|
|
|
dir = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (!done && _cursor->position().y < actorPos.top) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction) {
|
|
|
|
if (act->direction == 6) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.top - _cursor->position().y > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 7;
|
|
|
|
} else {
|
|
|
|
dir = 7;
|
|
|
|
}
|
|
|
|
} else {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x - actorPos.right > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 7;
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (!done && _cursor->position().y <= actorPos.bottom) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 5) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (actorPos.bottom - _cursor->position().y > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 6;
|
|
|
|
} else {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->direction == 7) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().y - actorPos.top > 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 6;
|
|
|
|
} else {
|
|
|
|
dir = 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
2009-12-23 12:13:41 +00:00
|
|
|
if (!done && act->direction == 4) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x - actorPos.right <= 10)
|
2009-09-09 11:14:42 +00:00
|
|
|
done = true;
|
|
|
|
if (!done)
|
|
|
|
dir = 5;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (!done && (act->direction != 6 || _cursor->position().y - actorPos.bottom > 10))
|
2009-09-09 11:14:42 +00:00
|
|
|
dir = 5;
|
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) {
|
|
|
|
if (act->updateType == 1 || act->updateType == 12)
|
|
|
|
setActorDirection(act, dir);
|
2009-09-09 11:14:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-23 12:13:41 +00:00
|
|
|
void Scene::setActorDirection(Actor *act, int direction) {
|
|
|
|
act->direction = (direction > 4) ? 8 - direction : direction;
|
|
|
|
int32 grResId;
|
|
|
|
|
|
|
|
if (act->field_944 != 5) {
|
|
|
|
switch (act->updateType) {
|
|
|
|
case 0x04:
|
|
|
|
case 0x05:
|
|
|
|
case 0x0E: {
|
|
|
|
grResId = act->grResTable[act->direction + 5];
|
|
|
|
// FIXME this seems kind of wasteful just to grab a frame count
|
|
|
|
GraphicResource *gra = new GraphicResource(_resPack, grResId);
|
|
|
|
act->grResId = grResId;
|
|
|
|
act->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x12:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
if (_playerActorIdx == 11) {
|
|
|
|
// NOTE this is supposed to explicitely point to the actor 11 reference,
|
|
|
|
// (_ws->actors[11])
|
|
|
|
// but I'm assuming if control drops through to here, getActor() would
|
|
|
|
// pull the right object because the _playerActorIndex should == 11
|
|
|
|
if (act->direction > 4)
|
|
|
|
act->grResId = act->grResTable[8 - act->direction];
|
|
|
|
else
|
|
|
|
act->grResId = act->grResTable[act->direction];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x01:
|
|
|
|
case 0x02:
|
|
|
|
case 0x0C:
|
2010-01-13 11:53:51 +00:00
|
|
|
act->grResId = act->grResTable[act->direction];
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
case 0x08:
|
2010-01-13 11:53:51 +00:00
|
|
|
act->grResId = act->grResTable[act->direction + 20];
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
warning ("[setActorDirection] default case hit with updateType of %d", act->updateType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::handleMouseUpdate(int direction, Common::Rect rect) {
|
|
|
|
int16 rlimit = rect.right - 10;
|
|
|
|
int32 newGrResId;
|
|
|
|
HitType type = kHitNone;
|
|
|
|
|
|
|
|
// TODO if encounter_flag03
|
2010-01-13 11:53:51 +00:00
|
|
|
if (0 && _cursor->grResId != _ws->curTalkNPC)
|
|
|
|
_cursor->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
|
2009-12-23 12:13:41 +00:00
|
|
|
if (_cursor->field_11 & 2) {
|
|
|
|
if (act->updateType == 1 || act->updateType == 12) {
|
|
|
|
if (direction >= 0) {
|
2009-12-29 21:38:00 +00:00
|
|
|
newGrResId = _ws->curScrollUp + direction;
|
2010-01-13 11:53:51 +00:00
|
|
|
_cursor->set(newGrResId, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (act->updateType == 6 || act->updateType == 10) {
|
2009-12-29 21:38:00 +00:00
|
|
|
newGrResId = _ws->curHand;
|
2010-01-13 11:53:51 +00:00
|
|
|
_cursor->set(newGrResId, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
} else {
|
|
|
|
if (act->field_638) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x >= rect.left && _cursor->position().x <= rlimit &&
|
|
|
|
_cursor->position().y >= rect.top && _cursor->position().y <= rect.bottom &&
|
|
|
|
hitTestActor(_cursor->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-01-13 11:53:51 +00:00
|
|
|
newGrResId = hitTestScene(_cursor->position(), type);
|
2009-12-23 12:13:41 +00:00
|
|
|
if (newGrResId != -1) {
|
|
|
|
warning ("Can't set mouse cursor, field_D6AC8 not handled ... yet");
|
|
|
|
// TODO
|
|
|
|
// check if _ws->field_D6AC8[act->field_638] != newGrResId
|
|
|
|
// 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-01-13 11:53:51 +00:00
|
|
|
int32 targetIdx = hitTest(_cursor->position(), type);
|
|
|
|
|
|
|
|
//printf ("Mouse X(%d)/Y(%d) = %d\n", _cursor->position().x, _cursor->position().y, type);
|
|
|
|
if (_cursor->position().x >= rect.left && _cursor->position().x <= rlimit &&
|
|
|
|
_cursor->position().y >= rect.top && _cursor->position().y <= rect.bottom &&
|
|
|
|
hitTestActor(_cursor->position())) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (act->reaction[0]) {
|
2010-01-13 11:53:51 +00:00
|
|
|
_cursor->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) {
|
2009-12-23 12:13:41 +00:00
|
|
|
if (_ws->numChapter != 2 || _playerActorIdx != 10) {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->flags)
|
|
|
|
_cursor->set(_ws->curMagnifyingGlass, 0, 2);
|
2009-12-23 12:13:41 +00:00
|
|
|
} else {
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->flags)
|
|
|
|
_cursor->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-01-13 11:53:51 +00:00
|
|
|
targetUpdateType = _ws->actions[targetIdx].actionType;
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
case kHitBarrier:
|
2010-01-13 11:53:51 +00:00
|
|
|
targetUpdateType = _ws->barriers[targetIdx].flags2;
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
case kHitActor:
|
2010-01-13 11:53:51 +00:00
|
|
|
targetUpdateType = getActor(targetIdx)->updateType;
|
2009-12-23 12:13:41 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// TODO LOBYTE(hitType)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
if (targetUpdateType & 1 && _cursor->flags != 2) {
|
|
|
|
_cursor->set(_ws->curMagnifyingGlass, 0, 2);
|
|
|
|
} else {
|
|
|
|
if (targetUpdateType & 4) {
|
|
|
|
_cursor->set(_ws->curHand, 0, 2);
|
|
|
|
} else {
|
|
|
|
if (targetUpdateType & 2) {
|
|
|
|
_cursor->set(_ws->curTalkNPC, 0, 2);
|
|
|
|
} else {
|
|
|
|
if (targetUpdateType & 0x10 && _cursor->flags != 2) {
|
|
|
|
_cursor->set(_ws->curTalkNPC2, 0, 2);
|
|
|
|
} else {
|
|
|
|
if (_ws->numChapter != 2 && _playerActorIdx != 10) {
|
|
|
|
_cursor->set(_ws->curMagnifyingGlass, 0, 0);
|
|
|
|
} else {
|
|
|
|
if (_cursor->flags)
|
|
|
|
_cursor->set(_ws->curTalkNPC2, 0, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-23 12:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 Scene::hitTestBarrier(const Common::Point pt) {
|
2009-12-23 12:13:41 +00:00
|
|
|
int32 targetIdx = -1;
|
|
|
|
for (int32 i = 0; i < _ws->numBarriers; i++) {
|
|
|
|
Barrier b = _ws->barriers[i];
|
|
|
|
if (_ws->isBarrierOnScreen(i))
|
|
|
|
if (b.polyIdx)
|
2010-01-13 11:53:51 +00:00
|
|
|
if (hitTestPixel(b.resId, b.frameIdx, pt.x, pt.y, b.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-01-13 11:53:51 +00:00
|
|
|
int32 targetIdx = hitTestBarrier(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-01-13 11:53:51 +00:00
|
|
|
targetIdx = hitTestActor(pt);
|
2009-12-23 12:13:41 +00:00
|
|
|
if (targetIdx != -1)
|
|
|
|
type = kHitActor;
|
|
|
|
} else {
|
|
|
|
type = kHitActionArea;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
type = kHitBarrier;
|
|
|
|
}
|
|
|
|
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-01-13 11:53:51 +00:00
|
|
|
if ( targetIdx == -1 || !(_ws->actions[targetIdx].actionType & 0x17))
|
|
|
|
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) {
|
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;
|
|
|
|
for (int32 i = 0; i < _ws->numActions; i++) {
|
|
|
|
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-01-13 11:53:51 +00:00
|
|
|
int32 Scene::hitTestScene(const Common::Point pt, HitType &type) {
|
|
|
|
int32 top = pt.x + _ws->xLeft;
|
|
|
|
int32 left = pt.y + _ws->yTop;
|
2009-12-23 12:13:41 +00:00
|
|
|
type = kHitNone;
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
int32 result = findActionArea(Common::Point(top, left));
|
2009-12-23 12:13:41 +00:00
|
|
|
|
|
|
|
if (result != -1) {
|
|
|
|
if (LOBYTE(_ws->actions[result].actionType) & 8) {
|
|
|
|
type = kHitActionArea;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO barrier and actor checks
|
|
|
|
|
|
|
|
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;
|
|
|
|
if (act->frameNum >= act->frameCount)
|
|
|
|
hitFrame = 2 * act->frameNum - act->frameCount - 1;
|
|
|
|
else
|
|
|
|
hitFrame = act->frameNum;
|
|
|
|
|
|
|
|
return hitTestPixel(act->grResId,
|
|
|
|
hitFrame,
|
2010-01-13 11:53:51 +00:00
|
|
|
pt.x - act->x - actPos.x,
|
|
|
|
pt.y - act->y - actPos.y,
|
2009-12-23 12:13:41 +00:00
|
|
|
(act->direction >= 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Scene::hitTestPixel(int32 grResId, int32 frame, int16 x, int16 y, bool flipped) {
|
|
|
|
GraphicResource *gra = new GraphicResource(_resPack, grResId);
|
|
|
|
GraphicFrame *fra = gra->getFrame(frame);
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
Common::Rect rect;
|
|
|
|
rect.top = fra->x;
|
|
|
|
rect.left = fra->y;
|
|
|
|
rect.right = fra->x + fra->surface.w;
|
|
|
|
rect.bottom = fra->y + fra->surface.h;
|
|
|
|
|
|
|
|
delete gra;
|
|
|
|
|
|
|
|
return rect.contains(x, y);
|
|
|
|
}
|
|
|
|
|
2009-11-30 22:52:51 +00:00
|
|
|
void Scene::updateActor(int32 actorIdx) {
|
2009-09-21 19:11:49 +00:00
|
|
|
Actor *actor = getActor();
|
|
|
|
|
|
|
|
if (actor->visible()) {
|
|
|
|
// printf("Actor updateType = 0x%02X\n", actor->updateType);
|
|
|
|
|
|
|
|
switch (actor->updateType) {
|
|
|
|
|
|
|
|
case 0x10:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
// TODO: updateCharacterSub14()
|
|
|
|
} else if (_ws->numChapter == 1) {
|
|
|
|
if (_playerActorIdx == actorIdx) {
|
|
|
|
// TODO: updateActorSub21();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x11:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
// TODO: put code here
|
|
|
|
} else if (_ws->numChapter == 11) {
|
|
|
|
if (_playerActorIdx == actorIdx) {
|
|
|
|
// TODO: put code here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xF:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
// TODO: put code here
|
|
|
|
} else if (_ws->numChapter == 11) {
|
|
|
|
// TODO: put code here
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x12:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
// TODO: put code here
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x5: {
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 frameNum = actor->frameNum + 1;
|
2009-09-21 19:11:49 +00:00
|
|
|
actor->frameNum = frameNum % actor->frameCount;
|
|
|
|
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_vm->getTick() - actor->tickValue1 > 300) {
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(100) < 50) {
|
2009-09-21 19:11:49 +00:00
|
|
|
// TODO: check sound playing
|
|
|
|
}
|
2009-11-17 02:00:35 +00:00
|
|
|
actor->tickValue1 = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xC:
|
|
|
|
if (_ws->numChapter == 2) {
|
|
|
|
// TODO: put code here
|
|
|
|
} else if (_ws->numChapter == 11) {
|
|
|
|
// TODO: put code here
|
|
|
|
}
|
|
|
|
case 0x1:
|
|
|
|
// TODO: do actor direction
|
|
|
|
break;
|
|
|
|
case 0x2:
|
|
|
|
case 0xD:
|
|
|
|
// TODO: do actor direction
|
|
|
|
break;
|
|
|
|
case 0x3:
|
|
|
|
case 0x13:
|
|
|
|
// TODO: updateCharacterSub05();
|
|
|
|
break;
|
|
|
|
case 0x7:
|
|
|
|
// TODO: something
|
|
|
|
break;
|
|
|
|
case 0x4:
|
|
|
|
if (actor->field_944 != 5) {
|
2009-11-17 02:00:35 +00:00
|
|
|
updateActorSub01(actor);
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xE:
|
|
|
|
// TODO: updateCharacterSub02(1, actorIdx);
|
|
|
|
break;
|
|
|
|
case 0x15:
|
|
|
|
// TODO: updateCharacterSub06(1, actorIdx);
|
|
|
|
break;
|
|
|
|
case 0x9:
|
|
|
|
// TODO: updateCharacterSub03(1, actorIdx);
|
|
|
|
break;
|
|
|
|
case 0x6:
|
|
|
|
case 0xA:
|
|
|
|
actor->frameNum = (actor->frameNum + 1) % actor->frameCount;
|
|
|
|
break;
|
|
|
|
case 0x8:
|
|
|
|
// TODO: actor sound
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-08-04 13:27:04 +00:00
|
|
|
}
|
|
|
|
|
2009-11-17 02:00:35 +00:00
|
|
|
void Scene::updateActorSub01(Actor *act) {
|
|
|
|
// TODO make sure this is right
|
|
|
|
act->frameNum = act->frameNum + 1 % act->frameCount;
|
|
|
|
if (_vm->getTick() - act->tickValue1 > 300) {
|
|
|
|
// TODO
|
|
|
|
// Check if the actor's name is "Crow"?
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(100) < 50) {
|
2009-11-17 02:00:35 +00:00
|
|
|
// TODO
|
|
|
|
// Check if soundResId04 is assigned, and if so,
|
|
|
|
// if it's playing
|
|
|
|
// If true, check characterSub407260(10)
|
|
|
|
// and if that's true, do characterDirection(9)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if act == getActor()
|
|
|
|
if (_vm->tempTick07) {
|
|
|
|
if (_vm->getTick() - _vm->tempTick07 > 500) {
|
|
|
|
if (_vm->isGameFlagNotSet(183)) { // processing action list
|
|
|
|
if (act->visible()) {
|
|
|
|
// if some_encounter_flag
|
|
|
|
// if !soundResId04
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(100) < 50) {
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_sceneIdx == 13) {
|
|
|
|
; // sub414810(507)
|
|
|
|
} else {
|
|
|
|
; // sub4146d0(4)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
act->tickValue1 = _vm->getTick();
|
|
|
|
}
|
|
|
|
// else
|
|
|
|
// TODO now there's something to do with the
|
|
|
|
// character's name and "Big Crow", or "Crow".
|
|
|
|
// Quite a bit of work to do yet, but it only seems to
|
|
|
|
// take effect when the character index doesn't equal
|
|
|
|
// the currentPlayerIndex (so I'm guessing this is a
|
|
|
|
// one off situation).
|
|
|
|
}
|
|
|
|
|
2010-01-13 11:53:51 +00:00
|
|
|
void Scene::stopSound(int32 barrierIndex, int32 actorIndex) {
|
|
|
|
int32 sndResId = 0;
|
|
|
|
|
|
|
|
if (actorIndex) {
|
|
|
|
sndResId = getActor(actorIndex)->soundResId;
|
|
|
|
} else {
|
|
|
|
if (barrierIndex) {
|
|
|
|
sndResId = _ws->barriers[barrierIndex].soundResId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_vm->sound()->isPlaying(sndResId)) {
|
|
|
|
_vm->sound()->stopSound(sndResId);
|
|
|
|
}
|
|
|
|
}
|
2009-09-19 21:00:18 +00:00
|
|
|
void Scene::updateBarriers() {
|
2009-09-24 02:55:02 +00:00
|
|
|
//Screen *screen = _vm->screen();
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 barriersCount = (int32)_ws->barriers.size();
|
2009-09-24 02:55:02 +00:00
|
|
|
//int startTickCount = 0;
|
2009-09-21 19:11:49 +00:00
|
|
|
bool canPlaySound = false;
|
|
|
|
|
|
|
|
if (barriersCount > 0) {
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 b = 0; b < barriersCount; b++) {
|
2009-09-21 19:11:49 +00:00
|
|
|
Barrier *barrier = &_ws->barriers[b];
|
|
|
|
|
|
|
|
if (barrier->field_3C == 4) {
|
|
|
|
if (_ws->isBarrierVisible(b)) {
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 flag = barrier->flags;
|
2009-09-21 19:11:49 +00:00
|
|
|
if (flag & 0x20) {
|
2009-12-04 21:19:38 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 0x3E8 / barrier->field_B4) {
|
2009-09-21 19:11:49 +00:00
|
|
|
barrier->frameIdx = (barrier->frameIdx + 1) % barrier->frameCount;
|
2009-11-17 02:00:35 +00:00
|
|
|
barrier->tickCount = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
canPlaySound = true;
|
|
|
|
}
|
|
|
|
} else if (flag & 0x10) {
|
2009-12-06 14:20:26 +00:00
|
|
|
uint32 frameIdx = barrier->frameIdx;
|
2009-11-17 02:00:35 +00:00
|
|
|
int equalZero = frameIdx == 0;
|
2009-09-21 19:11:49 +00:00
|
|
|
if (!frameIdx) {
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 1000 * barrier->tickCount2) {
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(barrier->field_C0) == 1) {
|
2009-09-21 19:11:49 +00:00
|
|
|
if (barrier->field_68C[0]) {
|
|
|
|
// TODO: fix this, and find a better way to get frame count
|
|
|
|
// Sometimes we get wrong random resource id
|
|
|
|
|
|
|
|
barrier->resId = barrier->getRandomId();
|
|
|
|
GraphicResource *gra = new GraphicResource(_resPack, barrier->resId);
|
|
|
|
barrier->frameCount = gra->getFrameCount();
|
|
|
|
delete gra;
|
|
|
|
}
|
|
|
|
barrier->frameIdx++;
|
|
|
|
}
|
2009-11-17 02:00:35 +00:00
|
|
|
barrier->tickCount = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
canPlaySound = true;
|
|
|
|
}
|
|
|
|
frameIdx = barrier->frameIdx;
|
|
|
|
equalZero = frameIdx == 0;
|
|
|
|
}
|
|
|
|
|
2009-12-06 17:06:14 +00:00
|
|
|
if (!equalZero) {
|
2009-12-04 21:19:38 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 0x3E8 / barrier->field_B4) {
|
2009-09-21 19:11:49 +00:00
|
|
|
barrier->frameIdx = (barrier->frameIdx + 1) % barrier->frameCount;
|
2009-11-17 02:00:35 +00:00
|
|
|
barrier->tickCount = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
canPlaySound = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (flag & 8) {
|
2009-12-04 21:19:38 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 0x3E8 / barrier->field_B4) {
|
2009-12-06 14:20:26 +00:00
|
|
|
uint32 frameIdx = barrier->frameIdx + 1;
|
2009-09-21 19:11:49 +00:00
|
|
|
if (frameIdx < barrier->frameCount - 1) {
|
|
|
|
if (barrier->field_688 == 1) {
|
|
|
|
// TODO: get global x, y positions
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
barrier->flags &= 0xFFFFFFF7;
|
|
|
|
if (barrier->field_688 == 1) {
|
|
|
|
// TODO: reset global x, y positions
|
|
|
|
}
|
|
|
|
}
|
|
|
|
barrier->frameIdx = frameIdx;
|
2009-08-18 21:07:40 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
} else if ((flag & 0xFF) & 8) { // check this
|
2009-11-17 02:00:35 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 1000 * barrier->tickCount2) {
|
2010-11-03 04:27:47 +00:00
|
|
|
if (vm()->getRandom(barrier->field_C0) == 1) { // TODO: THIS ISNT WORKING
|
2009-08-20 11:17:32 +00:00
|
|
|
barrier->frameIdx = (barrier->frameIdx + 1) % barrier->frameCount;
|
2009-11-17 02:00:35 +00:00
|
|
|
barrier->tickCount = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
canPlaySound = true;
|
2009-08-18 21:07:40 +00:00
|
|
|
}
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
2009-08-20 11:17:32 +00:00
|
|
|
} else if (!((flag & 0xFFFF) & 6)) {
|
2009-12-04 21:19:38 +00:00
|
|
|
if (_vm->getTick() - barrier->tickCount >= 0x3E8 / barrier->field_B4 && (flag & 0x10000)) {
|
2009-12-06 14:20:26 +00:00
|
|
|
uint32 frameIdx = barrier->frameIdx - 1;
|
2009-09-21 19:11:49 +00:00
|
|
|
if (frameIdx <= 0) {
|
|
|
|
barrier->flags &= 0xFFFEFFFF;
|
|
|
|
if (barrier->field_688 == 1) {
|
|
|
|
// TODO: reset global x, y positions
|
|
|
|
}
|
2009-11-17 02:00:35 +00:00
|
|
|
barrier->tickCount = _vm->getTick();
|
2009-09-21 19:11:49 +00:00
|
|
|
canPlaySound = true;
|
|
|
|
}
|
|
|
|
if (barrier->field_688 == 1) {
|
|
|
|
// TODO: get global x, y positions
|
|
|
|
}
|
|
|
|
barrier->frameIdx = frameIdx;
|
2009-12-04 21:19:38 +00:00
|
|
|
} else if (_vm->getTick() - barrier->tickCount >= 0x3E8 / barrier->field_B4) {
|
2009-09-21 19:11:49 +00:00
|
|
|
if ((flag & 0xFF) & 2) {
|
|
|
|
if (barrier->frameIdx == barrier->frameCount - 1) {
|
|
|
|
barrier->frameIdx--;
|
|
|
|
barrier->flags = ((flag & 0xFF) & 0xFD) | 4;
|
|
|
|
} else {
|
|
|
|
barrier->frameIdx++;
|
|
|
|
}
|
|
|
|
} else if ((flag & 0xFF) & 4) {
|
|
|
|
if (barrier->frameIdx) {
|
|
|
|
barrier->frameIdx--;
|
|
|
|
} else {
|
|
|
|
barrier->frameIdx++;
|
|
|
|
barrier->flags = ((flag & 0xFF) & 0xFB) | 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flag = barrier->flags;
|
|
|
|
flag &= 0x40000;
|
|
|
|
if (flag != 0) {
|
|
|
|
if (barrier->frameIdx == barrier->frameCount - 1) {
|
|
|
|
if (barrier->field_B4 <= 15) {
|
|
|
|
barrier->field_B4 -= 2;
|
2009-12-04 21:19:38 +00:00
|
|
|
if (barrier->field_B4 < 0)
|
2009-09-21 19:11:49 +00:00
|
|
|
barrier->field_B4 = 0;
|
|
|
|
} else {
|
|
|
|
barrier->field_B4 = 15;
|
|
|
|
}
|
|
|
|
if (!barrier->field_B4)
|
|
|
|
barrier->flags &= 0xFFFEF1C7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (canPlaySound) {
|
2010-01-13 11:53:51 +00:00
|
|
|
barrier->updateSoundItems(_vm->sound());
|
|
|
|
stopSound(b, 0);
|
2009-09-21 19:11:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: get sound functions according with scene
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-08-18 21:07:40 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 22:19:25 +00:00
|
|
|
void Scene::updateAmbientSounds() {
|
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++) {
|
2009-11-11 09:51:36 +00:00
|
|
|
int 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 {
|
2009-12-04 06:15:51 +00:00
|
|
|
if (_vm->isGameFlagSet(-gameFlag)) {
|
|
|
|
processSound = false;
|
|
|
|
break;
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 06:15:51 +00:00
|
|
|
if (processSound) {
|
2009-09-20 21:10:43 +00:00
|
|
|
if (_vm->sound()->isPlaying(snd->resId)) {
|
|
|
|
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;
|
|
|
|
// TODO setSoundVolume(snd->resId, volume);
|
|
|
|
} else
|
|
|
|
; // TODO setSoundVolume(snd->resId, 0);
|
2009-09-20 21:10:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2009-12-04 06:15:51 +00:00
|
|
|
int loflag = LOBYTE(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) {
|
2009-12-04 14:48:59 +00:00
|
|
|
_vm->sound()->playSound(snd->resId, false, volume, panning, false);
|
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-03 04:27:47 +00:00
|
|
|
_vm->sound()->playSound(snd->resId, 0, 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 {
|
|
|
|
if (_vm->sound()->isPlaying(snd->resId))
|
|
|
|
_vm->sound()->stopSound(snd->resId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
x = snd->x - act->x1 - act->x2;
|
|
|
|
y = snd->y - act->y1 - act->y2;
|
|
|
|
} 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() {
|
2009-08-19 21:51:43 +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-03-12 11:48:28 +00:00
|
|
|
int32 posX = act->x1 - _ws->xLeft;
|
|
|
|
int32 posY = act->y1 - _ws->yTop;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------
|
|
|
|
// ---------- DRAW REGION -----------
|
|
|
|
// ----------------------------------
|
|
|
|
|
|
|
|
int Scene::drawScene() {
|
2009-08-19 22:19:25 +00:00
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
_vm->screen()->clearGraphicsInQueue();
|
|
|
|
|
|
|
|
if (_skipDrawScene) {
|
|
|
|
_vm->screen()->clearScreen();
|
|
|
|
} else {
|
|
|
|
// Draw scene background
|
|
|
|
GraphicFrame *bg = _bgResource->getFrame(0);
|
2009-12-05 20:51:46 +00:00
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
_vm->screen()->copyToBackBuffer(
|
2010-03-12 11:48:28 +00:00
|
|
|
((byte *)bg->surface.pixels) + _ws->yTop * bg->surface.w + _ws->xLeft,
|
|
|
|
bg->surface.w,
|
2009-12-29 21:38:00 +00:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
640,
|
|
|
|
480);
|
2009-09-21 19:11:49 +00:00
|
|
|
|
2009-11-17 02:00:35 +00:00
|
|
|
drawActorsAndBarriers();
|
2009-11-14 03:46:38 +00:00
|
|
|
queueActorUpdates();
|
|
|
|
queueBarrierUpdates();
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
// TODO: draw main actor stuff
|
|
|
|
|
|
|
|
_vm->screen()->drawGraphicsInQueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
2009-11-14 03:46:38 +00:00
|
|
|
void Scene::drawActorsAndBarriers() {
|
|
|
|
// TODO this is supposed to be looping through
|
|
|
|
// a collection of CharacterUpdateItems. Since
|
|
|
|
// we're only on scene 1 atm, and there is only one
|
|
|
|
// character, this will have to do :P
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 i = 0; i < _ws->numActors; i++) {
|
2009-11-14 03:46:38 +00:00
|
|
|
int actorRegPt = 0;
|
|
|
|
Actor *act = &_ws->actors[i];
|
|
|
|
Common::Point pt;
|
|
|
|
|
|
|
|
// XXX Since we're not using CharacterUpdateItems,
|
|
|
|
// the actor priority is never going to be changed.
|
|
|
|
// Need to investigate if this is an issue
|
|
|
|
/*
|
|
|
|
if (act->priority < 0)
|
|
|
|
act->priority = abs(act->priority);
|
|
|
|
continue;
|
|
|
|
*/
|
|
|
|
act->priority = 3;
|
|
|
|
if (act->field_944 == 1 || act->field_944 == 4)
|
|
|
|
act->priority = 1;
|
|
|
|
else {
|
|
|
|
act->field_938 = 1;
|
|
|
|
act->field_934 = 0;
|
|
|
|
pt.x = act->x1 + act->x2;
|
|
|
|
pt.y = act->y1 + act->y2;
|
|
|
|
|
|
|
|
actorRegPt = act->boundingRect.bottom + act->boundingRect.right + 4;
|
|
|
|
|
|
|
|
// TODO special case for scene 11
|
|
|
|
// Not sure if we're checking the scene index
|
|
|
|
// or the scene number though :P
|
|
|
|
/*
|
|
|
|
if (_sceneIdx == 11) {
|
|
|
|
// FIXME this probably won't work
|
|
|
|
if (act != this->getActor())
|
|
|
|
actorRegPt += 20;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
// XXX from .text:0040a4d1
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 barIdx = 0; barIdx < _ws->numBarriers; barIdx++) {
|
2009-11-14 03:46:38 +00:00
|
|
|
Barrier *bar = &_ws->barriers[barIdx];
|
|
|
|
bool actInBar = bar->boundingRect.contains(act->boundingRect);
|
|
|
|
bool intersects = false;
|
|
|
|
|
|
|
|
// TODO verify that my funky LOBYTE macro actually
|
|
|
|
// works the way I assume it should :P
|
|
|
|
if (!actInBar) {
|
|
|
|
if (LOBYTE(bar->flags) & 0x20)
|
2009-11-30 22:52:51 +00:00
|
|
|
if (!(LOBYTE(bar->flags) & 0x80))
|
2009-11-14 03:46:38 +00:00
|
|
|
// XXX not sure if this will work, as it's
|
|
|
|
// supposed to set 0x40 to the lobyte...
|
|
|
|
bar->flags |= 0x40;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bar->flags & 2) {
|
|
|
|
// TODO refactor
|
|
|
|
if (bar->field_74 || bar->field_78 ||
|
|
|
|
bar->field_7C || bar->field_80)
|
|
|
|
intersects = (pt.y > bar->field_78 + (bar->field_80 - bar->field_78) * (pt.x - bar->field_74) / (bar->field_7C - bar->field_74)) == 0;
|
|
|
|
else
|
|
|
|
intersects = true;
|
|
|
|
} else {
|
|
|
|
if (bar->flags & 0x40) {
|
|
|
|
PolyDefinitions *poly = &_polygons->entries[bar->polyIdx];
|
2009-11-17 02:00:35 +00:00
|
|
|
if (pt.x > 0 && pt.y > 0 && poly->numPoints > 0)
|
|
|
|
intersects = poly->contains(pt.x, pt.y);
|
|
|
|
else
|
2009-11-27 14:36:27 +00:00
|
|
|
;//warning ("[drawActorsAndBarriers] trying to find intersection of uninitialized point");
|
2009-11-14 03:46:38 +00:00
|
|
|
}
|
|
|
|
// XXX the original has an else case here that
|
|
|
|
// assigns intersects the value of the
|
|
|
|
// flags & 2 check, which doesn't make any sense since
|
|
|
|
// that path would never have been taken if code
|
|
|
|
// execution had made it's way here.
|
|
|
|
}
|
|
|
|
if (LOBYTE(bar->flags) & 0x80 || intersects) {
|
|
|
|
if (LOBYTE(bar->flags) & 0x20)
|
|
|
|
// XXX not sure if this will work, as it's
|
|
|
|
// supposed to set this value on the lobyte...
|
|
|
|
bar->flags &= 0xBF | 0x80;
|
|
|
|
else
|
|
|
|
// XXX another lobyte assignment...
|
|
|
|
bar->flags |= 0x40;
|
|
|
|
// TODO label jump up a few lines here. Investigate...
|
|
|
|
}
|
|
|
|
if (bar->flags & 4) {
|
|
|
|
if (intersects) {
|
|
|
|
if(act->flags & 2)
|
2009-11-27 14:36:27 +00:00
|
|
|
;//warning ("[drawActorsAndBarriers] Assigning mask to masked character [%s]", bar->name);
|
2009-11-14 03:46:38 +00:00
|
|
|
else {
|
|
|
|
// TODO there's a call to sub_40ac10 that does
|
|
|
|
// a point calculation, but the result doesn't appear to
|
|
|
|
// ever be used, and the object passed in as a parameter
|
|
|
|
// isn't updated
|
|
|
|
act->field_3C = barIdx;
|
|
|
|
act->flags |= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (intersects) {
|
|
|
|
// XXX assuming the following:
|
|
|
|
// "if ( *(int *)((char *)&scene.characters[0].priority + v18) < *(v12_barrierPtr + 35) )"
|
|
|
|
// is the same as what I'm comparing :P
|
|
|
|
if (act->priority < bar->priority) {
|
|
|
|
act->field_934 = 1;
|
|
|
|
act->priority = bar->priority + 3;
|
|
|
|
// TODO there's a block of code here that seems
|
|
|
|
// to loop through the CharacterUpdateItems and do some
|
|
|
|
// priority adjustment. Since I'm not using CharacterUpdateItems as of yet,
|
|
|
|
// I'm not sure what to do here
|
|
|
|
// The loop seems to occur if:
|
|
|
|
// (a) there are still character items to process
|
|
|
|
// (b) sceneNumber != 2 && actor->field_944 != 1
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (act->priority > bar->priority || act->priority == 1) {
|
|
|
|
act->field_934 = 1;
|
|
|
|
act->priority = bar->priority - 1;
|
|
|
|
// TODO another character update loop
|
|
|
|
// This time it looks like there's another
|
|
|
|
// intersection test, and more updates
|
|
|
|
// to field_934 and field_944, then
|
|
|
|
// priority updates
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // end for (barriers)
|
|
|
|
}
|
|
|
|
} // end for (actors)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-09-21 19:11:49 +00:00
|
|
|
void Scene::getActorPosition(Actor *actor, Common::Point *pt) {
|
|
|
|
pt->x = actor->x1 - _ws->xLeft;
|
|
|
|
pt->y = actor->y1 - _ws->yTop;
|
2009-09-20 19:21:59 +00:00
|
|
|
}
|
|
|
|
|
2009-11-14 03:46:38 +00:00
|
|
|
int Scene::queueActorUpdates() {
|
2009-09-21 19:11:49 +00:00
|
|
|
if (_ws->numActors > 0) {
|
|
|
|
Common::Point pt;
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 a = 0; a < _ws->numActors; a++) {
|
2009-09-21 19:11:49 +00:00
|
|
|
Actor *actor = &_ws->actors[a];
|
|
|
|
|
|
|
|
if ((actor->flags & 0xFF) & 1) { // check this mask
|
|
|
|
getActorPosition(actor, &pt);
|
|
|
|
//pt.x += actor->x;
|
|
|
|
//pt.y += actor->y;
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 frameNum = actor->frameNum;
|
2009-09-21 19:11:49 +00:00
|
|
|
if (actor->frameNum >= actor->frameCount) {
|
|
|
|
frameNum = 2 * actor->frameCount - actor->frameNum - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((actor->flags & 0xFF) & 2) {
|
|
|
|
// TODO: sub_40AC10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// TODO: get flag value from character_DeadSarah_sub_40A140
|
|
|
|
_vm->screen()->addGraphicToQueue(actor->grResId, frameNum, pt.x, pt.y, ((actor->direction < 5) - 1) & 2, actor->field_96C, actor->priority);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2009-09-20 19:21:59 +00:00
|
|
|
}
|
|
|
|
|
2009-11-14 03:46:38 +00:00
|
|
|
int Scene::queueBarrierUpdates() {
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 barriersCount = (int32)_ws->barriers.size();
|
2009-09-21 19:11:49 +00:00
|
|
|
|
|
|
|
if (barriersCount > 0) {
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 b = 0; b < barriersCount; b++) {
|
2009-09-21 19:11:49 +00:00
|
|
|
Barrier *barrier = &_ws->barriers[b];
|
|
|
|
|
|
|
|
if (!(barrier->flags & 4) && !((barrier->flags & 0xFF) & 0x40)) {
|
|
|
|
if (_ws->isBarrierOnScreen(b)) {
|
|
|
|
//TODO: need to do something here yet
|
|
|
|
|
|
|
|
if (barrier->field_67C <= 0 || barrier->field_67C >= 4) { // TODO: still missing a condition for game quality config
|
|
|
|
_vm->screen()->addGraphicToQueue(barrier->resId, barrier->frameIdx, barrier->x, barrier->y, (barrier->flags >> 11) & 2, barrier->field_67C - 3, barrier->priority);
|
|
|
|
} else {
|
|
|
|
// TODO: Do Cross Fade
|
2009-12-29 21:38:00 +00:00
|
|
|
// parameters: barrier->resId, barrier->frameIdx, barrier->x, barrier->y, _ws->backgroundImage, _ws->xLeft, _ws->yTop, 0, 0, barrier->field_67C - 1
|
2009-09-21 19:11:49 +00:00
|
|
|
_vm->screen()->addGraphicToQueue(barrier->resId, barrier->frameIdx, barrier->x, barrier->y, 0, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2009-08-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------
|
|
|
|
// ---------- SCREEN REGION -----------
|
|
|
|
// ----------------------------------
|
|
|
|
|
|
|
|
void Scene::copyToBackBufferClipped(Graphics::Surface *surface, int x, int y) {
|
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) {
|
2009-09-21 19:11:49 +00:00
|
|
|
// Horizontal scrolling
|
2010-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().x < SCREEN_EDGES && _ws->xLeft >= SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->xLeft -= SCROLL_STEP;
|
2010-01-13 11:53:51 +00:00
|
|
|
else if (_cursor->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-01-13 11:53:51 +00:00
|
|
|
if (_cursor->position().y < SCREEN_EDGES && _ws->yTop >= SCROLL_STEP)
|
2009-12-05 20:51:46 +00:00
|
|
|
_ws->yTop -= SCROLL_STEP;
|
2010-01-13 11:53:51 +00:00
|
|
|
else if (_cursor->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
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 i = 0; i < poly->numPoints; 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,
|
|
|
|
poly->points[(i+1) % poly->numPoints].x - poly->boundingRect.left,
|
|
|
|
poly->points[(i+1) % poly->numPoints].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() {
|
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
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 i = 0; i < poly.numPoints; 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,
|
|
|
|
poly.points[(i+1) % poly.numPoints].x - poly.boundingRect.left,
|
|
|
|
poly.points[(i+1) % poly.numPoints].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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// BARRIER DEBUGGING
|
|
|
|
void Scene::debugShowBarriers() {
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 p = 0; p < _ws->numBarriers; p++) {
|
2009-08-19 21:51:43 +00:00
|
|
|
Graphics::Surface surface;
|
2009-09-19 12:24:53 +00:00
|
|
|
Barrier b = _ws->barriers[p];
|
2009-08-19 21:51:43 +00:00
|
|
|
|
|
|
|
if (b.flags & 0x20) {
|
|
|
|
surface.create(b.boundingRect.right - b.boundingRect.left + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
b.boundingRect.bottom - b.boundingRect.top + 1,
|
|
|
|
1);
|
2009-08-19 21:51:43 +00:00
|
|
|
surface.frameRect(b.boundingRect, 0x22);
|
|
|
|
copyToBackBufferClipped(&surface, b.x, b.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-20 19:21:59 +00:00
|
|
|
// BARRIER DEBUGGING
|
|
|
|
void Scene::debugShowActors() {
|
2009-12-04 03:14:07 +00:00
|
|
|
for (int32 p = 0; p < _ws->numActors; p++) {
|
2009-09-20 19:21:59 +00:00
|
|
|
Graphics::Surface surface;
|
|
|
|
Actor a = _ws->actors[p];
|
|
|
|
|
|
|
|
if (a.flags & 2) {
|
|
|
|
surface.create(a.boundingRect.right - a.boundingRect.left + 1,
|
2009-09-21 19:11:49 +00:00
|
|
|
a.boundingRect.bottom - a.boundingRect.top + 1,
|
|
|
|
1);
|
2009-09-20 19:21:59 +00:00
|
|
|
surface.frameRect(a.boundingRect, 0x22);
|
|
|
|
copyToBackBufferClipped(&surface, a.x, a.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
surface.free();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-25 01:05:23 +00:00
|
|
|
SceneTitle::SceneTitle(Scene *scene): _scene(scene) {
|
2009-11-24 11:46:58 +00:00
|
|
|
_start = _scene->vm()->getTick();
|
2009-09-25 01:05:23 +00:00
|
|
|
|
|
|
|
_bg = new GraphicResource(_scene->_resPack, _scene->_ws->sceneTitleGrResId);
|
|
|
|
_scene->vm()->screen()->setPalette(_scene->_resPack, _scene->_ws->sceneTitlePalResId);
|
|
|
|
|
|
|
|
ResourcePack *pack = new ResourcePack(0x12);
|
|
|
|
_progress = new GraphicResource(pack, 0x80120011);
|
|
|
|
_spinnerProgress = 0;
|
|
|
|
_spinnerFrame = 0;
|
|
|
|
|
|
|
|
_scene->vm()->text()->loadFont(pack, 0x80120012);
|
|
|
|
|
|
|
|
delete pack;
|
|
|
|
|
|
|
|
_done = false;
|
2009-12-01 22:42:11 +00:00
|
|
|
_showMouseState = g_system->showMouse(false);
|
2009-09-25 01:05:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SceneTitle::~SceneTitle() {
|
|
|
|
delete _bg;
|
|
|
|
delete _progress;
|
|
|
|
}
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
void SceneTitle::update(int32 tick) {
|
2009-09-25 01:05:23 +00:00
|
|
|
|
|
|
|
// XXX This is not from the original. It's just some
|
|
|
|
// arbitrary math to throttle the progress indicator.
|
|
|
|
// In the game, the scene loading progress indicated
|
|
|
|
// how far the engine had progressed in terms of buffering
|
|
|
|
// the various scene resource.
|
|
|
|
// Since we don't actually buffer content like the original,
|
|
|
|
// but load on demand from offset/length within a ResourcePack,
|
|
|
|
// the progress indicator is effectively useless.
|
|
|
|
// It's just in here as "eye candy" :P
|
|
|
|
if ((tick - _start) % 500 > 100)
|
|
|
|
_spinnerProgress += 20;
|
|
|
|
|
|
|
|
GraphicFrame *bgFrame = _bg->getFrame(0);
|
|
|
|
|
|
|
|
_scene->vm()->screen()->copyToBackBuffer(
|
|
|
|
((byte *)bgFrame->surface.pixels),
|
|
|
|
bgFrame->surface.w,
|
|
|
|
0, 0, 640, 480);
|
|
|
|
|
2009-12-04 03:14:07 +00:00
|
|
|
int32 resId = _scene->getSceneIndex() - 4 + 1811;
|
|
|
|
int32 resWidth = _scene->vm()->text()->getResTextWidth(resId);
|
2009-09-25 01:05:23 +00:00
|
|
|
_scene->vm()->text()->drawResTextCentered(320 - resWidth * 24, 30, resWidth, resId);
|
|
|
|
|
|
|
|
GraphicFrame *frame = _progress->getFrame(_spinnerFrame);
|
|
|
|
|
|
|
|
_scene->vm()->screen()->copyRectToScreenWithTransparency(
|
|
|
|
((byte*)frame->surface.pixels),
|
|
|
|
frame->surface.w,
|
|
|
|
frame->x - 290 + _spinnerProgress,
|
|
|
|
frame->y,
|
|
|
|
frame->surface.w,
|
|
|
|
frame->surface.h);
|
|
|
|
|
|
|
|
_spinnerFrame++;
|
|
|
|
|
|
|
|
if (_spinnerFrame > _progress->getFrameCount() - 1)
|
|
|
|
_spinnerFrame = 0;
|
|
|
|
|
2009-12-01 22:42:11 +00:00
|
|
|
if (_spinnerProgress > 590) {
|
2009-09-25 01:05:23 +00:00
|
|
|
_done = true;
|
2009-12-01 22:42:11 +00:00
|
|
|
g_system->showMouse(_showMouseState);
|
|
|
|
}
|
2009-09-25 01:05:23 +00:00
|
|
|
}
|
|
|
|
|
2009-08-04 13:27:04 +00:00
|
|
|
} // end of namespace Asylum
|