2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
2006-02-22 22:40:53 +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.
|
2006-02-22 22:40:53 +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-09-19 08:40:12 +00:00
|
|
|
|
2006-03-29 15:59:37 +00:00
|
|
|
#include "common/endian.h"
|
2006-02-25 01:18:01 +00:00
|
|
|
#include "common/scummsys.h"
|
|
|
|
#include "common/util.h"
|
|
|
|
|
2006-02-22 22:40:53 +00:00
|
|
|
#include "cine/cine.h"
|
2006-02-25 01:18:01 +00:00
|
|
|
#include "cine/object.h"
|
|
|
|
#include "cine/part.h"
|
|
|
|
#include "cine/various.h"
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2006-02-25 00:26:14 +00:00
|
|
|
namespace Cine {
|
|
|
|
|
2006-02-22 22:40:53 +00:00
|
|
|
objectStruct objectTable[NUM_MAX_OBJECT];
|
2008-04-21 20:51:17 +00:00
|
|
|
Common::List<overlay> overlayList;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
|
|
|
void loadObject(char *pObjectName) {
|
2006-02-23 09:12:21 +00:00
|
|
|
uint16 numEntry;
|
|
|
|
uint16 entrySize;
|
|
|
|
uint16 i;
|
2007-05-29 21:06:07 +00:00
|
|
|
byte *ptr, *dataPtr;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
|
|
|
checkDataDisk(-1);
|
|
|
|
|
2007-05-29 21:06:07 +00:00
|
|
|
ptr = dataPtr = readBundleFile(findFileInBundle(pObjectName));
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2006-03-16 20:29:07 +00:00
|
|
|
setMouseCursor(MOUSE_CURSOR_DISK);
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2006-02-27 21:25:59 +00:00
|
|
|
numEntry = READ_BE_UINT16(ptr); ptr += 2;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2006-02-27 21:25:59 +00:00
|
|
|
entrySize = READ_BE_UINT16(ptr); ptr += 2;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2006-03-23 03:17:47 +00:00
|
|
|
assert(numEntry <= NUM_MAX_OBJECT);
|
2006-02-22 22:40:53 +00:00
|
|
|
|
|
|
|
for (i = 0; i < numEntry; i++) {
|
2006-04-05 20:11:00 +00:00
|
|
|
if (objectTable[i].costume != -2) { // flag is keep ?
|
|
|
|
Common::MemoryReadStream readS(ptr, entrySize);
|
|
|
|
|
|
|
|
objectTable[i].x = readS.readSint16BE();
|
|
|
|
objectTable[i].y = readS.readSint16BE();
|
|
|
|
objectTable[i].mask = readS.readUint16BE();
|
|
|
|
objectTable[i].frame = readS.readSint16BE();
|
|
|
|
objectTable[i].costume = readS.readSint16BE();
|
|
|
|
readS.read(objectTable[i].name, 20);
|
|
|
|
objectTable[i].part = readS.readUint16BE();
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
2006-04-05 20:11:00 +00:00
|
|
|
ptr += entrySize;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(pObjectName, "INTRO.OBJ")) {
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
objectTable[i].costume = 0;
|
|
|
|
}
|
|
|
|
}
|
2007-05-29 21:06:07 +00:00
|
|
|
|
|
|
|
free(dataPtr);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
/*! \brief Remove overlay sprite from the list
|
|
|
|
* \param objIdx Remove overlay associated with this object
|
|
|
|
* \param param Remove overlay of this type
|
|
|
|
*/
|
|
|
|
int removeOverlay(uint16 objIdx, uint16 param) {
|
|
|
|
Common::List<overlay>::iterator it;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
|
|
|
if (it->objIdx == objIdx && it->type == param) {
|
|
|
|
overlayList.erase(it);
|
|
|
|
return 1;
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2006-04-08 07:16:14 +00:00
|
|
|
return 0;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
/*! \brief Add new overlay sprite to the list
|
|
|
|
* \param objIdx Associate the overlay with this object
|
|
|
|
* \param param Type of new overlay
|
|
|
|
* \todo Why are x, y, width and color left uninitialized?
|
|
|
|
*/
|
|
|
|
void addOverlay(uint16 objIdx, uint16 param) {
|
|
|
|
Common::List<overlay>::iterator it;
|
|
|
|
overlay tmp;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
|
|
|
if (objectTable[it->objIdx].mask >= objectTable[objIdx].mask) {
|
|
|
|
break;
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
tmp.objIdx = objIdx;
|
|
|
|
tmp.type = param;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
overlayList.insert(it, tmp);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
/*! \brief Add new background mask overlay
|
|
|
|
* \param objIdx Associate the overlay with this object
|
|
|
|
* \param param source background index
|
|
|
|
*/
|
|
|
|
void addGfxElementA0(int16 objIdx, int16 param) {
|
|
|
|
Common::List<overlay>::iterator it;
|
|
|
|
overlay tmp;
|
|
|
|
|
|
|
|
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
|
|
|
// wtf?!
|
|
|
|
if (objectTable[it->objIdx].mask == objectTable[objIdx].mask &&
|
|
|
|
(it->type == 2 || it->type == 3)) {
|
|
|
|
break;
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
if (it != overlayList.end() && it->objIdx == objIdx && it->type == 20 && it->x == param) {
|
|
|
|
return;
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
tmp.objIdx = objIdx;
|
|
|
|
tmp.type = 20;
|
|
|
|
tmp.x = param;
|
|
|
|
tmp.y = 0;
|
|
|
|
tmp.width = 0;
|
|
|
|
tmp.color = 0;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
overlayList.insert(it, tmp);
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
/*! \brief Remove background mask overlay
|
|
|
|
* \param objIdx Remove overlay associated with this object
|
|
|
|
* \param param Remove overlay using this background
|
|
|
|
* \todo Check that it works
|
|
|
|
*/
|
|
|
|
void removeGfxElementA0(int16 objIdx, int16 param) {
|
|
|
|
Common::List<overlay>::iterator it;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
|
|
|
if (it->objIdx == objIdx && it->type == 20 && it->x == param) {
|
|
|
|
overlayList.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-23 03:45:52 +00:00
|
|
|
void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4) {
|
2006-02-22 22:40:53 +00:00
|
|
|
objectTable[objIdx].x = param1;
|
|
|
|
objectTable[objIdx].y = param2;
|
|
|
|
objectTable[objIdx].mask = param3;
|
|
|
|
objectTable[objIdx].frame = param4;
|
|
|
|
|
2008-04-21 20:51:17 +00:00
|
|
|
if (removeOverlay(objIdx, 0)) {
|
|
|
|
addOverlay(objIdx, 0);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-23 03:45:52 +00:00
|
|
|
void subObjectParam(byte objIdx, byte paramIdx, int16 newValue) {
|
2007-12-08 02:24:12 +00:00
|
|
|
addObjectParam(objIdx, paramIdx, -newValue);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2006-03-23 03:45:52 +00:00
|
|
|
void addObjectParam(byte objIdx, byte paramIdx, int16 newValue) {
|
2007-12-08 02:24:12 +00:00
|
|
|
int16 currentValue = getObjectParam(objIdx, paramIdx);
|
|
|
|
modifyObjectParam(objIdx, paramIdx, currentValue + newValue);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2006-03-23 03:45:52 +00:00
|
|
|
void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue) {
|
2006-02-22 22:40:53 +00:00
|
|
|
switch (paramIdx) {
|
2008-05-29 12:22:14 +00:00
|
|
|
case 1:
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].x = newValue;
|
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
case 2:
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].y = newValue;
|
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
case 3:
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].mask = newValue;
|
2006-02-22 22:40:53 +00:00
|
|
|
|
2008-05-29 12:22:14 +00:00
|
|
|
// TODO: Check this part against disassembly
|
2008-04-21 20:51:17 +00:00
|
|
|
if (removeOverlay(objIdx, 0)) {
|
|
|
|
addOverlay(objIdx, 0);
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
2006-04-08 07:16:14 +00:00
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
case 4:
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].frame = newValue;
|
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
case 5:
|
|
|
|
// TODO: Test if this really breaks the newspaper machine on the airport in Operation Stealth.
|
|
|
|
if (g_cine->getGameType() == Cine::GType_FW && newValue == -1) {
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].costume = globalVars[0];
|
|
|
|
} else {
|
|
|
|
objectTable[objIdx].costume = newValue;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
2006-04-08 07:16:14 +00:00
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
case 6:
|
2006-04-08 07:16:14 +00:00
|
|
|
objectTable[objIdx].part = newValue;
|
|
|
|
break;
|
2008-05-29 12:22:14 +00:00
|
|
|
default: // No-operation
|
|
|
|
break;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-07 20:24:40 +00:00
|
|
|
uint16 compareObjectParam(byte objIdx, byte type, int16 value) {
|
|
|
|
uint16 compareResult = 0;
|
2007-12-08 02:24:12 +00:00
|
|
|
int16 objectParam = getObjectParam(objIdx, type);
|
|
|
|
|
|
|
|
if (objectParam > value) {
|
|
|
|
compareResult |= kCmpGT;
|
|
|
|
} else if (objectParam < value) {
|
|
|
|
compareResult |= kCmpLT;
|
|
|
|
} else {
|
|
|
|
compareResult |= kCmpEQ;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2006-04-08 07:16:14 +00:00
|
|
|
return compareResult;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
2008-05-24 22:11:41 +00:00
|
|
|
/*! \bug In Operation Stealth, if you try to go downstairs to the sea in the
|
|
|
|
* location between bank and hotel, getObjectParam is called with paramIdx 16
|
|
|
|
* and crashes
|
|
|
|
*/
|
2006-02-23 09:12:21 +00:00
|
|
|
int16 getObjectParam(uint16 objIdx, uint16 paramIdx) {
|
2006-03-23 03:17:47 +00:00
|
|
|
assert(objIdx <= NUM_MAX_OBJECT);
|
2006-02-22 22:40:53 +00:00
|
|
|
|
|
|
|
paramIdx--;
|
|
|
|
|
2006-03-23 03:17:47 +00:00
|
|
|
assert(paramIdx <= 5);
|
2006-02-22 22:40:53 +00:00
|
|
|
|
|
|
|
switch (paramIdx) {
|
|
|
|
case 0:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].x;
|
2006-02-22 22:40:53 +00:00
|
|
|
case 1:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].y;
|
2006-02-22 22:40:53 +00:00
|
|
|
case 2:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].mask;
|
2006-02-22 22:40:53 +00:00
|
|
|
case 3:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].frame;
|
2006-02-22 22:40:53 +00:00
|
|
|
case 4:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].costume;
|
2006-02-22 22:40:53 +00:00
|
|
|
case 5:
|
2006-04-08 07:16:14 +00:00
|
|
|
return objectTable[objIdx].part;
|
2006-02-22 22:40:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2006-02-25 00:26:14 +00:00
|
|
|
|
|
|
|
} // End of namespace Cine
|