2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
2007-05-30 21:56:52 +00:00
|
|
|
* 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.
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
|
|
|
* 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
|
2008-01-05 12:45:14 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2004-04-12 21:40:49 +00:00
|
|
|
* 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
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Event management module
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/saga.h"
|
|
|
|
#include "saga/gfx.h"
|
|
|
|
|
|
|
|
#include "saga/animation.h"
|
2004-08-10 18:31:33 +00:00
|
|
|
#include "saga/console.h"
|
2004-08-04 20:28:57 +00:00
|
|
|
#include "saga/scene.h"
|
2004-08-06 01:39:17 +00:00
|
|
|
#include "saga/interface.h"
|
2004-08-10 19:20:33 +00:00
|
|
|
#include "saga/palanim.h"
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/render.h"
|
|
|
|
#include "saga/sndres.h"
|
2008-12-22 14:13:15 +00:00
|
|
|
#include "saga/resource.h"
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/music.h"
|
2004-12-24 12:47:16 +00:00
|
|
|
#include "saga/actor.h"
|
2004-08-02 16:20:35 +00:00
|
|
|
|
|
|
|
#include "saga/events.h"
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
namespace Saga {
|
|
|
|
|
2008-12-04 21:25:44 +00:00
|
|
|
Events::Events(SagaEngine *vm) : _vm(vm) {
|
2005-07-05 16:58:36 +00:00
|
|
|
debug(8, "Initializing event subsystem...");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2009-11-02 21:54:57 +00:00
|
|
|
Events::~Events() {
|
2005-07-05 16:58:36 +00:00
|
|
|
debug(8, "Shutting down event subsystem...");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-07-29 17:58:00 +00:00
|
|
|
// Function to process event list once per frame.
|
2004-05-01 06:50:20 +00:00
|
|
|
// First advances event times, then processes each event with the appropriate
|
2005-10-11 17:39:31 +00:00
|
|
|
// handler depending on the type of event.
|
2010-10-23 23:07:10 +00:00
|
|
|
void Events::handleEvents(long msec) {
|
2004-04-12 21:40:49 +00:00
|
|
|
long delta_time;
|
|
|
|
int result;
|
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Advance event times
|
2004-08-10 19:00:30 +00:00
|
|
|
processEventTime(msec);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Process each event in list
|
2004-12-15 00:24:12 +00:00
|
|
|
for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
|
2010-10-23 23:07:10 +00:00
|
|
|
Event *event_p = &eventi->front();
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Call the appropriate event handler for the specific event type
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event_p->type) {
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTOneshot:
|
2004-08-10 19:00:30 +00:00
|
|
|
result = handleOneShot(event_p);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTContinuous:
|
2004-08-10 19:00:30 +00:00
|
|
|
result = handleContinuous(event_p);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTInterval:
|
2004-08-10 19:00:30 +00:00
|
|
|
result = handleInterval(event_p);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTImmediate:
|
2004-08-11 22:27:39 +00:00
|
|
|
result = handleImmediate(event_p);
|
|
|
|
break;
|
|
|
|
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
2005-08-10 15:31:15 +00:00
|
|
|
result = kEvStInvalidCode;
|
2004-05-05 13:05:45 +00:00
|
|
|
warning("Invalid event code encountered");
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-07-29 17:58:00 +00:00
|
|
|
// Process the event appropriately based on result code from
|
2004-05-01 06:50:20 +00:00
|
|
|
// handler
|
2005-08-10 15:31:15 +00:00
|
|
|
if ((result == kEvStDelete) || (result == kEvStInvalidCode)) {
|
2004-05-01 06:50:20 +00:00
|
|
|
// If there is no event chain, delete the base event.
|
2010-10-23 23:07:10 +00:00
|
|
|
if (eventi->size() < 2) {
|
2009-04-11 00:28:49 +00:00
|
|
|
eventi = _eventList.reverse_erase(eventi);
|
2004-04-12 21:40:49 +00:00
|
|
|
} else {
|
2005-07-29 17:58:00 +00:00
|
|
|
// If there is an event chain present, move the next event
|
|
|
|
// in the chain up, adjust it by the previous delta time,
|
2005-10-11 17:39:31 +00:00
|
|
|
// and reprocess the event
|
2004-04-12 21:40:49 +00:00
|
|
|
delta_time = event_p->time;
|
2010-10-23 23:07:10 +00:00
|
|
|
eventi->pop_front();
|
|
|
|
event_p = &eventi->front();
|
2004-04-12 21:40:49 +00:00
|
|
|
event_p->time += delta_time;
|
2004-12-15 00:24:12 +00:00
|
|
|
--eventi;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-08-10 15:31:15 +00:00
|
|
|
} else if (result == kEvStBreak) {
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-05-01 06:50:20 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 14:11:22 +00:00
|
|
|
int Events::handleContinuous(Event *event) {
|
2004-05-01 06:50:20 +00:00
|
|
|
double event_pc = 0.0; // Event completion percentage
|
2004-04-12 21:40:49 +00:00
|
|
|
int event_done = 0;
|
|
|
|
|
2005-07-08 16:56:03 +00:00
|
|
|
BGInfo bgInfo;
|
2005-07-09 17:11:41 +00:00
|
|
|
Rect rect;
|
2006-07-14 13:33:58 +00:00
|
|
|
if (event->duration != 0) {
|
|
|
|
event_pc = ((double)event->duration - event->time) / event->duration;
|
2005-07-09 23:07:46 +00:00
|
|
|
} else {
|
|
|
|
event_pc = 1.0;
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
if (event_pc >= 1.0) {
|
2004-05-01 06:50:20 +00:00
|
|
|
// Cap percentage to 100
|
2004-04-12 21:40:49 +00:00
|
|
|
event_pc = 1.0;
|
|
|
|
event_done = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_pc < 0.0) {
|
2004-05-01 06:50:20 +00:00
|
|
|
// Event not signaled, skip it
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStContinue;
|
|
|
|
} else if (!(event->code & kEvFSignaled)) {
|
2004-05-01 06:50:20 +00:00
|
|
|
// Signal event
|
2005-08-10 15:31:15 +00:00
|
|
|
event->code |= kEvFSignaled;
|
2004-04-12 21:40:49 +00:00
|
|
|
event_pc = 0.0;
|
|
|
|
}
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
switch (event->code & EVENT_MASK) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kPalEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventBlackToPal:
|
2005-10-05 01:40:55 +00:00
|
|
|
_vm->_gfx->blackToPal((PalEntry *)event->data, event_pc);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventPalToBlack:
|
2005-10-05 01:40:55 +00:00
|
|
|
_vm->_gfx->palToBlack((PalEntry *)event->data, event_pc);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#ifdef ENABLE_IHNM
|
2007-08-23 13:56:25 +00:00
|
|
|
case kEventPalFade:
|
|
|
|
_vm->_gfx->palFade((PalEntry *)event->data, event->param, event->param2, event->param3, event->param4, event_pc);
|
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#endif
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
2004-05-01 06:50:20 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kTransitionEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventDissolve:
|
2005-07-08 16:56:03 +00:00
|
|
|
_vm->_scene->getBGInfo(bgInfo);
|
2005-07-09 17:11:41 +00:00
|
|
|
rect.left = rect.top = 0;
|
|
|
|
rect.right = bgInfo.bounds.width();
|
|
|
|
rect.bottom = bgInfo.bounds.height();
|
2008-12-06 13:35:27 +00:00
|
|
|
_vm->_render->getBackGroundSurface()->transitionDissolve(bgInfo.buffer, rect, 0, event_pc);
|
2008-12-12 14:23:02 +00:00
|
|
|
_vm->_render->setFullRefresh(true);
|
2004-08-10 23:04:52 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventDissolveBGMask:
|
2004-08-10 23:04:52 +00:00
|
|
|
// we dissolve it centered.
|
|
|
|
// set flag of Dissolve to 1. It is a hack to simulate zero masking.
|
|
|
|
int w, h;
|
2005-07-09 17:11:41 +00:00
|
|
|
byte *maskBuffer;
|
2004-08-10 23:04:52 +00:00
|
|
|
|
2010-10-23 21:56:16 +00:00
|
|
|
_vm->_scene->getBGMaskInfo(w, h, maskBuffer);
|
2008-12-22 14:36:58 +00:00
|
|
|
rect.left = (_vm->getDisplayInfo().width - w) / 2;
|
|
|
|
rect.top = (_vm->getDisplayInfo().height - h) / 2;
|
2005-07-09 17:11:41 +00:00
|
|
|
rect.setWidth(w);
|
|
|
|
rect.setHeight(h);
|
2005-07-29 17:58:00 +00:00
|
|
|
|
2008-12-06 13:35:27 +00:00
|
|
|
_vm->_render->getBackGroundSurface()->transitionDissolve( maskBuffer, rect, 1, event_pc);
|
2008-12-12 14:23:02 +00:00
|
|
|
_vm->_render->setFullRefresh(true);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
if (event_done) {
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStDelete;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStContinue;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 14:11:22 +00:00
|
|
|
int Events::handleImmediate(Event *event) {
|
2004-08-11 22:27:39 +00:00
|
|
|
double event_pc = 0.0; // Event completion percentage
|
|
|
|
bool event_done = false;
|
|
|
|
|
2005-07-09 23:07:46 +00:00
|
|
|
// Duration might be 0 so dont do division then
|
2006-07-14 13:33:58 +00:00
|
|
|
if (event->duration != 0) {
|
|
|
|
event_pc = ((double)event->duration - event->time) / event->duration;
|
2005-07-09 23:07:46 +00:00
|
|
|
} else {
|
|
|
|
// Just make sure that event_pc is 1.0 so event_done is true
|
|
|
|
event_pc = 1.0;
|
|
|
|
}
|
2004-08-11 22:27:39 +00:00
|
|
|
|
|
|
|
if (event_pc >= 1.0) {
|
|
|
|
// Cap percentage to 100
|
|
|
|
event_pc = 1.0;
|
|
|
|
event_done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_pc < 0.0) {
|
|
|
|
// Event not signaled, skip it
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStBreak;
|
|
|
|
} else if (!(event->code & kEvFSignaled)) {
|
2004-08-11 22:27:39 +00:00
|
|
|
// Signal event
|
2005-08-10 15:31:15 +00:00
|
|
|
event->code |= kEvFSignaled;
|
2004-08-11 22:27:39 +00:00
|
|
|
event_pc = 0.0;
|
|
|
|
}
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
switch (event->code & EVENT_MASK) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kPalEvent:
|
2004-08-11 22:27:39 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventBlackToPal:
|
2005-10-05 01:40:55 +00:00
|
|
|
_vm->_gfx->blackToPal((PalEntry *)event->data, event_pc);
|
2004-08-11 22:27:39 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventPalToBlack:
|
2005-10-05 01:40:55 +00:00
|
|
|
_vm->_gfx->palToBlack((PalEntry *)event->data, event_pc);
|
2004-08-11 22:27:39 +00:00
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#ifdef ENABLE_IHNM
|
2007-08-23 13:56:25 +00:00
|
|
|
case kEventPalFade:
|
|
|
|
_vm->_gfx->palFade((PalEntry *)event->data, event->param, event->param2, event->param3, event->param4, event_pc);
|
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#endif
|
2004-08-11 22:27:39 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kScriptEvent:
|
|
|
|
case kBgEvent:
|
|
|
|
case kInterfaceEvent:
|
2007-06-16 14:06:17 +00:00
|
|
|
case kSceneEvent:
|
|
|
|
case kAnimEvent:
|
|
|
|
case kCutawayEvent:
|
2007-08-25 16:01:42 +00:00
|
|
|
case kActorEvent:
|
2004-08-11 22:27:39 +00:00
|
|
|
handleOneShot(event);
|
|
|
|
event_done = true;
|
|
|
|
break;
|
|
|
|
default:
|
2007-06-16 14:06:17 +00:00
|
|
|
warning("Unhandled Immediate event type (%d)", event->code & EVENT_MASK);
|
2004-08-11 22:27:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_done) {
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStDelete;
|
2004-08-11 22:27:39 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStBreak;
|
2004-08-11 22:27:39 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 14:11:22 +00:00
|
|
|
int Events::handleOneShot(Event *event) {
|
2005-01-06 16:07:46 +00:00
|
|
|
Rect rect;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (event->time > 0) {
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStContinue;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Event has been signaled
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
switch (event->code & EVENT_MASK) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kTextEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventDisplay:
|
2005-07-19 19:05:52 +00:00
|
|
|
((TextListEntry *)event->data)->display = true;
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2010-03-10 20:33:38 +00:00
|
|
|
case kEventRemove: {
|
|
|
|
TextListEntry entry = *((TextListEntry *)event->data);
|
|
|
|
_vm->_scene->_textList.remove(entry);
|
|
|
|
} break;
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kSoundEvent:
|
2004-11-26 13:28:00 +00:00
|
|
|
_vm->_sound->stopSound();
|
2005-08-10 15:31:15 +00:00
|
|
|
if (event->op == kEventPlay)
|
2004-11-26 13:28:00 +00:00
|
|
|
_vm->_sndRes->playSound(event->param, event->param2, event->param3 != 0);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kVoiceEvent:
|
2004-04-28 23:19:45 +00:00
|
|
|
_vm->_sndRes->playVoice(event->param);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kMusicEvent:
|
|
|
|
if (event->op == kEventPlay)
|
2005-07-19 19:05:52 +00:00
|
|
|
_vm->_music->play(event->param, (MusicFlags)event->param2);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kBgEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
{
|
2008-12-06 13:35:27 +00:00
|
|
|
Surface *backGroundSurface = _vm->_render->getBackGroundSurface();
|
2005-07-09 16:23:45 +00:00
|
|
|
BGInfo bgInfo;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-07 22:18:53 +00:00
|
|
|
if (!(_vm->_scene->getFlags() & kSceneFlagISO)) {
|
2005-07-08 16:56:03 +00:00
|
|
|
_vm->_scene->getBGInfo(bgInfo);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-07-09 16:23:45 +00:00
|
|
|
backGroundSurface->blit(bgInfo.bounds, bgInfo.buffer);
|
2005-04-22 01:38:27 +00:00
|
|
|
|
|
|
|
// If it is inset scene then draw black border
|
2008-12-22 14:36:58 +00:00
|
|
|
if (bgInfo.bounds.width() < _vm->getDisplayInfo().width || bgInfo.bounds.height() < _vm->_scene->getHeight()) {
|
2005-07-08 16:56:03 +00:00
|
|
|
Common::Rect rect1(2, bgInfo.bounds.height() + 4);
|
|
|
|
Common::Rect rect2(bgInfo.bounds.width() + 4, 2);
|
|
|
|
Common::Rect rect3(2, bgInfo.bounds.height() + 4);
|
|
|
|
Common::Rect rect4(bgInfo.bounds.width() + 4, 2);
|
|
|
|
rect1.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2);
|
|
|
|
rect2.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2);
|
|
|
|
rect3.moveTo(bgInfo.bounds.right, bgInfo.bounds.top - 2);
|
|
|
|
rect4.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.bottom);
|
2005-04-22 01:38:27 +00:00
|
|
|
|
2005-07-09 16:23:45 +00:00
|
|
|
backGroundSurface->drawRect(rect1, kITEColorBlack);
|
|
|
|
backGroundSurface->drawRect(rect2, kITEColorBlack);
|
|
|
|
backGroundSurface->drawRect(rect3, kITEColorBlack);
|
|
|
|
backGroundSurface->drawRect(rect4, kITEColorBlack);
|
2005-04-22 01:38:27 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
if (event->param == kEvPSetPalette) {
|
2005-07-19 19:05:52 +00:00
|
|
|
PalEntry *palPointer;
|
2007-08-17 06:08:18 +00:00
|
|
|
|
2009-01-02 16:52:38 +00:00
|
|
|
#ifdef ENABLE_IHNM
|
2008-12-21 15:59:05 +00:00
|
|
|
if (_vm->getGameId() == GID_IHNM) {
|
2012-11-11 21:31:25 +00:00
|
|
|
PalEntry portraitBgColor = _vm->_interface->_portraitBgColor;
|
|
|
|
byte portraitColor = (_vm->getLanguage() == Common::ES_ESP) ? 253 : 254;
|
|
|
|
|
|
|
|
// Set the portrait bg color, in case a saved state is restored from the
|
|
|
|
// launcher. In this case, sfSetPortraitBgColor is not called, thus the
|
|
|
|
// portrait color will always be 0 (black).
|
|
|
|
if (portraitBgColor.red == 0 && portraitBgColor.green == 0 && portraitBgColor.blue == 0)
|
|
|
|
portraitBgColor.green = 255;
|
|
|
|
|
2007-08-17 06:08:18 +00:00
|
|
|
if (_vm->_spiritualBarometer > 255)
|
2012-11-11 21:31:25 +00:00
|
|
|
_vm->_gfx->setPaletteColor(portraitColor, 0xff, 0xff, 0xff);
|
2007-08-17 06:08:18 +00:00
|
|
|
else
|
2012-11-11 21:31:25 +00:00
|
|
|
_vm->_gfx->setPaletteColor(portraitColor,
|
|
|
|
_vm->_spiritualBarometer * portraitBgColor.red / 256,
|
|
|
|
_vm->_spiritualBarometer * portraitBgColor.green / 256,
|
|
|
|
_vm->_spiritualBarometer * portraitBgColor.blue / 256);
|
2007-08-17 06:08:18 +00:00
|
|
|
}
|
2009-01-02 16:52:38 +00:00
|
|
|
#endif
|
2007-08-17 06:08:18 +00:00
|
|
|
|
2005-07-19 19:05:52 +00:00
|
|
|
_vm->_scene->getBGPal(palPointer);
|
2005-10-05 01:40:55 +00:00
|
|
|
_vm->_gfx->setPalette(palPointer);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
2007-08-25 23:19:55 +00:00
|
|
|
_vm->_render->clearFlag(RF_DISABLE_ACTORS);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
break;
|
2007-07-30 13:19:46 +00:00
|
|
|
case kPsychicProfileBgEvent:
|
|
|
|
{
|
|
|
|
ResourceContext *context = _vm->_resource->getContext(GAME_RESOURCEFILE);
|
|
|
|
|
2010-10-24 22:17:44 +00:00
|
|
|
ByteArray resourceData;
|
2007-07-30 13:19:46 +00:00
|
|
|
|
2010-10-24 22:17:44 +00:00
|
|
|
_vm->_resource->loadResource(context, _vm->getResourceDescription()->psychicProfileResourceId, resourceData);
|
2007-07-30 13:19:46 +00:00
|
|
|
|
2010-10-23 21:56:16 +00:00
|
|
|
ByteArray image;
|
2007-07-30 13:19:46 +00:00
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
|
2010-10-24 22:17:44 +00:00
|
|
|
_vm->decodeBGImage(resourceData, image, &width, &height);
|
2007-07-30 13:19:46 +00:00
|
|
|
|
2010-10-24 22:17:44 +00:00
|
|
|
const PalEntry *palette = (const PalEntry *)_vm->getImagePal(resourceData);
|
2007-07-30 13:19:46 +00:00
|
|
|
|
2007-08-01 02:37:29 +00:00
|
|
|
const Rect profileRect(width, height);
|
2007-07-30 13:19:46 +00:00
|
|
|
|
2010-10-23 21:56:16 +00:00
|
|
|
_vm->_render->getBackGroundSurface()->blit(profileRect, image.getBuffer());
|
2008-12-12 14:23:02 +00:00
|
|
|
_vm->_render->addDirtyRect(profileRect);
|
2007-07-30 13:19:46 +00:00
|
|
|
_vm->_frameCount++;
|
|
|
|
|
|
|
|
_vm->_gfx->setPalette(palette);
|
|
|
|
|
2007-09-14 12:42:47 +00:00
|
|
|
// Draw the scene. It won't be drawn by Render::drawScene(), as a placard is up
|
2007-07-30 13:19:46 +00:00
|
|
|
_vm->_scene->draw();
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kAnimEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventPlay:
|
2005-01-02 14:36:00 +00:00
|
|
|
_vm->_anim->play(event->param, event->time, true);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventStop:
|
2005-01-02 15:45:38 +00:00
|
|
|
_vm->_anim->stop(event->param);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventFrame:
|
2004-12-28 04:09:10 +00:00
|
|
|
_vm->_anim->play(event->param, event->time, false);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventSetFlag:
|
2004-08-10 23:04:52 +00:00
|
|
|
_vm->_anim->setFlag(event->param, event->param2);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventClearFlag:
|
2004-08-10 23:04:52 +00:00
|
|
|
_vm->_anim->clearFlag(event->param, event->param2);
|
|
|
|
break;
|
2007-06-16 14:06:17 +00:00
|
|
|
case kEventResumeAll:
|
|
|
|
_vm->_anim->resumeAll();
|
|
|
|
break;
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kSceneEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2007-06-17 16:21:05 +00:00
|
|
|
case kEventDraw:
|
2007-06-17 01:50:49 +00:00
|
|
|
{
|
|
|
|
BGInfo bgInfo;
|
|
|
|
_vm->_scene->getBGInfo(bgInfo);
|
2008-12-06 13:35:27 +00:00
|
|
|
_vm->_render->getBackGroundSurface()->blit(bgInfo.bounds, bgInfo.buffer);
|
2008-12-12 14:23:02 +00:00
|
|
|
_vm->_render->addDirtyRect(bgInfo.bounds);
|
2007-06-17 01:50:49 +00:00
|
|
|
_vm->_scene->draw();
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventEnd:
|
2004-08-04 20:28:57 +00:00
|
|
|
_vm->_scene->nextScene();
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStBreak;
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kPalAnimEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventCycleStart:
|
2004-08-10 19:20:33 +00:00
|
|
|
_vm->_palanim->cycleStart();
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventCycleStep:
|
2004-08-10 19:20:33 +00:00
|
|
|
_vm->_palanim->cycleStep(event->time);
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kInterfaceEvent:
|
2004-04-12 21:40:49 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventActivate:
|
2004-08-06 01:39:17 +00:00
|
|
|
_vm->_interface->activate();
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventDeactivate:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_interface->deactivate();
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventSetStatus:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_interface->setStatusText((const char*)event->data);
|
2005-04-18 20:03:14 +00:00
|
|
|
_vm->_interface->drawStatusBar();
|
2005-01-06 16:07:46 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventClearStatus:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_interface->setStatusText("");
|
2005-04-18 20:03:14 +00:00
|
|
|
_vm->_interface->drawStatusBar();
|
2005-01-06 16:07:46 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventSetFadeMode:
|
2005-06-04 15:02:17 +00:00
|
|
|
_vm->_interface->setFadeMode(event->param);
|
2005-01-07 00:57:43 +00:00
|
|
|
break;
|
2007-09-14 12:42:47 +00:00
|
|
|
case kEventRestoreMode:
|
|
|
|
_vm->_interface->restoreMode();
|
|
|
|
break;
|
2007-09-18 23:15:48 +00:00
|
|
|
case kEventSetMode:
|
|
|
|
_vm->_interface->setMode(event->param);
|
|
|
|
break;
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2004-10-16 07:46:52 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kScriptEvent:
|
2005-01-06 16:07:46 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventExecBlocking:
|
2009-04-11 21:38:41 +00:00
|
|
|
case kEventExecNonBlocking: {
|
2006-03-08 11:37:25 +00:00
|
|
|
debug(6, "Exec module number %ld script entry number %ld", event->param, event->param2);
|
2005-07-29 17:58:00 +00:00
|
|
|
|
2009-04-11 21:38:41 +00:00
|
|
|
ScriptThread &sthread = _vm->_script->createThread(event->param, event->param2);
|
|
|
|
sthread._threadVars[kThreadVarAction] = event->param3;
|
|
|
|
sthread._threadVars[kThreadVarObject] = event->param4;
|
|
|
|
sthread._threadVars[kThreadVarWithObject] = event->param5;
|
|
|
|
sthread._threadVars[kThreadVarActor] = event->param6;
|
2004-10-16 07:46:52 +00:00
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
if (event->op == kEventExecBlocking)
|
2005-01-15 20:12:49 +00:00
|
|
|
_vm->_script->completeThread();
|
2004-10-16 07:46:52 +00:00
|
|
|
|
2005-01-06 16:07:46 +00:00
|
|
|
break;
|
2009-04-11 21:38:41 +00:00
|
|
|
}
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventThreadWake:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_script->wakeUpThreads(event->param);
|
|
|
|
break;
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kCursorEvent:
|
2004-11-20 00:05:50 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventShow:
|
2004-11-20 00:05:50 +00:00
|
|
|
_vm->_gfx->showCursor(true);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventHide:
|
2004-11-20 00:05:50 +00:00
|
|
|
_vm->_gfx->showCursor(false);
|
|
|
|
break;
|
2007-05-06 22:18:31 +00:00
|
|
|
case kEventSetNormalCursor:
|
2007-07-27 18:32:00 +00:00
|
|
|
// in ITE and IHNM demo there is just one cursor
|
2008-12-21 15:59:05 +00:00
|
|
|
// ITE never makes this call
|
2010-05-16 10:36:21 +00:00
|
|
|
if (!_vm->isIHNMDemo())
|
2007-05-07 06:18:08 +00:00
|
|
|
_vm->_gfx->setCursor(kCursorNormal);
|
2007-05-06 22:18:31 +00:00
|
|
|
break;
|
|
|
|
case kEventSetBusyCursor:
|
2007-07-27 18:32:00 +00:00
|
|
|
// in ITE and IHNM demo there is just one cursor
|
2008-12-21 15:59:05 +00:00
|
|
|
// ITE never makes this call
|
2010-05-16 10:36:21 +00:00
|
|
|
if (!_vm->isIHNMDemo())
|
2007-05-07 06:18:08 +00:00
|
|
|
_vm->_gfx->setCursor(kCursorBusy);
|
2007-05-06 22:18:31 +00:00
|
|
|
break;
|
2004-11-20 00:05:50 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2005-01-06 16:07:46 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kGraphicsEvent:
|
2005-01-06 16:07:46 +00:00
|
|
|
switch (event->op) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventFillRect:
|
2005-01-06 16:07:46 +00:00
|
|
|
rect.top = event->param2;
|
|
|
|
rect.bottom = event->param3;
|
|
|
|
rect.left = event->param4;
|
|
|
|
rect.right = event->param5;
|
2008-12-06 18:23:34 +00:00
|
|
|
_vm->_gfx->drawRect(rect, event->param);
|
2005-01-06 16:07:46 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventSetFlag:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_render->setFlag(event->param);
|
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEventClearFlag:
|
2005-01-06 16:07:46 +00:00
|
|
|
_vm->_render->clearFlag(event->param);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-01 20:16:32 +00:00
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#ifdef ENABLE_IHNM
|
2007-06-16 08:53:46 +00:00
|
|
|
case kCutawayEvent:
|
|
|
|
switch (event->op) {
|
2007-06-17 16:21:05 +00:00
|
|
|
case kEventClear:
|
2007-06-16 08:53:46 +00:00
|
|
|
_vm->_anim->clearCutaway();
|
|
|
|
break;
|
2007-09-15 12:09:56 +00:00
|
|
|
case kEventShowCutawayBg:
|
|
|
|
_vm->_anim->showCutawayBg(event->param);
|
|
|
|
break;
|
2007-06-16 08:53:46 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-01 20:16:32 +00:00
|
|
|
break;
|
2009-01-02 16:52:38 +00:00
|
|
|
#endif
|
2007-08-25 16:01:42 +00:00
|
|
|
case kActorEvent:
|
|
|
|
switch (event->op) {
|
|
|
|
case kEventMove:
|
|
|
|
// TODO (check Actor::direct)
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-01 20:16:32 +00:00
|
|
|
break;
|
2004-04-12 21:40:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
2004-05-01 06:50:20 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStDelete;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 14:11:22 +00:00
|
|
|
int Events::handleInterval(Event *event) {
|
2005-08-10 15:31:15 +00:00
|
|
|
return kEvStDelete;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2010-10-24 17:42:45 +00:00
|
|
|
EventColumns *Events::chain(EventColumns *eventColumns, const Event &event) {
|
2011-06-19 22:59:48 +00:00
|
|
|
|
2010-10-23 23:07:10 +00:00
|
|
|
if (eventColumns == NULL) {
|
2010-10-24 17:42:45 +00:00
|
|
|
EventColumns tmp;
|
|
|
|
|
|
|
|
_eventList.push_back(tmp);
|
|
|
|
eventColumns = &_eventList.back();
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2010-10-24 17:42:45 +00:00
|
|
|
eventColumns->push_back(event);
|
2010-10-23 23:07:10 +00:00
|
|
|
initializeEvent(eventColumns->back());
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2010-10-23 23:07:10 +00:00
|
|
|
return eventColumns;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2010-10-23 23:07:10 +00:00
|
|
|
void Events::initializeEvent(Event &event) {
|
|
|
|
switch (event.type) {
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTOneshot:
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTContinuous:
|
|
|
|
case kEvTImmediate:
|
2010-10-23 23:07:10 +00:00
|
|
|
event.time += event.duration;
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
2005-08-10 15:31:15 +00:00
|
|
|
case kEvTInterval:
|
2004-04-12 21:40:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-23 23:07:10 +00:00
|
|
|
void Events::clearList(bool playQueuedMusic) {
|
2004-05-01 06:50:20 +00:00
|
|
|
// Walk down event list
|
2004-12-15 00:24:12 +00:00
|
|
|
for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
// Only remove events not marked kEvFNoDestory (engine events)
|
2010-10-23 23:07:10 +00:00
|
|
|
if (!(eventi->front().code & kEvFNoDestory)) {
|
2009-01-17 21:45:53 +00:00
|
|
|
// Handle queued music change events before deleting them
|
|
|
|
// This can happen in IHNM by music events set by sfQueueMusic()
|
|
|
|
// Fixes bug #2057987 - "IHNM: Music stops in Ellen's chapter"
|
2010-10-23 23:07:10 +00:00
|
|
|
if (playQueuedMusic && ((eventi->front().code & EVENT_MASK) == kMusicEvent)) {
|
2009-01-17 21:45:53 +00:00
|
|
|
_vm->_music->stop();
|
2010-10-23 23:07:10 +00:00
|
|
|
if (eventi->front().op == kEventPlay)
|
|
|
|
_vm->_music->play(eventi->front().param, (MusicFlags)eventi->front().param2);
|
2009-01-17 21:45:53 +00:00
|
|
|
}
|
|
|
|
|
2009-04-11 00:28:49 +00:00
|
|
|
eventi = _eventList.reverse_erase(eventi);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-10 15:31:15 +00:00
|
|
|
// Removes all events from the list (even kEvFNoDestory)
|
2010-10-23 23:07:10 +00:00
|
|
|
void Events::freeList() {
|
|
|
|
_eventList.clear();
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-01 06:50:20 +00:00
|
|
|
// Walks down the event list, updating event times by 'msec'.
|
2010-10-23 23:07:10 +00:00
|
|
|
void Events::processEventTime(long msec) {
|
2004-04-30 23:02:23 +00:00
|
|
|
uint16 event_count = 0;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-12-15 00:24:12 +00:00
|
|
|
for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
|
2010-10-23 23:07:10 +00:00
|
|
|
eventi->front().time -= msec;
|
2004-04-12 21:40:49 +00:00
|
|
|
event_count++;
|
|
|
|
|
2010-10-23 23:07:10 +00:00
|
|
|
if (eventi->front().type == kEvTImmediate)
|
2004-08-11 22:27:39 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
if (event_count > EVENT_WARNINGCOUNT) {
|
|
|
|
warning("Event list exceeds %u", EVENT_WARNINGCOUNT);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Saga
|