2009-09-03 20:59:17 +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.
|
|
|
|
*
|
2009-09-03 21:20:13 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2009-09-03 20:59:17 +00:00
|
|
|
*/
|
|
|
|
|
2009-09-04 20:08:33 +00:00
|
|
|
#include "teenagent/scene.h"
|
|
|
|
#include "teenagent/resources.h"
|
|
|
|
#include "teenagent/surface.h"
|
2009-09-03 20:59:17 +00:00
|
|
|
#include "common/debug.h"
|
2009-09-04 20:08:33 +00:00
|
|
|
#include "teenagent/objects.h"
|
|
|
|
#include "teenagent/teenagent.h"
|
|
|
|
#include "teenagent/dialog.h"
|
|
|
|
#include "teenagent/music.h"
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-04 20:08:33 +00:00
|
|
|
namespace TeenAgent {
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-15 08:54:06 +00:00
|
|
|
Scene::Scene() : intro(false), _engine(NULL),
|
|
|
|
_system(NULL),
|
2009-09-26 15:04:09 +00:00
|
|
|
_id(0), ons(0),
|
2009-09-15 20:21:18 +00:00
|
|
|
orientation(Object::kActorRight),
|
|
|
|
current_event(SceneEvent::kNone), hide_actor(false) {}
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-15 08:54:06 +00:00
|
|
|
void Scene::warp(const Common::Point &_point, byte o) {
|
2009-09-03 20:59:17 +00:00
|
|
|
Common::Point point(_point);
|
2009-09-15 08:54:06 +00:00
|
|
|
destination = position = position0 = point;
|
|
|
|
progress = 0;
|
|
|
|
progress_total = 1;
|
2009-09-03 20:59:17 +00:00
|
|
|
if (o)
|
|
|
|
orientation = o;
|
|
|
|
}
|
|
|
|
|
2009-09-15 08:54:06 +00:00
|
|
|
void Scene::moveTo(const Common::Point &_point, byte orient, bool validate) {
|
2009-09-03 20:59:17 +00:00
|
|
|
Common::Point point(_point);
|
|
|
|
debug(0, "moveTo(%d, %d, %u)", point.x, point.y, orient);
|
|
|
|
if (validate) {
|
2009-09-26 15:04:09 +00:00
|
|
|
const Common::Array<Walkbox> &scene_walkboxes = walkboxes[_id - 1];
|
|
|
|
for (byte i = 0; i < scene_walkboxes.size(); ++i) {
|
|
|
|
const Walkbox &w = scene_walkboxes[i];
|
|
|
|
if (w.rect.in(point)) {
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "bumped into walkbox %u", i);
|
2009-09-26 15:04:09 +00:00
|
|
|
byte o = w.orientation;
|
2009-09-15 08:54:06 +00:00
|
|
|
switch (o) {
|
2009-09-08 19:24:20 +00:00
|
|
|
case 1:
|
2009-09-26 15:04:09 +00:00
|
|
|
point.y = w.rect.top - 1;
|
2009-09-08 19:24:20 +00:00
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
case 2:
|
2009-09-26 15:04:09 +00:00
|
|
|
point.x = w.rect.right + 1;
|
2009-09-08 19:24:20 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2009-09-26 15:04:09 +00:00
|
|
|
point.y = w.rect.bottom + 1;
|
2009-09-08 19:24:20 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2009-09-26 15:04:09 +00:00
|
|
|
point.x = w.rect.left - 1;
|
2009-09-08 19:24:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (point == position) {
|
|
|
|
if (orient != 0)
|
|
|
|
orientation = orient;
|
|
|
|
nextEvent();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
destination = point;
|
|
|
|
orientation = orient;
|
2009-09-15 08:54:06 +00:00
|
|
|
position0 = position;
|
|
|
|
progress_total = 1 + (int)(sqrt((float)position.sqrDist(destination)) / 10);
|
2009-09-03 20:59:17 +00:00
|
|
|
progress = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
void Scene::init(TeenAgentEngine *engine, OSystem *system) {
|
2009-09-03 20:59:17 +00:00
|
|
|
_engine = engine;
|
|
|
|
_system = system;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
|
|
|
Common::SeekableReadStream *s = res->varia.getStream(1);
|
2009-09-03 20:59:17 +00:00
|
|
|
if (s == NULL)
|
|
|
|
error("invalid resource data");
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
teenagent.load(s, Animation::kTypeVaria);
|
2009-09-09 20:42:44 +00:00
|
|
|
if (teenagent.empty())
|
|
|
|
error("invalid mark animation");
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
s = res->varia.getStream(2);
|
|
|
|
if (s == NULL)
|
|
|
|
error("invalid resource data");
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
teenagent_idle.load(s, Animation::kTypeVaria);
|
2009-09-09 20:42:44 +00:00
|
|
|
if (teenagent_idle.empty())
|
|
|
|
error("invalid mark animation");
|
2009-09-26 15:04:09 +00:00
|
|
|
|
|
|
|
//loading objects & walkboxes
|
|
|
|
objects.resize(42);
|
|
|
|
walkboxes.resize(42);
|
|
|
|
|
2009-09-30 16:16:53 +00:00
|
|
|
for (byte i = 0; i < 42; ++i) {
|
2009-09-26 15:04:09 +00:00
|
|
|
Common::Array<Object> &scene_objects = objects[i];
|
|
|
|
scene_objects.clear();
|
|
|
|
|
|
|
|
uint16 scene_table = res->dseg.get_word(0x7254 + i * 2);
|
|
|
|
uint16 object_addr;
|
|
|
|
while ((object_addr = res->dseg.get_word(scene_table)) != 0) {
|
|
|
|
Object obj;
|
|
|
|
obj.load(res->dseg.ptr(object_addr));
|
|
|
|
//obj.dump();
|
|
|
|
scene_objects.push_back(obj);
|
|
|
|
scene_table += 2;
|
|
|
|
}
|
|
|
|
debug(0, "scene[%u] has %u object(s)", i + 1, scene_objects.size());
|
|
|
|
|
|
|
|
byte *walkboxes_base = res->dseg.ptr(READ_LE_UINT16(res->dseg.ptr(0x6746 + i * 2)));
|
|
|
|
byte walkboxes_n = *walkboxes_base++;
|
|
|
|
debug(0, "scene[%u] has %u walkboxes", i + 1, walkboxes_n);
|
|
|
|
|
|
|
|
Common::Array<Walkbox> &scene_walkboxes = walkboxes[i];
|
|
|
|
for (byte j = 0; j < walkboxes_n; ++j) {
|
|
|
|
Walkbox w;
|
|
|
|
w.load(walkboxes_base + 14 * j);
|
|
|
|
//walkbox[i]->dump();
|
|
|
|
scene_walkboxes.push_back(w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Object *Scene::findObject(const Common::Point &point) {
|
|
|
|
if (_id == 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
Common::Array<Object> &scene_objects = objects[_id - 1];
|
|
|
|
|
2009-09-30 16:16:53 +00:00
|
|
|
for (uint i = 0; i < scene_objects.size(); ++i) {
|
2009-09-26 15:04:09 +00:00
|
|
|
Object &obj = scene_objects[i];
|
|
|
|
if (obj.enabled != 0 && obj.rect.in(point))
|
|
|
|
return &obj;
|
|
|
|
}
|
|
|
|
return NULL;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
2009-09-26 15:04:09 +00:00
|
|
|
|
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
byte *Scene::getOns(int id) {
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
return res->dseg.ptr(res->dseg.get_word(0xb4f5 + (id - 1) * 2));
|
|
|
|
}
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
byte *Scene::getLans(int id) {
|
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
return res->dseg.ptr(0xd89e + (id - 1) * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::loadOns() {
|
|
|
|
debug(0, "loading ons animation");
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
|
|
|
|
uint16 addr = res->dseg.get_word(0xb4f5 + (_id - 1) * 2);
|
|
|
|
//debug(0, "ons index: %04x", addr);
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
ons_count = 0;
|
|
|
|
byte b;
|
|
|
|
byte on_id[16];
|
2009-09-04 20:09:29 +00:00
|
|
|
while ((b = res->dseg.get_byte(addr)) != 0xff) {
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "on: %04x = %02x", addr, b);
|
|
|
|
++addr;
|
|
|
|
if (b == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
on_id[ons_count++] = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] ons;
|
|
|
|
ons = NULL;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
if (ons_count > 0) {
|
|
|
|
ons = new Surface[ons_count];
|
2009-09-04 20:09:29 +00:00
|
|
|
for (uint32 i = 0; i < ons_count; ++i) {
|
2009-09-15 07:41:05 +00:00
|
|
|
Common::SeekableReadStream *s = res->ons.getStream(on_id[i]);
|
2009-09-03 20:59:17 +00:00
|
|
|
if (s != NULL)
|
2009-09-15 20:21:18 +00:00
|
|
|
ons[i].load(s, Surface::kTypeOns);
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::loadLans() {
|
|
|
|
debug(0, "loading lans animation");
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
//load lan000
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 22:34:08 +00:00
|
|
|
for (byte i = 0; i < 4; ++i) {
|
2009-09-15 19:21:45 +00:00
|
|
|
animation[i].free();
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
uint16 bx = 0xd89e + (_id - 1) * 4 + i;
|
|
|
|
byte bxv = res->dseg.get_byte(bx);
|
2009-09-14 21:05:43 +00:00
|
|
|
uint16 res_id = 4 * (_id - 1) + i + 1;
|
2009-09-15 22:34:08 +00:00
|
|
|
debug(0, "lan[%u]@%04x = %02x, resource id: %u", i, bx, bxv, res_id);
|
2009-09-03 20:59:17 +00:00
|
|
|
if (bxv == 0)
|
|
|
|
continue;
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Common::SeekableReadStream *s = res->loadLan000(res_id);
|
2009-09-03 20:59:17 +00:00
|
|
|
if (s != NULL) {
|
2009-09-15 20:21:18 +00:00
|
|
|
animation[i].load(s, Animation::kTypeLan);
|
2009-09-15 08:54:06 +00:00
|
|
|
if (bxv != 0 && bxv != 0xff)
|
2009-09-15 19:21:45 +00:00
|
|
|
animation[i].id = bxv;
|
2009-09-03 20:59:17 +00:00
|
|
|
delete s;
|
|
|
|
}
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
//uint16 bp = res->dseg.get_word();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::init(int id, const Common::Point &pos) {
|
|
|
|
debug(0, "init(%d)", id);
|
|
|
|
_id = id;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
if (background.pixels == NULL)
|
|
|
|
background.create(320, 200, 1);
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
warp(pos);
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
res->loadOff(background, palette, id);
|
|
|
|
if (id == 24) {
|
|
|
|
//dark scene
|
|
|
|
if (res->dseg.get_byte(0xDBA4) != 1) {
|
|
|
|
//dim down palette
|
|
|
|
uint i;
|
2009-09-04 20:09:29 +00:00
|
|
|
for (i = 0; i < 624; ++i) {
|
2009-09-15 08:54:06 +00:00
|
|
|
palette[i] = palette[i] > 0x20 ? palette[i] - 0x20 : 0;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
2009-09-04 20:09:29 +00:00
|
|
|
for (i = 726; i < 768; ++i) {
|
2009-09-15 08:54:06 +00:00
|
|
|
palette[i] = palette[i] > 0x20 ? palette[i] - 0x20 : 0;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setPalette(_system, palette, 4);
|
|
|
|
|
|
|
|
Common::SeekableReadStream *stream = res->on.getStream(id);
|
2009-09-15 20:21:18 +00:00
|
|
|
on.load(stream, Surface::kTypeOn);
|
2009-09-03 20:59:17 +00:00
|
|
|
delete stream;
|
|
|
|
|
|
|
|
loadOns();
|
|
|
|
loadLans();
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-08 14:26:14 +00:00
|
|
|
//check music
|
|
|
|
int now_playing = _engine->music->getId();
|
2009-09-15 08:54:06 +00:00
|
|
|
|
|
|
|
if (now_playing != res->dseg.get_byte(0xDB90))
|
2009-09-08 14:26:14 +00:00
|
|
|
_engine->music->load(res->dseg.get_byte(0xDB90));
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 22:23:35 +00:00
|
|
|
void Scene::playAnimation(byte idx, uint id, bool loop, bool paused) {
|
2009-09-09 20:42:44 +00:00
|
|
|
assert(idx < 4);
|
2009-09-15 07:41:05 +00:00
|
|
|
Common::SeekableReadStream *s = Resources::instance()->loadLan(id + 1);
|
2009-09-03 20:59:17 +00:00
|
|
|
if (s == NULL)
|
|
|
|
error("playing animation %u failed", id);
|
|
|
|
|
2009-09-15 19:21:45 +00:00
|
|
|
custom_animation[idx].load(s);
|
|
|
|
custom_animation[idx].loop = loop;
|
|
|
|
custom_animation[idx].paused = paused;
|
2009-09-09 20:42:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::playActorAnimation(uint id, bool loop) {
|
2009-09-15 07:41:05 +00:00
|
|
|
Common::SeekableReadStream *s = Resources::instance()->loadLan(id + 1);
|
2009-09-09 20:42:44 +00:00
|
|
|
if (s == NULL)
|
|
|
|
error("playing animation %u failed", id);
|
|
|
|
|
|
|
|
actor_animation.load(s);
|
|
|
|
actor_animation.loop = loop;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::push(const SceneEvent &event) {
|
|
|
|
//debug(0, "push");
|
|
|
|
//event.dump();
|
|
|
|
events.push_back(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Scene::processEvent(const Common::Event &event) {
|
2009-09-15 08:54:06 +00:00
|
|
|
switch (event.type) {
|
2009-09-13 10:50:29 +00:00
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
2009-09-15 08:54:06 +00:00
|
|
|
case Common::EVENT_RBUTTONDOWN:
|
2009-09-13 10:50:29 +00:00
|
|
|
if (!message.empty()) {
|
2009-09-03 20:59:17 +00:00
|
|
|
message.clear();
|
|
|
|
nextEvent();
|
|
|
|
return true;
|
|
|
|
}
|
2009-09-13 10:50:29 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
case Common::EVENT_KEYUP:
|
|
|
|
if (intro && event.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
|
|
|
intro = false;
|
|
|
|
message.clear();
|
|
|
|
events.clear();
|
|
|
|
sounds.clear();
|
|
|
|
current_event.clear();
|
2009-09-14 21:05:43 +00:00
|
|
|
message_color = 0xd1;
|
2009-09-15 08:54:06 +00:00
|
|
|
for (int i = 0; i < 4; ++i)
|
2009-09-15 19:21:45 +00:00
|
|
|
custom_animation[i].free();
|
2009-09-13 10:50:29 +00:00
|
|
|
_engine->playMusic(4);
|
|
|
|
init(10, Common::Point(136, 153));
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
bool Scene::render(OSystem *system) {
|
2009-09-03 20:59:17 +00:00
|
|
|
//render background
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-15 20:21:18 +00:00
|
|
|
if (current_event.type == SceneEvent::kCreditsMessage) {
|
2009-09-13 09:54:53 +00:00
|
|
|
system->fillScreen(0);
|
2009-09-15 07:41:05 +00:00
|
|
|
Graphics::Surface *surface = system->lockScreen();
|
2009-09-13 09:54:53 +00:00
|
|
|
res->font8.color = current_event.color;
|
|
|
|
res->font8.shadow_color = current_event.orientation;
|
|
|
|
res->font8.render(surface, current_event.dst.x, current_event.dst.y, message);
|
|
|
|
system->unlockScreen();
|
|
|
|
return true;
|
|
|
|
}
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-13 13:59:55 +00:00
|
|
|
bool busy;
|
|
|
|
bool restart;
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-13 13:59:55 +00:00
|
|
|
do {
|
|
|
|
restart = false;
|
|
|
|
busy = processEventQueue();
|
|
|
|
system->copyRectToScreen((const byte *)background.pixels, background.pitch, 0, 0, background.w, background.h);
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Graphics::Surface *surface = system->lockScreen();
|
2009-09-13 13:59:55 +00:00
|
|
|
|
|
|
|
if (ons != NULL) {
|
|
|
|
for (uint32 i = 0; i < ons_count; ++i) {
|
2009-09-15 07:41:05 +00:00
|
|
|
Surface *s = ons + i;
|
2009-09-13 13:59:55 +00:00
|
|
|
if (s != NULL)
|
|
|
|
s->render(surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//render on
|
|
|
|
if (on.pixels != NULL) {
|
|
|
|
on.render(surface);
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
2009-09-09 20:42:44 +00:00
|
|
|
|
2009-09-13 13:59:55 +00:00
|
|
|
bool got_any_animation = false;
|
|
|
|
|
2009-09-15 22:34:08 +00:00
|
|
|
for (byte i = 0; i < 4; ++i) {
|
2009-09-15 19:21:45 +00:00
|
|
|
Animation *a = custom_animation + i;
|
2009-09-13 13:59:55 +00:00
|
|
|
Surface *s = a->currentFrame();
|
|
|
|
if (s != NULL) {
|
2009-09-15 19:21:45 +00:00
|
|
|
animation_position[i] = s->render(surface);
|
2009-09-13 13:59:55 +00:00
|
|
|
busy = true;
|
|
|
|
got_any_animation = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-09-15 19:21:45 +00:00
|
|
|
a = animation + i;
|
2009-09-13 13:59:55 +00:00
|
|
|
s = a->currentFrame();
|
|
|
|
if (s == NULL)
|
|
|
|
continue;
|
2009-09-09 20:42:44 +00:00
|
|
|
|
2009-09-15 19:21:45 +00:00
|
|
|
animation_position[i] = s->render(surface);
|
2009-09-13 13:59:55 +00:00
|
|
|
|
|
|
|
if (a->id == 0)
|
|
|
|
continue;
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Object *obj = getObject(a->id);
|
2009-09-13 13:59:55 +00:00
|
|
|
if (obj != NULL) {
|
|
|
|
obj->rect.left = s->x;
|
|
|
|
obj->rect.top = s->y;
|
|
|
|
obj->rect.right = s->w + s->x;
|
|
|
|
obj->rect.bottom = s->h + s->y;
|
2009-09-27 05:17:00 +00:00
|
|
|
obj->rect.save();
|
2009-09-13 13:59:55 +00:00
|
|
|
//obj->dump();
|
|
|
|
}
|
2009-09-09 20:42:44 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 22:34:08 +00:00
|
|
|
{
|
2009-09-15 07:41:05 +00:00
|
|
|
Surface *mark = actor_animation.currentFrame();
|
2009-09-15 22:34:08 +00:00
|
|
|
if (mark != NULL) {
|
|
|
|
actor_animation_position = mark->render(surface);
|
|
|
|
busy = true;
|
|
|
|
got_any_animation = true;
|
|
|
|
} else if (!hide_actor) {
|
2009-09-13 13:59:55 +00:00
|
|
|
actor_animation.free();
|
|
|
|
|
|
|
|
if (destination != position) {
|
|
|
|
Common::Point dp(destination.x - position0.x, destination.y - position0.y);
|
|
|
|
int o;
|
|
|
|
if (ABS(dp.x) > ABS(dp.y))
|
2009-09-15 20:21:18 +00:00
|
|
|
o = dp.x > 0 ? Object::kActorRight : Object::kActorLeft;
|
2009-09-13 13:59:55 +00:00
|
|
|
else
|
2009-09-15 20:21:18 +00:00
|
|
|
o = dp.y > 0 ? Object::kActorDown : Object::kActorUp;
|
2009-09-13 13:59:55 +00:00
|
|
|
|
|
|
|
position.x = position0.x + dp.x * progress / progress_total;
|
|
|
|
position.y = position0.y + dp.y * progress / progress_total;
|
2009-09-15 19:21:45 +00:00
|
|
|
actor_animation_position = teenagent.render(surface, position, o, 1);
|
2009-09-13 13:59:55 +00:00
|
|
|
++progress;
|
|
|
|
if (progress >= progress_total) {
|
|
|
|
position = destination;
|
|
|
|
if (orientation == 0)
|
|
|
|
orientation = o; //save last orientation
|
|
|
|
nextEvent();
|
2009-09-15 20:57:49 +00:00
|
|
|
got_any_animation = true;
|
2009-09-13 13:59:55 +00:00
|
|
|
restart = true;
|
|
|
|
} else
|
|
|
|
busy = true;
|
|
|
|
} else
|
2009-09-15 20:08:28 +00:00
|
|
|
actor_animation_position = teenagent.render(surface, position, orientation, 0);
|
2009-09-13 13:59:55 +00:00
|
|
|
}
|
2009-09-15 22:34:08 +00:00
|
|
|
}
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-13 13:59:55 +00:00
|
|
|
if (!message.empty()) {
|
2009-09-14 21:05:43 +00:00
|
|
|
res->font7.color = message_color;
|
2009-09-13 13:59:55 +00:00
|
|
|
res->font7.render(surface, message_pos.x, message_pos.y, message);
|
|
|
|
busy = true;
|
|
|
|
}
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-13 13:59:55 +00:00
|
|
|
system->unlockScreen();
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
if (current_event.type == SceneEvent::kWaitForAnimation && !got_any_animation) {
|
2009-09-13 13:59:55 +00:00
|
|
|
debug(0, "no animations, nextevent");
|
|
|
|
nextEvent();
|
|
|
|
restart = true;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
2009-09-13 13:59:55 +00:00
|
|
|
|
|
|
|
//if (!current_event.empty())
|
|
|
|
// current_event.dump();
|
2009-09-26 15:05:47 +00:00
|
|
|
/*
|
2009-09-26 15:04:09 +00:00
|
|
|
{
|
|
|
|
const Common::Array<Walkbox> & scene_walkboxes = walkboxes[_id - 1];
|
|
|
|
for (uint i = 0; i < scene_walkboxes.size(); ++i) {
|
|
|
|
scene_walkboxes[i].rect.render(surface, 0xd0 + i);
|
|
|
|
}
|
2009-09-13 12:48:57 +00:00
|
|
|
}
|
2009-09-26 15:05:47 +00:00
|
|
|
*/
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-15 08:54:06 +00:00
|
|
|
} while (restart);
|
|
|
|
|
|
|
|
for (Sounds::iterator i = sounds.begin(); i != sounds.end();) {
|
2009-09-05 15:04:37 +00:00
|
|
|
Sound &sound = *i;
|
|
|
|
if (sound.delay == 0) {
|
|
|
|
debug(0, "sound %u started", sound.id);
|
|
|
|
_engine->playSoundNow(sound.id);
|
|
|
|
i = sounds.erase(i);
|
|
|
|
} else {
|
|
|
|
--sound.delay;
|
|
|
|
++i;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
return busy;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Scene::processEventQueue() {
|
|
|
|
while (!events.empty() && current_event.empty()) {
|
|
|
|
//debug(0, "processing next event");
|
|
|
|
current_event = events.front();
|
|
|
|
events.pop_front();
|
2009-09-15 08:54:06 +00:00
|
|
|
switch (current_event.type) {
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kSetOn: {
|
2009-09-15 08:54:06 +00:00
|
|
|
byte *ptr = getOns(current_event.scene == 0 ? _id : current_event.scene);
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "on[%u] = %02x", current_event.ons - 1, current_event.color);
|
|
|
|
ptr[current_event.ons - 1] = current_event.color;
|
|
|
|
loadOns();
|
|
|
|
current_event.clear();
|
2009-09-15 08:54:06 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kSetLan: {
|
2009-09-03 20:59:17 +00:00
|
|
|
if (current_event.lan != 0) {
|
|
|
|
debug(0, "lan[%u] = %02x", current_event.lan - 1, current_event.color);
|
2009-09-15 08:54:06 +00:00
|
|
|
byte *ptr = getLans(current_event.scene == 0 ? _id : current_event.scene);
|
2009-09-03 20:59:17 +00:00
|
|
|
ptr[current_event.lan - 1] = current_event.color;
|
|
|
|
}
|
|
|
|
loadLans();
|
|
|
|
current_event.clear();
|
2009-09-15 08:54:06 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kLoadScene: {
|
2009-09-03 20:59:17 +00:00
|
|
|
init(current_event.scene, current_event.dst);
|
2009-09-05 17:15:28 +00:00
|
|
|
sounds.clear();
|
2009-09-03 20:59:17 +00:00
|
|
|
current_event.clear();
|
2009-09-15 08:54:06 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kWalk: {
|
2009-09-05 17:15:28 +00:00
|
|
|
Common::Point dst = current_event.dst;
|
|
|
|
if ((current_event.color & 2) != 0) { //relative move
|
|
|
|
dst.x += position.x;
|
|
|
|
dst.y += position.y;
|
|
|
|
}
|
|
|
|
if ((current_event.color & 1) != 0) {
|
|
|
|
warp(dst, current_event.orientation);
|
2009-09-03 20:59:17 +00:00
|
|
|
current_event.clear();
|
|
|
|
} else
|
2009-09-05 17:15:28 +00:00
|
|
|
moveTo(dst, current_event.orientation);
|
2009-09-15 08:54:06 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kCreditsMessage:
|
|
|
|
case SceneEvent::kMessage: {
|
2009-09-15 20:08:28 +00:00
|
|
|
message = current_event.message;
|
|
|
|
Common::Point p(
|
|
|
|
(actor_animation_position.left + actor_animation_position.right) / 2,
|
|
|
|
actor_animation_position.top
|
|
|
|
);
|
|
|
|
//FIXME: rewrite it:
|
|
|
|
if (current_event.lan < 4) {
|
2009-09-15 20:21:18 +00:00
|
|
|
const Surface *s = custom_animation[current_event.lan].currentFrame(0);
|
2009-09-15 20:08:28 +00:00
|
|
|
if (s == NULL)
|
|
|
|
s = animation[current_event.lan].currentFrame(0);
|
|
|
|
if (s != NULL) {
|
|
|
|
p.x = s->x + s->w / 2;
|
|
|
|
p.y = s->y;
|
|
|
|
} else
|
|
|
|
warning("no animation in slot %u", current_event.lan);
|
|
|
|
}
|
|
|
|
message_pos = messagePosition(message, p);
|
|
|
|
message_color = current_event.color;
|
|
|
|
}
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kPlayAnimation:
|
2009-09-15 20:08:28 +00:00
|
|
|
debug(0, "playing animation %u in slot %u", current_event.animation, current_event.lan & 3);
|
2009-09-15 22:34:08 +00:00
|
|
|
playAnimation(current_event.lan & 3, current_event.animation, (current_event.lan & 0x80) != 0, (current_event.lan & 0x40) != 0);
|
2009-09-09 20:42:44 +00:00
|
|
|
current_event.clear();
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
2009-09-09 20:42:44 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kPauseAnimation:
|
2009-09-15 20:08:28 +00:00
|
|
|
debug(0, "pause animation in slot %u", current_event.lan & 3);
|
2009-09-15 19:21:45 +00:00
|
|
|
custom_animation[current_event.lan & 3].paused = (current_event.lan & 0x80) != 0;
|
2009-09-09 20:42:44 +00:00
|
|
|
current_event.clear();
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kClearAnimations:
|
2009-09-15 08:54:06 +00:00
|
|
|
for (byte i = 0; i < 4; ++i)
|
2009-09-15 19:21:45 +00:00
|
|
|
custom_animation[i].free();
|
2009-09-14 22:23:35 +00:00
|
|
|
current_event.clear();
|
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kPlayActorAnimation:
|
2009-09-14 22:23:35 +00:00
|
|
|
debug(0, "playing actor animation %u", current_event.animation);
|
2009-09-15 19:21:45 +00:00
|
|
|
playActorAnimation(current_event.animation, (current_event.lan & 0x80) != 0);
|
2009-09-14 22:23:35 +00:00
|
|
|
current_event.clear();
|
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kPlayMusic:
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "setting music %u", current_event.music);
|
|
|
|
_engine->setMusic(current_event.music);
|
|
|
|
Resources::instance()->dseg.set_byte(0xDB90, current_event.music);
|
|
|
|
current_event.clear();
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kPlaySound:
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "playing sound %u, delay: %u", current_event.sound, current_event.color);
|
2009-09-15 19:21:45 +00:00
|
|
|
sounds.push_back(Sound(current_event.sound, current_event.color));
|
2009-09-03 20:59:17 +00:00
|
|
|
current_event.clear();
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kEnableObject: {
|
2009-09-15 08:54:06 +00:00
|
|
|
debug(0, "%s object #%u", current_event.color ? "enabling" : "disabling", current_event.object - 1);
|
|
|
|
Object *obj = getObject(current_event.object - 1, current_event.scene == 0 ? _id : current_event.scene);
|
|
|
|
obj->enabled = current_event.color;
|
2009-09-27 05:17:00 +00:00
|
|
|
obj->save();
|
2009-09-15 08:54:06 +00:00
|
|
|
current_event.clear();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kHideActor:
|
2009-09-13 12:48:57 +00:00
|
|
|
hide_actor = current_event.color != 0;
|
|
|
|
current_event.clear();
|
2009-09-14 22:23:35 +00:00
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kWaitForAnimation:
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "waiting for the animation");
|
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-15 20:21:18 +00:00
|
|
|
case SceneEvent::kQuit:
|
2009-09-07 22:47:50 +00:00
|
|
|
debug(0, "quit!");
|
|
|
|
_engine->quitGame();
|
|
|
|
break;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
|
|
|
default:
|
2009-09-03 20:59:17 +00:00
|
|
|
error("empty/unhandler event[%d]", (int)current_event.type);
|
|
|
|
}
|
|
|
|
}
|
2009-09-13 12:48:57 +00:00
|
|
|
if (events.empty()) {
|
2009-09-14 21:05:43 +00:00
|
|
|
message_color = 0xd1;
|
2009-09-13 12:48:57 +00:00
|
|
|
hide_actor = false;
|
|
|
|
}
|
2009-09-03 20:59:17 +00:00
|
|
|
return !current_event.empty();
|
|
|
|
}
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
void Scene::setPalette(OSystem *system, const byte *buf, unsigned mul) {
|
2009-09-03 20:59:17 +00:00
|
|
|
byte p[1024];
|
|
|
|
|
|
|
|
memset(p, 0, 1024);
|
2009-09-04 20:09:29 +00:00
|
|
|
for (int i = 0; i < 256; ++i) {
|
2009-09-15 08:54:06 +00:00
|
|
|
for (int c = 0; c < 3; ++c)
|
2009-09-03 20:59:17 +00:00
|
|
|
p[i * 4 + c] = buf[i * 3 + c] * mul;
|
|
|
|
}
|
|
|
|
|
|
|
|
system->setPalette(p, 0, 256);
|
|
|
|
}
|
|
|
|
|
2009-09-15 07:41:05 +00:00
|
|
|
Object *Scene::getObject(int id, int scene_id) {
|
2009-09-26 15:04:09 +00:00
|
|
|
assert(id > 0);
|
|
|
|
|
2009-09-03 20:59:17 +00:00
|
|
|
if (scene_id == 0)
|
|
|
|
scene_id = _id;
|
2009-09-15 08:54:06 +00:00
|
|
|
|
2009-09-26 15:04:09 +00:00
|
|
|
if (scene_id == 0)
|
|
|
|
return NULL;
|
2009-09-03 20:59:17 +00:00
|
|
|
|
2009-09-26 15:04:09 +00:00
|
|
|
return &objects[scene_id - 1][id - 1];
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 20:08:28 +00:00
|
|
|
Common::Point Scene::messagePosition(const Common::String &str, Common::Point position) {
|
2009-09-15 07:41:05 +00:00
|
|
|
Resources *res = Resources::instance();
|
2009-09-03 20:59:17 +00:00
|
|
|
uint w = res->font7.render(NULL, 0, 0, str);
|
2009-09-15 20:08:28 +00:00
|
|
|
position.x -= w / 2;
|
|
|
|
position.y -= res->font7.height + 3;
|
|
|
|
if (position.x + w > 320)
|
|
|
|
position.x = 320 - w;
|
|
|
|
if (position.x < 0)
|
|
|
|
position.x = 0;
|
|
|
|
|
|
|
|
return position;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 21:05:43 +00:00
|
|
|
void Scene::displayMessage(const Common::String &str, byte color) {
|
2009-09-03 20:59:17 +00:00
|
|
|
debug(0, "displayMessage: %s", str.c_str());
|
|
|
|
message = str;
|
|
|
|
message_pos = messagePosition(str, position);
|
2009-09-14 21:05:43 +00:00
|
|
|
message_color = color;
|
2009-09-03 20:59:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::clear() {
|
|
|
|
events.clear();
|
|
|
|
current_event.clear();
|
|
|
|
}
|
2009-09-04 20:08:33 +00:00
|
|
|
|
|
|
|
} // End of namespace TeenAgent
|