2007-05-30 21:56:52 +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.
|
2007-01-14 21:29:12 +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
|
|
|
|
* 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$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2007-05-13 14:38:05 +00:00
|
|
|
#include "common/stdafx.h"
|
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
#include "parallaction/parallaction.h"
|
2007-05-01 16:21:16 +00:00
|
|
|
#include "parallaction/sound.h"
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
namespace Parallaction {
|
|
|
|
|
|
|
|
|
2007-03-24 19:55:34 +00:00
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-18 19:35:54 +00:00
|
|
|
Zone *Parallaction::findZone(const char *name) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++)
|
|
|
|
if (!scumm_stricmp((*it)->_label._text, name)) return *it;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-19 21:49:41 +00:00
|
|
|
return findAnimation(name);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
void Parallaction::parseZone(Script &script, ZoneList &list, char *name) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("parseZone(%s)", name);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
if (findZone(name)) {
|
|
|
|
while (scumm_stricmp(_tokens[0], "endzone")) {
|
2007-02-20 16:54:55 +00:00
|
|
|
fillBuffers(script, true);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-03-18 20:18:19 +00:00
|
|
|
Zone *z = new Zone;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-04 08:58:23 +00:00
|
|
|
z->_label._text = (char*)malloc(strlen(name)+1);
|
2007-02-04 08:12:33 +00:00
|
|
|
strcpy(z->_label._text, name);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
list.push_front(z);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-02-20 16:54:55 +00:00
|
|
|
fillBuffers(script, true);
|
2007-01-14 21:29:12 +00:00
|
|
|
while (scumm_stricmp(_tokens[0], "endzone")) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("token[0] = %s", _tokens[0]);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
if (!scumm_stricmp(_tokens[0], "limits")) {
|
2007-03-17 19:48:48 +00:00
|
|
|
z->_left = atoi(_tokens[1]);
|
|
|
|
z->_top = atoi(_tokens[2]);
|
|
|
|
z->_right = atoi(_tokens[3]);
|
|
|
|
z->_bottom = atoi(_tokens[4]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "moveto")) {
|
2007-03-18 17:17:21 +00:00
|
|
|
z->_moveTo.x = atoi(_tokens[1]);
|
|
|
|
z->_moveTo.y = atoi(_tokens[2]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "type")) {
|
|
|
|
if (_tokens[2][0] != '\0') {
|
2007-03-24 21:18:08 +00:00
|
|
|
z->_type = (4 + _objectsNames->lookup(_tokens[2])) << 16;
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
2007-03-24 21:18:08 +00:00
|
|
|
int16 _si = _zoneTypeNames->lookup(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
if (_si != -1) {
|
|
|
|
z->_type |= 1 << (_si - 1);
|
2007-02-20 16:54:55 +00:00
|
|
|
parseZoneTypeBlock(script, z);
|
2007-01-14 21:29:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "commands")) {
|
2007-04-07 15:18:26 +00:00
|
|
|
parseCommands(script, z->_commands);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "label")) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("label: %s", _tokens[1]);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->makeCnvFromString(&z->_label._cnv, _tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "flags")) {
|
|
|
|
uint16 _si = 1;
|
|
|
|
|
|
|
|
do {
|
2007-03-24 21:18:08 +00:00
|
|
|
char _al = _zoneFlagNames->lookup(_tokens[_si]);
|
2007-01-14 21:29:12 +00:00
|
|
|
_si++;
|
|
|
|
z->_flags |= 1 << (_al - 1);
|
|
|
|
} while (!scumm_stricmp(_tokens[_si++], "|"));
|
|
|
|
}
|
|
|
|
|
2007-02-20 16:54:55 +00:00
|
|
|
fillBuffers(script, true);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
void Parallaction::freeZones() {
|
2007-02-17 15:37:49 +00:00
|
|
|
debugC(1, kDebugLocation, "freeZones: kEngineQuit = %i", _engineFlags & kEngineQuit);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
ZoneList::iterator it = _zones.begin();
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
while ( it != _zones.end() ) {
|
|
|
|
|
|
|
|
Zone* z = *it;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-17 20:51:13 +00:00
|
|
|
// WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
|
2007-02-17 15:37:49 +00:00
|
|
|
// instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
|
|
|
|
// but we need to check it separately here. The same workaround is applied in hitZone.
|
2007-03-17 19:48:48 +00:00
|
|
|
if (((z->_top == -1) ||
|
|
|
|
((z->_left == -2) && (
|
2007-05-18 20:05:08 +00:00
|
|
|
(((z->_type & 0xFFFF) == kZoneMerge) && ((isItemInInventory(MAKE_INVENTORY_ID(z->u.merge->_obj1)) != 0) || (isItemInInventory(MAKE_INVENTORY_ID(z->u.merge->_obj2)) != 0))) ||
|
|
|
|
(((z->_type & 0xFFFF) == kZoneGet) && ((isItemInInventory(MAKE_INVENTORY_ID(z->u.get->_icon)) != 0)))
|
2007-02-17 15:37:49 +00:00
|
|
|
))) &&
|
|
|
|
((_engineFlags & kEngineQuit) == 0)) {
|
2007-02-04 08:12:33 +00:00
|
|
|
|
2007-02-17 15:37:49 +00:00
|
|
|
debugC(1, kDebugLocation, "freeZones preserving zone '%s'", z->_label._text);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
it++;
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
it = _zones.erase(it);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-02-20 16:54:55 +00:00
|
|
|
void Parallaction::parseZoneTypeBlock(Script &script, Zone *z) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("parseZoneTypeBlock()");
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-17 20:51:13 +00:00
|
|
|
TypeData *u = &z->u;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-05-18 20:05:08 +00:00
|
|
|
switch (z->_type & 0xFFFF) {
|
2007-01-14 21:29:12 +00:00
|
|
|
case kZoneExamine: // examine Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->examine = new ExamineData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneDoor: // door Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->door = new DoorData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneGet: // get Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->get = new GetData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneMerge: // merge Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->merge = new MergeData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneHear: // hear Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->hear = new HearData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneSpeak: // speak Zone alloc
|
2007-03-18 20:18:19 +00:00
|
|
|
u->speak = new SpeakData;
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
char vC8[PATH_LEN];
|
|
|
|
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("type = %x", z->_type);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
|
2007-05-18 20:05:08 +00:00
|
|
|
switch (z->_type & 0xFFFF) {
|
2007-01-14 21:29:12 +00:00
|
|
|
case kZoneExamine: // examine Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "file")) {
|
2007-03-04 08:58:23 +00:00
|
|
|
u->examine->_filename = (char*)malloc(strlen(_tokens[1])+1);
|
2007-01-14 21:29:12 +00:00
|
|
|
strcpy(u->examine->_filename, _tokens[1]);
|
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "desc")) {
|
2007-02-20 16:54:55 +00:00
|
|
|
u->examine->_description = parseComment(script);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneDoor: // door Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "slidetext")) {
|
|
|
|
strcpy(_slideText[0], _tokens[1]);
|
|
|
|
// printf("%s\t", _slideText[0]);
|
|
|
|
strcpy(_slideText[1], _tokens[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!scumm_stricmp(_tokens[0], "location")) {
|
2007-03-04 08:58:23 +00:00
|
|
|
u->door->_location = (char*)malloc(strlen(_tokens[1])+1);
|
2007-01-14 21:29:12 +00:00
|
|
|
strcpy(u->door->_location, _tokens[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!scumm_stricmp(_tokens[0], "file")) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("file: '%s'", _tokens[0]);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
strcpy(vC8, _tokens[1]);
|
|
|
|
|
2007-03-18 21:08:28 +00:00
|
|
|
u->door->_cnv = _disk->loadFrames(vC8);
|
2007-01-14 21:29:12 +00:00
|
|
|
uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1);
|
|
|
|
|
2007-07-01 19:28:32 +00:00
|
|
|
u->door->_background = (byte*)malloc(u->door->_cnv->_width * u->door->_cnv->_height);
|
2007-03-17 19:48:48 +00:00
|
|
|
_gfx->backupDoorBackground(u->door, z->_left, z->_top);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-07-01 19:28:32 +00:00
|
|
|
_gfx->flatBlitCnv(u->door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!scumm_stricmp(_tokens[0], "startpos")) {
|
2007-03-18 17:17:21 +00:00
|
|
|
u->door->_startPos.x = atoi(_tokens[1]);
|
|
|
|
u->door->_startPos.y = atoi(_tokens[2]);
|
2007-01-14 21:29:12 +00:00
|
|
|
u->door->_startFrame = atoi(_tokens[3]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneGet: // get Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "file")) {
|
|
|
|
strcpy(vC8, _tokens[1]);
|
2007-03-18 21:15:39 +00:00
|
|
|
u->get->_cnv = _disk->loadStatic(vC8);
|
|
|
|
u->get->_backup = (byte*)malloc(u->get->_cnv->_width*u->get->_cnv->_height);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
if ((z->_flags & kFlagsRemove) == 0) {
|
2007-03-17 19:48:48 +00:00
|
|
|
_gfx->backupGetBackground(u->get, z->_left, z->_top);
|
2007-03-18 21:15:39 +00:00
|
|
|
_gfx->flatBlitCnv(u->get->_cnv, z->_left, z->_top, Gfx::kBitBack);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!scumm_stricmp(_tokens[0], "icon")) {
|
2007-03-24 21:18:08 +00:00
|
|
|
u->get->_icon = 4 + _objectsNames->lookup(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneMerge: // merge Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "obj1")) {
|
2007-03-24 21:18:08 +00:00
|
|
|
u->merge->_obj1 = 4 + _objectsNames->lookup(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "obj2")) {
|
2007-03-24 21:18:08 +00:00
|
|
|
u->merge->_obj2 = 4 + _objectsNames->lookup(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "newobj")) {
|
2007-03-24 21:18:08 +00:00
|
|
|
u->merge->_obj3 = 4 + _objectsNames->lookup(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneHear: // hear Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "sound")) {
|
|
|
|
strcpy(u->hear->_name, _tokens[1]);
|
2007-05-01 15:39:40 +00:00
|
|
|
z->u.hear->_channel = atoi(_tokens[2]);
|
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "freq")) {
|
|
|
|
z->u.hear->_freq = atoi(_tokens[1]);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneSpeak: // speak Zone init
|
|
|
|
if (!scumm_stricmp(_tokens[0], "file")) {
|
|
|
|
strcpy(u->speak->_name, _tokens[1]);
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("speak file name: %s", u.speak._name);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
if (!scumm_stricmp(_tokens[0], "Dialogue")) {
|
2007-02-20 16:54:55 +00:00
|
|
|
u->speak->_dialogue = parseDialogue(script);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-02-20 16:54:55 +00:00
|
|
|
fillBuffers(script, true);
|
2007-01-14 21:29:12 +00:00
|
|
|
} while (scumm_stricmp(_tokens[0], "endzone"));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// displays character head commenting an examined object
|
|
|
|
//
|
|
|
|
// works on the frontbuffer
|
|
|
|
//
|
2007-04-07 16:40:27 +00:00
|
|
|
void Parallaction::displayCharacterComment(ExamineData *data) {
|
2007-01-14 21:29:12 +00:00
|
|
|
if (data->_description == NULL) return;
|
|
|
|
|
2007-07-28 15:15:23 +00:00
|
|
|
// NOTE: saving visible screen before displaying comment allows
|
|
|
|
// to restore the exact situation after the comment is deleted.
|
|
|
|
// This means animations are restored in the exact position as
|
|
|
|
// they were, thus avoiding clipping effect as signalled in
|
|
|
|
// BUG item #1762614.
|
|
|
|
_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
|
|
|
|
|
2007-04-15 20:57:56 +00:00
|
|
|
_gfx->setFont(kFontDialogue);
|
2007-07-01 19:28:32 +00:00
|
|
|
_gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
int16 v26, v28;
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->getStringExtent(data->_description, 130, &v28, &v26);
|
2007-03-13 19:59:45 +00:00
|
|
|
Common::Rect r(v28, v26);
|
|
|
|
r.moveTo(140, 10);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->drawBalloon(r, 0);
|
2007-07-02 07:32:06 +00:00
|
|
|
_gfx->displayWrappedString(data->_description, 140, 10, 0, 130);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
waitUntilLeftClick();
|
|
|
|
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
|
2007-07-15 10:10:48 +00:00
|
|
|
_gfx->updateScreen();
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ZONE TYPE: EXAMINE
|
|
|
|
//
|
|
|
|
|
|
|
|
// display detail view of an item (and eventually comments)
|
|
|
|
//
|
|
|
|
// works on the frontbuffer
|
|
|
|
//
|
|
|
|
|
2007-04-07 16:40:27 +00:00
|
|
|
void Parallaction::displayItemComment(ExamineData *data) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
if (data->_description == NULL) return;
|
|
|
|
|
2007-04-21 12:51:40 +00:00
|
|
|
_gfx->setHalfbriteMode(true);
|
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
char v68[PATH_LEN];
|
|
|
|
strcpy(v68, data->_filename);
|
2007-04-07 16:40:27 +00:00
|
|
|
data->_cnv = _disk->loadStatic(v68);
|
2007-07-26 18:30:27 +00:00
|
|
|
_gfx->flatBlitCnv(data->_cnv, 140, (_screenHeight - data->_cnv->_height)/2, Gfx::kBitFront);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->freeStaticCnv(data->_cnv);
|
2007-03-18 21:15:39 +00:00
|
|
|
delete data->_cnv;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
int16 v6A = 0, v6C = 0;
|
|
|
|
|
2007-04-15 20:57:56 +00:00
|
|
|
_gfx->setFont(kFontDialogue);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->getStringExtent(data->_description, 130, &v6C, &v6A);
|
2007-03-13 19:59:45 +00:00
|
|
|
Common::Rect r(v6C, v6A);
|
|
|
|
r.moveTo(0, 90);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->drawBalloon(r, 0);
|
2007-07-29 19:17:53 +00:00
|
|
|
_gfx->flatBlitCnv(_char._head, 100, 152, Gfx::kBitFront);
|
2007-07-02 07:32:06 +00:00
|
|
|
_gfx->displayWrappedString(data->_description, 0, 90, 0, 130);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
jobEraseAnimations((void*)1, NULL);
|
2007-04-16 20:16:18 +00:00
|
|
|
_gfx->updateScreen();
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
waitUntilLeftClick();
|
2007-04-21 12:51:40 +00:00
|
|
|
|
|
|
|
_gfx->setHalfbriteMode(false);
|
2007-04-07 16:40:27 +00:00
|
|
|
_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
|
2007-07-15 10:10:48 +00:00
|
|
|
_gfx->updateScreen();
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-24 19:55:34 +00:00
|
|
|
uint16 Parallaction::runZone(Zone *z) {
|
2007-02-17 15:37:49 +00:00
|
|
|
debugC(3, kDebugLocation, "runZone (%s)", z->_label._text);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-05-18 20:05:08 +00:00
|
|
|
uint16 subtype = z->_type & 0xFFFF;
|
|
|
|
|
|
|
|
debugC(3, kDebugLocation, "type = %x, object = %x", subtype, (z->_type & 0xFFFF0000) >> 16);
|
|
|
|
switch(subtype) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
case kZoneExamine:
|
|
|
|
if (z->u.examine->_filename) {
|
|
|
|
displayItemComment(z->u.examine);
|
|
|
|
} else {
|
|
|
|
displayCharacterComment(z->u.examine);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneGet:
|
|
|
|
if (z->_flags & kFlagsFixed) break;
|
|
|
|
if (pickupItem(z) != 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
z->_flags |= kFlagsRemove;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneDoor:
|
|
|
|
if (z->_flags & kFlagsLocked) break;
|
|
|
|
z->_flags ^= kFlagsClosed;
|
2007-03-18 21:00:22 +00:00
|
|
|
if (z->u.door->_cnv == NULL) break;
|
2007-04-07 16:40:27 +00:00
|
|
|
addJob(&jobToggleDoor, z, kPriority18 );
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneHear:
|
2007-05-01 15:39:40 +00:00
|
|
|
_soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60);
|
2007-01-14 21:29:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneSpeak:
|
|
|
|
runDialogue(z->u.speak);
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-02-17 15:37:49 +00:00
|
|
|
debugC(3, kDebugLocation, "runZone completed");
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ZONE TYPE: DOOR
|
|
|
|
//
|
|
|
|
void jobToggleDoor(void *parm, Job *j) {
|
|
|
|
|
|
|
|
static byte count = 0;
|
|
|
|
|
|
|
|
Zone *z = (Zone*)parm;
|
|
|
|
|
|
|
|
StaticCnv v14;
|
|
|
|
|
2007-03-18 21:00:22 +00:00
|
|
|
if (z->u.door->_cnv) {
|
|
|
|
v14._width = z->u.door->_cnv->_width;
|
|
|
|
v14._height = z->u.door->_cnv->_height;
|
2007-03-12 19:58:10 +00:00
|
|
|
|
2007-03-18 21:00:22 +00:00
|
|
|
Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height);
|
2007-03-13 19:59:45 +00:00
|
|
|
|
|
|
|
_vm->_gfx->restoreZoneBackground(r, z->u.door->_background);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1);
|
|
|
|
|
2007-07-01 19:28:32 +00:00
|
|
|
_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
|
|
|
|
_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBit2);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
|
|
|
if (count == 2) {
|
|
|
|
j->_finished = 1;
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// ZONE TYPE: GET
|
|
|
|
//
|
|
|
|
|
2007-05-06 08:52:27 +00:00
|
|
|
int16 Parallaction::pickupItem(Zone *z) {
|
|
|
|
int r = addInventoryItem(z->u.get->_icon);
|
|
|
|
if (r == 0)
|
|
|
|
addJob(&jobRemovePickedItem, z, kPriority17 );
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
void jobRemovePickedItem(void *parm, Job *j) {
|
|
|
|
|
|
|
|
Zone *z = (Zone*)parm;
|
|
|
|
|
|
|
|
static uint16 count = 0;
|
|
|
|
|
2007-03-18 21:15:39 +00:00
|
|
|
if (z->u.get->_cnv) {
|
|
|
|
Common::Rect r(z->_left, z->_top, z->_left + z->u.get->_cnv->_width, z->_top + z->u.get->_cnv->_height);
|
2007-03-13 19:59:45 +00:00
|
|
|
|
|
|
|
_vm->_gfx->restoreZoneBackground(r, z->u.get->_backup);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
|
|
|
if (count == 2) {
|
|
|
|
count = 0;
|
|
|
|
j->_finished = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void jobDisplayDroppedItem(void *parm, Job *j) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("jobDisplayDroppedItem...");
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
Zone *z = (Zone*)parm;
|
|
|
|
|
2007-03-18 21:15:39 +00:00
|
|
|
if (z->u.get->_cnv) {
|
2007-05-20 13:47:43 +00:00
|
|
|
if (j->_count == 0) {
|
2007-03-17 19:48:48 +00:00
|
|
|
_vm->_gfx->backupGetBackground(z->u.get, z->_left, z->_top);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
2007-03-18 21:15:39 +00:00
|
|
|
_vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBitBack);
|
|
|
|
_vm->_gfx->flatBlitCnv(z->u.get->_cnv, z->_left, z->_top, Gfx::kBit2);
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
j->_count++;
|
|
|
|
if (j->_count == 2) {
|
|
|
|
j->_count = 0;
|
|
|
|
j->_finished = 1;
|
|
|
|
}
|
|
|
|
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("done");
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-18 19:35:54 +00:00
|
|
|
Zone *Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("hitZone(%i, %i, %i)", type, x, y);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
uint16 _di = y;
|
|
|
|
uint16 _si = x;
|
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
for (ZoneList::iterator it = _zones.begin(); it != _zones.end(); it++) {
|
2007-01-26 23:24:12 +00:00
|
|
|
// printf("Zone name: %s", z->_name);
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-11 20:01:06 +00:00
|
|
|
Zone *z = *it;
|
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
if (z->_flags & kFlagsRemove) continue;
|
|
|
|
|
2007-03-17 21:17:00 +00:00
|
|
|
Common::Rect r;
|
|
|
|
z->getRect(r);
|
|
|
|
r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
|
|
|
|
r.bottom++;
|
|
|
|
|
|
|
|
r.grow(-1); // allows some tolerance for mouse click
|
|
|
|
|
|
|
|
if (!r.contains(_si, _di)) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
// out of Zone, so look for special values
|
2007-03-17 19:48:48 +00:00
|
|
|
if ((z->_left == -2) || (z->_left == -3)) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-17 20:51:13 +00:00
|
|
|
// WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
|
2007-02-17 10:58:54 +00:00
|
|
|
// instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
|
|
|
|
// but we need to check it separately here. The same workaround is applied in freeZones.
|
2007-05-18 20:05:08 +00:00
|
|
|
if ((((z->_type & 0xFFFF) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) ||
|
|
|
|
(((z->_type & 0xFFFF) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
// special Zone
|
2007-05-18 20:05:08 +00:00
|
|
|
if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
|
2007-02-17 15:37:49 +00:00
|
|
|
return z;
|
|
|
|
if (z->_type == type)
|
|
|
|
return z;
|
2007-05-18 20:05:08 +00:00
|
|
|
if ((z->_type & 0xFFFF0000) == type)
|
2007-02-17 15:37:49 +00:00
|
|
|
return z;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-17 19:48:48 +00:00
|
|
|
if (z->_left != -1)
|
2007-02-17 15:37:49 +00:00
|
|
|
continue;
|
2007-04-07 16:40:27 +00:00
|
|
|
if (_si < _char._ani._left)
|
2007-02-17 15:37:49 +00:00
|
|
|
continue;
|
2007-04-07 16:40:27 +00:00
|
|
|
if (_si > (_char._ani._left + _char._ani.width()))
|
2007-02-17 15:37:49 +00:00
|
|
|
continue;
|
2007-04-07 16:40:27 +00:00
|
|
|
if (_di < _char._ani._top)
|
2007-02-17 15:37:49 +00:00
|
|
|
continue;
|
2007-04-07 16:40:27 +00:00
|
|
|
if (_di > (_char._ani._top + _char._ani.height()))
|
2007-02-17 15:37:49 +00:00
|
|
|
continue;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// normal Zone
|
2007-05-18 20:05:08 +00:00
|
|
|
if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
|
2007-02-17 15:37:49 +00:00
|
|
|
return z;
|
|
|
|
if (z->_type == type)
|
|
|
|
return z;
|
2007-05-18 20:05:08 +00:00
|
|
|
if ((z->_type & 0xFFFF0000) == type)
|
2007-02-17 15:37:49 +00:00
|
|
|
return z;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int16 _a, _b, _c, _d, _e, _f;
|
2007-04-11 20:01:06 +00:00
|
|
|
for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++) {
|
|
|
|
|
|
|
|
Animation *a = *it;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-19 21:49:41 +00:00
|
|
|
_a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
|
|
|
|
_e = ((_si >= a->_left + a->width()) || (_si <= a->_left)) ? 0 : 1; // _e: horizontal range
|
|
|
|
_f = ((_di >= a->_top + a->height()) || (_di <= a->_top)) ? 0 : 1; // _f: vertical range
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-19 21:49:41 +00:00
|
|
|
_b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
|
2007-05-18 20:05:08 +00:00
|
|
|
_c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object
|
|
|
|
_d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1; // _d: Animation is an object of the same type
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-19 21:49:41 +00:00
|
|
|
if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-03-19 21:49:41 +00:00
|
|
|
return a;
|
2007-01-14 21:29:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2007-04-07 09:31:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Zone::Zone() {
|
|
|
|
_left = _top = _right = _bottom = 0;
|
|
|
|
|
|
|
|
_type = 0;
|
|
|
|
_flags = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Zone::~Zone() {
|
2007-04-15 08:32:28 +00:00
|
|
|
// printf("~Zone(%s)\n", _label._text);
|
2007-04-07 09:31:24 +00:00
|
|
|
|
2007-05-18 20:05:08 +00:00
|
|
|
switch (_type & 0xFFFF) {
|
2007-04-07 09:31:24 +00:00
|
|
|
case kZoneExamine:
|
|
|
|
free(u.examine->_filename);
|
|
|
|
free(u.examine->_description);
|
|
|
|
delete u.examine;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneDoor:
|
|
|
|
free(u.door->_location);
|
|
|
|
free(u.door->_background);
|
|
|
|
if (u.door->_cnv)
|
|
|
|
delete u.door->_cnv;
|
|
|
|
delete u.door;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneSpeak:
|
2007-04-07 14:00:23 +00:00
|
|
|
delete u.speak->_dialogue;
|
2007-04-07 09:31:24 +00:00
|
|
|
delete u.speak;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneGet:
|
|
|
|
free(u.get->_backup);
|
|
|
|
_vm->_gfx->freeStaticCnv(u.get->_cnv);
|
|
|
|
if (u.get->_cnv)
|
|
|
|
delete u.get->_cnv;
|
|
|
|
delete u.get;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneHear:
|
|
|
|
delete u.hear;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kZoneMerge:
|
|
|
|
delete u.merge;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-01-14 21:29:12 +00:00
|
|
|
|
2007-04-07 09:31:24 +00:00
|
|
|
void Zone::getRect(Common::Rect& r) const {
|
|
|
|
r.left = _left;
|
|
|
|
r.right = _right;
|
|
|
|
r.top = _top;
|
|
|
|
r.bottom = _bottom;
|
2007-01-14 21:29:12 +00:00
|
|
|
}
|
|
|
|
|
2007-04-07 09:31:24 +00:00
|
|
|
void Zone::translate(int16 x, int16 y) {
|
|
|
|
_left += x;
|
|
|
|
_right += x;
|
|
|
|
_top += y;
|
|
|
|
_bottom += y;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 Zone::width() const {
|
|
|
|
return _right - _left;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 Zone::height() const {
|
|
|
|
return _bottom - _top;
|
|
|
|
}
|
|
|
|
|
2007-04-15 08:32:28 +00:00
|
|
|
Label::Label() {
|
|
|
|
_text = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Label::~Label() {
|
|
|
|
_vm->_gfx->freeStaticCnv(&_cnv);
|
|
|
|
if (_text)
|
|
|
|
free(_text);
|
|
|
|
}
|
|
|
|
|
2007-04-07 09:31:24 +00:00
|
|
|
|
2007-01-14 21:29:12 +00:00
|
|
|
} // namespace Parallaction
|