2001-10-09 14:30:12 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2001 Ludvig Strigeus
|
|
|
|
*
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
2001-11-06 20:00:47 +00:00
|
|
|
* $Header$
|
2001-10-09 14:30:12 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "scumm.h"
|
|
|
|
|
|
|
|
bool Scumm::getClass(int obj, int cls) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
cls &= 0x7F;
|
|
|
|
checkRange(32,1,cls,"Class %d out of range in getClass");
|
|
|
|
|
|
|
|
return (_classData[obj] & (1<<(cls-1))) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::putClass(int obj, int cls, bool set) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
cls &= 0x7F;
|
|
|
|
checkRange(32,1,cls,"Class %d out of range in getClass");
|
|
|
|
|
|
|
|
if (set)
|
|
|
|
_classData[obj] |= (1<<(cls-1));
|
|
|
|
else
|
|
|
|
_classData[obj] &= ~(1<<(cls-1));
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getOwner(int obj) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getOwner");
|
2001-11-12 20:50:36 +00:00
|
|
|
return _objectFlagTable[obj]&OF_OWNER_MASK;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::putOwner(int act, int owner) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putOwner");
|
2001-10-09 14:30:12 +00:00
|
|
|
checkRange(15, 0, owner, "Owner %d out of range in putOwner");
|
2001-11-12 20:50:36 +00:00
|
|
|
_objectFlagTable[act] = (_objectFlagTable[act]&~OF_OWNER_MASK) | owner;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getState(int act) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in getState");
|
2001-10-09 14:30:12 +00:00
|
|
|
return _objectFlagTable[act]>>4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::putState(int act, int state) {
|
2001-10-16 10:01:48 +00:00
|
|
|
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putState");
|
2001-10-09 14:30:12 +00:00
|
|
|
checkRange(15, 0, state, "State %d out of range in putState");
|
2001-11-12 20:50:36 +00:00
|
|
|
_objectFlagTable[act] = (_objectFlagTable[act]&~OF_STATE_MASK) |
|
|
|
|
(state<<OF_STATE_SHL);
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getObjectIndex(int object) {
|
|
|
|
int i;
|
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if ((_objectFlagTable[object]&OF_OWNER_MASK)!=OF_OWNER_ROOM) {
|
2001-10-09 14:30:12 +00:00
|
|
|
for (i=0; i<_maxInventoryItems; i++)
|
|
|
|
if (_inventory[i] == object)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
for (i=_numObjectsInRoom; i>0; i--) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr==object)
|
2001-10-09 14:30:12 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::whereIsObject(int object) {
|
|
|
|
int i;
|
|
|
|
|
2001-11-07 18:10:52 +00:00
|
|
|
if (object >= _numGlobalObjects)
|
2001-11-12 20:50:36 +00:00
|
|
|
return WIO_NOT_FOUND;
|
2001-11-06 21:29:23 +00:00
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if ((_objectFlagTable[object]&OF_OWNER_MASK)!=OF_OWNER_ROOM) {
|
2001-10-09 14:30:12 +00:00
|
|
|
for (i=0; i<_maxInventoryItems; i++)
|
|
|
|
if (_inventory[i] == object)
|
2001-11-12 20:50:36 +00:00
|
|
|
return WIO_INVENTORY;
|
|
|
|
return WIO_NOT_FOUND;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i=_numObjectsInRoom; i>0; i--)
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr == object) {
|
|
|
|
if (_objs[i].fl_object_index)
|
2001-11-12 20:50:36 +00:00
|
|
|
return WIO_FLOBJECT;
|
|
|
|
return WIO_ROOM;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
2001-11-12 20:50:36 +00:00
|
|
|
return WIO_NOT_FOUND;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getObjectOrActorXY(int object) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (object <= _vars[VAR_NUM_ACTOR]) {
|
2001-10-09 14:30:12 +00:00
|
|
|
return getActorXYPos(derefActorSafe(object, "getObjectOrActorXY"));
|
|
|
|
}
|
|
|
|
switch(whereIsObject(object)) {
|
2001-11-12 20:50:36 +00:00
|
|
|
case WIO_NOT_FOUND:
|
2001-10-09 14:30:12 +00:00
|
|
|
return -1;
|
2001-11-12 20:50:36 +00:00
|
|
|
case WIO_INVENTORY:
|
|
|
|
return getActorXYPos(derefActorSafe(_objectFlagTable[object]&OF_OWNER_MASK,"getObjectOrActorXY(2)"));
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
getObjectXYPos(object);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
void Scumm::getObjectXYPos(int object) {
|
|
|
|
ObjectData *od = &_objs[getObjectIndex(object)];
|
|
|
|
int state;
|
|
|
|
byte *ptr;
|
|
|
|
ImageHeader *imhd;
|
|
|
|
int x,y;
|
|
|
|
AdjustBoxResult abr;
|
|
|
|
|
2001-10-23 19:51:50 +00:00
|
|
|
if (_majorScummVersion==6) {
|
|
|
|
state = getState(object)-1;
|
|
|
|
if (state<0)
|
|
|
|
state = 0;
|
2001-10-16 10:01:48 +00:00
|
|
|
|
2001-10-23 19:51:50 +00:00
|
|
|
if (od->fl_object_index) {
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtFlObject, od->fl_object_index);
|
2001-10-26 17:34:50 +00:00
|
|
|
ptr = findResource(MKID('OBIM'), ptr, 0);
|
2001-10-23 19:51:50 +00:00
|
|
|
} else {
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtRoom, _roomResource);
|
2001-10-23 19:51:50 +00:00
|
|
|
ptr += od->offs_obim_to_room;
|
|
|
|
}
|
2001-11-11 16:54:45 +00:00
|
|
|
assert(ptr);
|
2001-10-26 17:34:50 +00:00
|
|
|
imhd = (ImageHeader*)findResource(MKID('IMHD'), ptr, 0);
|
2001-10-23 19:51:50 +00:00
|
|
|
x = od->x_pos*8 + (int16)READ_LE_UINT16(&imhd->hotspot[state].x);
|
|
|
|
y = od->y_pos*8 + (int16)READ_LE_UINT16(&imhd->hotspot[state].y);
|
2001-10-16 10:01:48 +00:00
|
|
|
} else {
|
2001-11-06 20:00:47 +00:00
|
|
|
x = od->walk_x;
|
|
|
|
y = od->walk_y;
|
2001-10-16 10:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
abr = adjustXYToBeInBox(0, x, y);
|
|
|
|
_xPos = abr.x;
|
|
|
|
_yPos = abr.y;
|
|
|
|
_dir = od->actordir&3;
|
|
|
|
}
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
int Scumm::getObjActToObjActDist(int a, int b) {
|
|
|
|
int x,y;
|
|
|
|
Actor *acta = NULL;
|
|
|
|
Actor *actb = NULL;
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
if (a<=_vars[VAR_NUM_ACTOR])
|
2001-10-09 14:30:12 +00:00
|
|
|
acta = derefActorSafe(a, "getObjActToObjActDist");
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
if (b<=_vars[VAR_NUM_ACTOR])
|
2001-10-09 14:30:12 +00:00
|
|
|
actb = derefActorSafe(b, "getObjActToObjActDist(2)");
|
|
|
|
|
|
|
|
if (acta && actb && acta->room==actb->room && acta->room &&
|
|
|
|
acta->room != _currentRoom)
|
|
|
|
return 0xFF;
|
|
|
|
|
|
|
|
if (getObjectOrActorXY(a)==-1)
|
|
|
|
return 0xFF;
|
|
|
|
|
|
|
|
x = _xPos;
|
|
|
|
y = _yPos;
|
|
|
|
|
|
|
|
if (getObjectOrActorXY(b)==-1)
|
|
|
|
return 0xFF;
|
|
|
|
|
|
|
|
if (acta) {
|
|
|
|
AdjustBoxResult r = adjustXYToBeInBox(acta, _xPos, _yPos);
|
|
|
|
_xPos = r.x;
|
|
|
|
_yPos = r.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
y = abs(y-_yPos);
|
|
|
|
x = abs(x-_xPos);
|
|
|
|
|
|
|
|
if (y>x) x=y;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::findObject(int x, int y) {
|
|
|
|
int i,a,b;
|
|
|
|
|
|
|
|
for (i=1; i<=_numObjectsInRoom; i++) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (!_objs[i].obj_nr || getClass(_objs[i].obj_nr, 32))
|
2001-10-09 14:30:12 +00:00
|
|
|
continue;
|
|
|
|
b = i;
|
|
|
|
do {
|
2001-10-16 10:01:48 +00:00
|
|
|
a = _objs[b].parentstate;
|
|
|
|
b = _objs[b].parent;
|
2001-10-09 14:30:12 +00:00
|
|
|
if (b==0) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].x_pos <= (x>>3) &&
|
|
|
|
_objs[i].numstrips + _objs[i].x_pos > (x>>3) &&
|
|
|
|
_objs[i].y_pos <= (y>>3) &&
|
|
|
|
_objs[i].height + _objs[i].y_pos > (y>>3))
|
|
|
|
return _objs[i].obj_nr;
|
2001-10-09 14:30:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-11-12 20:50:36 +00:00
|
|
|
} while ( (_objs[b].ownerstate&OF_STATE_MASK) == a);
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::drawRoomObjects(int arg) {
|
|
|
|
int num = _numObjectsInRoom;
|
|
|
|
ObjectData *od;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
if (num==0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
do {
|
2001-10-16 10:01:48 +00:00
|
|
|
od = &_objs[num];
|
2001-11-12 20:50:36 +00:00
|
|
|
if (!od->obj_nr || !(od->ownerstate&OF_STATE_MASK))
|
2001-10-09 14:30:12 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
do {
|
2001-10-09 18:35:02 +00:00
|
|
|
a = od->parentstate;
|
|
|
|
if (!od->parent) {
|
2001-10-09 14:30:12 +00:00
|
|
|
drawObject(num, arg);
|
|
|
|
break;
|
|
|
|
}
|
2001-10-16 10:01:48 +00:00
|
|
|
od = &_objs[od->parent];
|
2001-11-12 20:50:36 +00:00
|
|
|
} while ((od->ownerstate & OF_STATE_MASK)==a);
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
} while (--num);
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint32 state_tags[] = {
|
|
|
|
MKID('IM00'),
|
|
|
|
MKID('IM01'),
|
|
|
|
MKID('IM02'),
|
|
|
|
MKID('IM03'),
|
|
|
|
MKID('IM04'),
|
|
|
|
MKID('IM05'),
|
|
|
|
MKID('IM06'),
|
|
|
|
MKID('IM07'),
|
|
|
|
MKID('IM08'),
|
|
|
|
MKID('IM09'),
|
|
|
|
MKID('IM0A'),
|
|
|
|
MKID('IM0B'),
|
|
|
|
MKID('IM0C'),
|
|
|
|
MKID('IM0D'),
|
|
|
|
MKID('IM0E'),
|
|
|
|
MKID('IM0F')
|
|
|
|
};
|
|
|
|
|
|
|
|
void Scumm::drawObject(int obj, int arg) {
|
|
|
|
ObjectData *od;
|
|
|
|
int xpos, ypos, height, width;
|
|
|
|
byte *ptr;
|
2001-10-26 17:34:50 +00:00
|
|
|
int x,a,numstrip;
|
|
|
|
int tmp;
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
if (_BgNeedsRedraw)
|
|
|
|
arg = 0;
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
_curVirtScreen = &virtscr[0];
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
od = &_objs[obj];
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
xpos = od->x_pos;
|
|
|
|
ypos = od->y_pos;
|
|
|
|
width = od->numstrips;
|
|
|
|
height = od->height;
|
|
|
|
|
|
|
|
if (width==0 || xpos > _screenEndStrip || xpos + width < _screenStartStrip)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (od->fl_object_index) {
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtFlObject, od->fl_object_index);
|
2001-10-26 17:34:50 +00:00
|
|
|
ptr = findResource(MKID('OBIM'), ptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
} else {
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtRoom, _roomResource);
|
2001-10-09 14:30:12 +00:00
|
|
|
ptr = ptr + od->offs_obim_to_room;
|
|
|
|
}
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
ptr = findResource(state_tags[getState(od->obj_nr)], ptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
if (!ptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
x = 0xFFFF;
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
for (a=numstrip=0; a<width; a++) {
|
|
|
|
tmp = xpos + a;
|
|
|
|
if (arg==1 && _screenStartStrip!=tmp)
|
2001-10-09 14:30:12 +00:00
|
|
|
continue;
|
2001-10-26 17:34:50 +00:00
|
|
|
if (arg==2 && _screenEndStrip!=tmp)
|
2001-10-09 14:30:12 +00:00
|
|
|
continue;
|
2001-10-26 17:34:50 +00:00
|
|
|
if (tmp < _screenStartStrip || tmp > _screenEndStrip)
|
2001-10-09 14:30:12 +00:00
|
|
|
continue;
|
2001-10-26 17:34:50 +00:00
|
|
|
actorDrawBits[tmp] |= 0x8000;
|
|
|
|
if (tmp < x)
|
|
|
|
x = tmp;
|
|
|
|
numstrip++;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
if (numstrip!=0)
|
|
|
|
gdi.drawBitmap(ptr, _curVirtScreen, x, ypos<<3, height<<3, x-xpos, numstrip, true);
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
// _drawBmpY = ypos << 3;
|
|
|
|
// gdi._numLinesToProcess = height << 3;
|
|
|
|
// _drawBmpX = x;
|
|
|
|
// drawBmp(ptr, x - xpos, b, 1, "Object", od->obj_nr);
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::loadRoomObjects() {
|
|
|
|
int i,j;
|
|
|
|
ObjectData *od;
|
|
|
|
byte *ptr;
|
|
|
|
uint16 obim_id;
|
2001-10-26 17:34:50 +00:00
|
|
|
byte *room;
|
2001-10-09 14:30:12 +00:00
|
|
|
ImageHeader *imhd;
|
|
|
|
RoomHeader *roomhdr;
|
|
|
|
|
|
|
|
CodeHeader *cdhd;
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
CHECK_HEAP
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-11-05 19:21:49 +00:00
|
|
|
room = getResourceAddress(rtRoom, _roomResource);
|
2001-10-26 17:34:50 +00:00
|
|
|
roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
|
|
|
|
_numObjectsInRoom = READ_LE_UINT16(&roomhdr->numObjects);
|
|
|
|
|
|
|
|
if (_numObjectsInRoom == 0)
|
|
|
|
return;
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_numObjectsInRoom > _numLocalObjects)
|
|
|
|
error("More than %d objects in room %d", _numLocalObjects, _roomResource);
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
od = &_objs[1];
|
2001-10-26 17:34:50 +00:00
|
|
|
for (i=0; i<_numObjectsInRoom; i++,od++) {
|
|
|
|
ptr = findResource(MKID('OBCD'), room, i);
|
2001-10-09 14:30:12 +00:00
|
|
|
if (ptr==NULL)
|
|
|
|
error("Room %d missing object code block(s)", _roomResource);
|
|
|
|
|
|
|
|
od->offs_obcd_to_room = ptr - room;
|
2001-10-26 17:34:50 +00:00
|
|
|
cdhd = (CodeHeader*)findResource(MKID('CDHD'), ptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
od->obj_nr = READ_LE_UINT16(&cdhd->obj_id);
|
|
|
|
|
|
|
|
#ifdef DUMP_SCRIPTS
|
|
|
|
do {
|
|
|
|
char buf[32];
|
|
|
|
sprintf(buf,"roomobj-%d-",_roomResource);
|
|
|
|
dumpResource(buf, od->obj_nr, ptr);
|
|
|
|
} while (0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
for (i=0; i<_numObjectsInRoom; i++) {
|
|
|
|
ptr = findResource(MKID('OBIM'), room, i);
|
2001-10-09 14:30:12 +00:00
|
|
|
if (ptr==NULL)
|
|
|
|
error("Room %d missing image blocks(s)", _roomResource);
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
imhd = (ImageHeader*)findResource(MKID('IMHD'), ptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
obim_id = READ_LE_UINT16(&imhd->obj_id);
|
|
|
|
|
|
|
|
for(j=1; j<=_numObjectsInRoom; j++) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[j].obj_nr==obim_id)
|
|
|
|
_objs[j].offs_obim_to_room = ptr - room;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
od = &_objs[1];
|
2001-10-09 14:30:12 +00:00
|
|
|
for (i=1; i<=_numObjectsInRoom; i++,od++) {
|
2001-11-06 20:00:47 +00:00
|
|
|
ptr = room + od->offs_obcd_to_room;
|
2001-10-26 17:34:50 +00:00
|
|
|
cdhd = (CodeHeader*)findResource(MKID('CDHD'), ptr,0);
|
2001-11-06 20:00:47 +00:00
|
|
|
od->obj_nr = READ_LE_UINT16(&cdhd->obj_id);
|
2001-10-16 10:01:48 +00:00
|
|
|
|
2001-10-23 19:51:50 +00:00
|
|
|
if (_majorScummVersion == 6) {
|
2001-11-06 20:00:47 +00:00
|
|
|
od->numstrips = READ_LE_UINT16(&cdhd->v6.w)>>3;
|
|
|
|
od->height = READ_LE_UINT16(&cdhd->v6.h)>>3;
|
|
|
|
od->x_pos = ((int16)READ_LE_UINT16(&cdhd->v6.x))>>3;
|
|
|
|
od->y_pos = ((int16)READ_LE_UINT16(&cdhd->v6.y))>>3;
|
2001-10-23 19:51:50 +00:00
|
|
|
if (cdhd->v6.flags == 0x80) {
|
2001-11-06 20:00:47 +00:00
|
|
|
od->parentstate = 1<<4;
|
2001-10-23 19:51:50 +00:00
|
|
|
} else {
|
2001-11-12 20:50:36 +00:00
|
|
|
od->parentstate = (cdhd->v6.flags&0xF)<<OF_STATE_SHL;
|
2001-10-23 19:51:50 +00:00
|
|
|
}
|
2001-11-06 20:00:47 +00:00
|
|
|
od->parent = cdhd->v6.parent;
|
|
|
|
od->actordir = cdhd->v6.actordir;
|
2001-10-09 14:30:12 +00:00
|
|
|
} else {
|
2001-11-06 20:00:47 +00:00
|
|
|
od->numstrips = cdhd->v5.w;
|
|
|
|
od->height = cdhd->v5.h;
|
|
|
|
od->x_pos = cdhd->v5.x;
|
|
|
|
od->y_pos = cdhd->v5.y;
|
2001-10-23 19:51:50 +00:00
|
|
|
if (cdhd->v5.flags == 0x80) {
|
2001-11-06 20:00:47 +00:00
|
|
|
od->parentstate = 1<<4;
|
2001-10-23 19:51:50 +00:00
|
|
|
} else {
|
2001-11-12 20:50:36 +00:00
|
|
|
od->parentstate = (cdhd->v5.flags&0xF)<<OF_STATE_SHL;
|
2001-10-23 19:51:50 +00:00
|
|
|
}
|
2001-11-06 20:00:47 +00:00
|
|
|
od->parent = cdhd->v5.parent;
|
|
|
|
od->walk_x = READ_LE_UINT16(&cdhd->v5.walk_x);
|
|
|
|
od->walk_y = READ_LE_UINT16(&cdhd->v5.walk_y);
|
|
|
|
od->actordir = cdhd->v5.actordir;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
2001-11-06 20:00:47 +00:00
|
|
|
od->fl_object_index = 0;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
CHECK_HEAP
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::fixObjectFlags() {
|
|
|
|
int i;
|
2001-10-16 10:01:48 +00:00
|
|
|
ObjectData *od = &_objs[1];
|
2001-10-09 14:30:12 +00:00
|
|
|
for (i=1; i<=_numObjectsInRoom; i++,od++) {
|
|
|
|
od->ownerstate = _objectFlagTable[od->obj_nr];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::processDrawQue() {
|
|
|
|
int i, j;
|
|
|
|
for (i=0; i<_drawObjectQueNr; i++) {
|
|
|
|
j = _drawObjectQue[i];
|
|
|
|
if (j)
|
|
|
|
drawObject(j,0);
|
|
|
|
}
|
|
|
|
_drawObjectQueNr = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::clearOwnerOf(int obj) {
|
|
|
|
int i,j;
|
|
|
|
uint16 *a;
|
|
|
|
byte *ptr;
|
|
|
|
|
|
|
|
stopObjectScript(obj);
|
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if (getOwner(obj)==OF_OWNER_ROOM) {
|
2001-10-09 14:30:12 +00:00
|
|
|
i = 0;
|
|
|
|
do {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr==obj) {
|
|
|
|
if (!_objs[i].fl_object_index)
|
2001-10-09 14:30:12 +00:00
|
|
|
return;
|
2001-11-05 19:21:49 +00:00
|
|
|
nukeResource(rtFlObject, _objs[i].fl_object_index);
|
2001-10-16 10:01:48 +00:00
|
|
|
_objs[i].obj_nr = 0;
|
|
|
|
_objs[i].fl_object_index = 0;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
} while(++i <= _numObjectsInRoom);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (i=1; i<_maxInventoryItems; i++) {
|
|
|
|
if (_inventory[i] == obj) {
|
|
|
|
j = whereIsObject(obj);
|
2001-11-12 20:50:36 +00:00
|
|
|
if (j==WIO_INVENTORY) {
|
2001-11-05 19:21:49 +00:00
|
|
|
nukeResource(rtInventory, i);
|
2001-10-09 14:30:12 +00:00
|
|
|
_inventory[i] = 0;
|
|
|
|
}
|
2001-10-26 17:34:50 +00:00
|
|
|
a = &_inventory[1];
|
|
|
|
for (i=1; i < _maxInventoryItems-1; i++,a++) {
|
|
|
|
if (!a[0] && a[1]) {
|
|
|
|
a[0] = a[1];
|
|
|
|
a[1] = 0;
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtInventory, i+1);
|
2001-10-09 14:30:12 +00:00
|
|
|
_baseInventoryItems[i] = _baseInventoryItems[i+1];
|
2001-10-26 17:34:50 +00:00
|
|
|
_baseInventoryItems[i+1] = 0;
|
2001-10-09 14:30:12 +00:00
|
|
|
/* TODO: some wacky write is done here */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::removeObjectFromRoom(int obj) {
|
|
|
|
int i,cnt;
|
|
|
|
uint16 *ptr;
|
|
|
|
|
|
|
|
for(i=1; i<=_numObjectsInRoom; i++) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr==obj) {
|
|
|
|
if (_objs[i].numstrips != 0) {
|
|
|
|
ptr = &actorDrawBits[_objs[i].x_pos];
|
|
|
|
cnt = _objs[i].numstrips;
|
2001-10-09 14:30:12 +00:00
|
|
|
do {
|
|
|
|
*ptr++ |= 0x8000;
|
|
|
|
} while (--cnt);
|
|
|
|
}
|
|
|
|
_BgNeedsRedraw = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::addObjectToDrawQue(int object) {
|
|
|
|
_drawObjectQue[_drawObjectQueNr++] = object;
|
2001-11-06 21:41:56 +00:00
|
|
|
if (_drawObjectQueNr > sizeof(_drawObjectQue)/sizeof(_drawObjectQue[0]))
|
2001-10-09 14:30:12 +00:00
|
|
|
error("Draw Object Que overflow");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::clearDrawObjectQueue() {
|
|
|
|
_drawObjectQueNr = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte *Scumm::getObjOrActorName(int obj) {
|
|
|
|
byte *objptr;
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
if (obj <= _vars[VAR_NUM_ACTOR])
|
2001-10-09 14:30:12 +00:00
|
|
|
return getActorName(derefActorSafe(obj, "getObjOrActorName"));
|
|
|
|
|
|
|
|
objptr = getObjectAddress(obj);
|
|
|
|
if (objptr==NULL)
|
|
|
|
return (byte*)" ";
|
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
return findResource(MKID('OBNA'), objptr, 0) + 8;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 Scumm::getOBCDOffs(int object) {
|
|
|
|
int i;
|
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if ((_objectFlagTable[object]&OF_OWNER_MASK)!=OF_OWNER_ROOM)
|
2001-10-09 14:30:12 +00:00
|
|
|
return 0;
|
|
|
|
for (i=_numObjectsInRoom; i>0; i--) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr == object) {
|
|
|
|
if (_objs[i].fl_object_index!=0)
|
2001-10-09 14:30:12 +00:00
|
|
|
return 8;
|
2001-10-16 10:01:48 +00:00
|
|
|
return _objs[i].offs_obcd_to_room;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte *Scumm::getObjectAddress(int obj) {
|
|
|
|
int i;
|
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if ((_objectFlagTable[obj]&OF_OWNER_MASK)!=OF_OWNER_ROOM) {
|
2001-10-09 14:30:12 +00:00
|
|
|
for(i=0; i<_maxInventoryItems; i++) {
|
|
|
|
if (_inventory[i] == obj)
|
2001-11-05 19:21:49 +00:00
|
|
|
return getResourceAddress(rtInventory, i);
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for(i=_numObjectsInRoom; i>0; --i) {
|
2001-10-16 10:01:48 +00:00
|
|
|
if (_objs[i].obj_nr==obj) {
|
|
|
|
if (_objs[i].fl_object_index)
|
2001-11-05 19:21:49 +00:00
|
|
|
return getResourceAddress(rtFlObject, _objs[i].fl_object_index)+8;
|
|
|
|
return getResourceAddress(rtRoom, _roomResource) + _objs[i].offs_obcd_to_room;
|
2001-10-09 14:30:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-11-06 20:00:47 +00:00
|
|
|
void Scumm::addObjectToInventory(uint obj, uint room) {
|
2001-10-09 14:30:12 +00:00
|
|
|
int i, slot;
|
|
|
|
byte *ptr,*obcdptr;
|
|
|
|
uint32 size,cdoffs;
|
|
|
|
int numobj;
|
2001-10-26 17:34:50 +00:00
|
|
|
byte *roomptr;
|
2001-10-09 14:30:12 +00:00
|
|
|
CodeHeader *cdhd;
|
|
|
|
RoomHeader *roomhdr;
|
|
|
|
|
|
|
|
debug(1,"Adding object %d from room %d into inventory", obj, room);
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
CHECK_HEAP
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-11-12 20:50:36 +00:00
|
|
|
if (whereIsObject(obj)==WIO_FLOBJECT) {
|
2001-10-09 14:30:12 +00:00
|
|
|
i = getObjectIndex(obj);
|
2001-11-05 19:21:49 +00:00
|
|
|
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64;
|
2001-10-09 14:30:12 +00:00
|
|
|
size = READ_BE_UINT32_UNALIGNED(ptr+4);
|
|
|
|
slot = getInventorySlot();
|
|
|
|
_inventory[slot] = obj;
|
2001-11-05 19:21:49 +00:00
|
|
|
createResource(rtInventory, slot, size);
|
|
|
|
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64;
|
|
|
|
memcpy(getResourceAddress(rtInventory, slot), ptr, size);
|
2001-10-16 10:01:48 +00:00
|
|
|
CHECK_HEAP
|
2001-10-09 14:30:12 +00:00
|
|
|
return;
|
|
|
|
}
|
2001-11-05 19:21:49 +00:00
|
|
|
// ensureResourceLoaded(rtRoom, room);
|
|
|
|
roomptr = getResourceAddress(rtRoom, room);
|
2001-10-26 17:34:50 +00:00
|
|
|
roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
numobj = READ_LE_UINT16(&roomhdr->numObjects);
|
|
|
|
if (numobj==0)
|
|
|
|
error("addObjectToInventory: No object found in room %d", room);
|
2001-11-06 21:41:56 +00:00
|
|
|
if (numobj > _numLocalObjects)
|
|
|
|
error("addObjectToInventory: More (%d) than %d objects in room %d", numobj, _numLocalObjects, room);
|
2001-10-09 14:30:12 +00:00
|
|
|
|
2001-10-26 17:34:50 +00:00
|
|
|
for (i=0; i<numobj; i++) {
|
|
|
|
obcdptr = findResource(MKID('OBCD'), roomptr, i);
|
2001-10-09 14:30:12 +00:00
|
|
|
if(obcdptr==NULL)
|
|
|
|
error("addObjectToInventory: Not enough code blocks in room %d", room);
|
2001-10-26 17:34:50 +00:00
|
|
|
cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcdptr, 0);
|
2001-10-09 14:30:12 +00:00
|
|
|
if ( READ_LE_UINT16(&cdhd->obj_id) == obj) {
|
|
|
|
cdoffs = obcdptr - roomptr;
|
|
|
|
size = READ_BE_UINT32_UNALIGNED(obcdptr+4);
|
|
|
|
slot = getInventorySlot();
|
|
|
|
_inventory[slot] = obj;
|
2001-11-05 19:21:49 +00:00
|
|
|
createResource(rtInventory, slot, size);
|
|
|
|
obcdptr = getResourceAddress(rtRoom, room) + cdoffs;
|
|
|
|
memcpy(getResourceAddress(rtInventory,slot),obcdptr,size);
|
2001-10-16 10:01:48 +00:00
|
|
|
CHECK_HEAP
|
2001-10-09 14:30:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error("addObjectToInventory: Object %d not found in room %d", obj, room);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getInventorySlot() {
|
|
|
|
int i;
|
|
|
|
for (i=1; i<=_maxInventoryItems; i++) {
|
|
|
|
if (_inventory[i]==0)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
error("Inventory full, %d max items", _maxInventoryItems);
|
|
|
|
}
|
|
|
|
|
2001-10-16 10:01:48 +00:00
|
|
|
void Scumm::setOwnerOf(int obj, int owner) {
|
|
|
|
ScriptSlot *ss;
|
|
|
|
if (owner==0) {
|
|
|
|
clearOwnerOf(obj);
|
|
|
|
ss = &vm.slot[_currentScript];
|
2001-11-12 20:50:36 +00:00
|
|
|
if (ss->where==WIO_INVENTORY && _inventory[ss->number]==obj) {
|
2001-10-16 10:01:48 +00:00
|
|
|
putOwner(obj, 0);
|
|
|
|
runHook(0);
|
|
|
|
stopObjectCode();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
putOwner(obj, owner);
|
|
|
|
runHook(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getObjX(int obj) {
|
|
|
|
if (obj <= _vars[VAR_NUM_ACTOR]) {
|
|
|
|
return derefActorSafe(obj,"getObjX")->x;
|
|
|
|
} else {
|
2001-11-12 20:50:36 +00:00
|
|
|
if (whereIsObject(obj)==WIO_NOT_FOUND)
|
2001-10-16 10:01:48 +00:00
|
|
|
return -1;
|
|
|
|
getObjectOrActorXY(obj);
|
|
|
|
return _xPos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getObjY(int obj) {
|
|
|
|
if (obj <= _vars[VAR_NUM_ACTOR]) {
|
|
|
|
return derefActorSafe(obj,"getObjY")->y;
|
|
|
|
} else {
|
2001-11-12 20:50:36 +00:00
|
|
|
if (whereIsObject(obj)==WIO_NOT_FOUND)
|
2001-10-16 10:01:48 +00:00
|
|
|
return -1;
|
|
|
|
getObjectOrActorXY(obj);
|
|
|
|
return _yPos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getObjDir(int obj) {
|
|
|
|
if (obj <= _vars[VAR_NUM_ACTOR]) {
|
|
|
|
return derefActorSafe(obj,"getObjDir")->facing;
|
|
|
|
} else {
|
|
|
|
getObjectXYPos(obj);
|
|
|
|
return _dir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::findInventory(int owner, int index) {
|
|
|
|
int count = 1, i, obj;
|
|
|
|
for (i=0; i!=_maxInventoryItems; i++) {
|
|
|
|
obj = _inventory[i];
|
|
|
|
if (obj && getOwner(obj)==owner && count++ == index)
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getInventoryCount(int owner) {
|
|
|
|
int i,obj;
|
|
|
|
int count = 0;
|
|
|
|
for (i=0; i!=_maxInventoryItems; i++) {
|
|
|
|
obj = _inventory[i];
|
|
|
|
if (obj && getOwner(obj) == owner)
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::setObjectState(int obj, int state, int x, int y) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = getObjectIndex(obj);
|
|
|
|
if (i==-1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x != -1) {
|
|
|
|
_objs[i].x_pos = x;
|
2001-11-05 19:21:49 +00:00
|
|
|
_objs[i].y_pos = y;
|
2001-10-16 10:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
addObjectToDrawQue(i);
|
|
|
|
putState(obj, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int getDist(int x, int y, int x2, int y2) {
|
|
|
|
int a = abs(y-y2);
|
|
|
|
int b = abs(x-x2);
|
|
|
|
if (a>b)
|
|
|
|
return a;
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scumm::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f) {
|
|
|
|
int i,j;
|
|
|
|
int x,y;
|
|
|
|
int x2,y2;
|
|
|
|
|
|
|
|
j = i = 0xFF;
|
|
|
|
|
|
|
|
if (is_obj_1) {
|
|
|
|
if (getObjectOrActorXY(b)==-1)
|
|
|
|
return -1;
|
|
|
|
if (b < _vars[VAR_NUM_ACTOR])
|
|
|
|
i = derefActorSafe(b, "unkObjProc1")->scalex;
|
|
|
|
x = _xPos;
|
|
|
|
y = _yPos;
|
|
|
|
} else {
|
|
|
|
x = b;
|
|
|
|
y = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_obj_2) {
|
|
|
|
if (getObjectOrActorXY(e)==-1)
|
|
|
|
return -1;
|
|
|
|
if (e < _vars[VAR_NUM_ACTOR])
|
|
|
|
j = derefActorSafe(e, "unkObjProc1(2)")->scalex;
|
|
|
|
x2 = _xPos;
|
|
|
|
y2 = _yPos;
|
|
|
|
} else {
|
|
|
|
x2 = e;
|
|
|
|
y2 = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return getDist(x,y,x2,y2) * 0xFF / ((i + j)>>1);
|
|
|
|
}
|
2001-11-06 20:00:47 +00:00
|
|
|
|
|
|
|
void Scumm::setCursorImg(uint room, uint img) {
|
|
|
|
byte *ptr;
|
|
|
|
int index;
|
|
|
|
CodeHeader *cdhd;
|
|
|
|
ImageHeader *imhd;
|
|
|
|
int w,h;
|
|
|
|
byte *roomptr,*obcd,*obim,*dataptr,*bomp;
|
|
|
|
RoomHeader *rmhd;
|
|
|
|
int i,numobj;
|
|
|
|
uint32 size;
|
|
|
|
|
|
|
|
if (getObjectIndex(img)!=-1) {
|
|
|
|
obim = getObjectAddress(img);
|
|
|
|
ptr = obim + READ_BE_UINT32(&((ImageHeader*)obim)->size);
|
|
|
|
cdhd = (CodeHeader*)findResource(MKID('CDHD'), obim, 0);
|
|
|
|
imhd = (ImageHeader*)findResource(MKID('IMHD'), ptr, 0);
|
|
|
|
} else {
|
|
|
|
ensureResourceLoaded(1, room);
|
|
|
|
roomptr = getResourceAddress(1, room);
|
|
|
|
rmhd = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0);
|
|
|
|
|
|
|
|
numobj = READ_LE_UINT16(&rmhd->numObjects);
|
|
|
|
for(i=0; ;i++) {
|
|
|
|
if (i>=numobj)
|
|
|
|
error("setCursorImg: object %d code not found in room %d", img, room);
|
|
|
|
|
|
|
|
obcd = findResource(MKID('OBCD'), roomptr, i);
|
|
|
|
if (obcd==NULL)
|
|
|
|
error("setCursorImg: not enough code blocks in room %d", room);
|
|
|
|
cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcd, 0);
|
|
|
|
if (READ_LE_UINT16(&cdhd->obj_id) == img)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=0; ;i++) {
|
|
|
|
if (i>=numobj)
|
|
|
|
error("setCursorImg: object %d image not found in room %d", img, room);
|
|
|
|
obim = findResource(MKID('OBIM'), roomptr, i);
|
|
|
|
if (obim==NULL)
|
|
|
|
error("setCursorImg: not enough image blocks in room %d", room);
|
|
|
|
imhd = (ImageHeader*)findResource(MKID('IMHD'), obim, 0);
|
|
|
|
if (READ_LE_UINT16(&imhd->obj_id) == img)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setCursorHotspot2(
|
|
|
|
READ_LE_UINT16(&imhd->hotspot[0].x),
|
|
|
|
READ_LE_UINT16(&imhd->hotspot[0].y));
|
|
|
|
|
|
|
|
w = READ_LE_UINT16(&cdhd->v6.w)>>3;
|
|
|
|
h = READ_LE_UINT16(&cdhd->v6.h)>>3;
|
|
|
|
|
|
|
|
size = READ_BE_UINT32(&cdhd->size);
|
2001-11-07 18:10:52 +00:00
|
|
|
if (size > sizeof(_grabbedCursor))
|
2001-11-06 20:00:47 +00:00
|
|
|
error("setCursorImg: Cursor image too large");
|
|
|
|
|
|
|
|
dataptr = findResource(MKID('IM01'),obim, 0);
|
|
|
|
|
|
|
|
if ((bomp = findResource(MKID('BOMP'), dataptr, 0)) != NULL)
|
|
|
|
useBompCursor(bomp, w, h);
|
|
|
|
else
|
|
|
|
useIm01Cursor(dataptr, w, h);
|
|
|
|
|
|
|
|
}
|
2001-11-11 16:54:45 +00:00
|
|
|
|
|
|
|
void Scumm::nukeFlObjects(int min, int max) {
|
|
|
|
ObjectData *od;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
warning("nukeFlObjects(%d,%d)", min, max);
|
|
|
|
|
|
|
|
for (i=_numObjectsInRoom,od=_objs; --i>=0; od++)
|
|
|
|
if (od->fl_object_index && od->obj_nr>=min && od->obj_nr<=max) {
|
|
|
|
nukeResource(rtFlObject, od->fl_object_index);
|
|
|
|
od->obj_nr = 0;
|
|
|
|
od->fl_object_index = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h) {
|
|
|
|
EnqueuedObject *eo;
|
|
|
|
ObjectData *od;
|
|
|
|
|
|
|
|
if (_enqueuePos==sizeof(_enqueuedObjects)/sizeof(_enqueuedObjects[0]))
|
|
|
|
error("enqueueObject: overflow");
|
|
|
|
|
|
|
|
eo = &_enqueuedObjects[_enqueuePos++];
|
|
|
|
eo->a = a;
|
|
|
|
eo->b = _enqueue_b;
|
|
|
|
eo->c = _enqueue_c;
|
|
|
|
eo->d = _enqueue_d;
|
|
|
|
eo->e = _enqueue_e;
|
|
|
|
eo->x = b;
|
|
|
|
eo->y = c;
|
|
|
|
if (d==0) {
|
|
|
|
od = &_objs[getObjectIndex(a)];
|
|
|
|
eo->width = od->numstrips<<3;
|
|
|
|
} else {
|
|
|
|
eo->width = d;
|
|
|
|
}
|
|
|
|
if (e==0) {
|
|
|
|
od = &_objs[getObjectIndex(a)];
|
|
|
|
eo->height = od->height<<3;
|
|
|
|
} else {
|
|
|
|
eo->height = e;
|
|
|
|
}
|
|
|
|
|
|
|
|
eo->j = f;
|
|
|
|
eo->k = g;
|
|
|
|
eo->l = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::drawEnqueuedObjects() {
|
|
|
|
EnqueuedObject *eo;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
eo = _enqueuedObjects;
|
|
|
|
for(i=0; i < _enqueuePos; i++,eo++) {
|
|
|
|
drawEnqueuedObject(eo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Scumm::drawEnqueuedObject(EnqueuedObject *eo) {
|
|
|
|
VirtScreen *vs;
|
|
|
|
byte *roomptr,*bomp;
|
|
|
|
byte *ptr;
|
|
|
|
int index;
|
|
|
|
ObjectData *od;
|
|
|
|
int width,height;
|
|
|
|
byte *outptr;
|
|
|
|
int x,y;
|
|
|
|
byte *dataptr;
|
|
|
|
|
|
|
|
vs = &virtscr[0];
|
|
|
|
|
|
|
|
_lastXstart = vs->xstart;
|
|
|
|
|
|
|
|
if (eo->l==0) {
|
|
|
|
roomptr = getResourceAddress(1, _roomResource);
|
|
|
|
index = getObjectIndex(eo->a);
|
|
|
|
ptr = roomptr + _objs[index].offs_obim_to_room;
|
|
|
|
} else if (eo->a!=0) {
|
|
|
|
od = &_objs[getObjectIndex(eo->a)];
|
|
|
|
ptr = getResourceAddress(rtFlObject, od->fl_object_index);
|
|
|
|
ptr = findResource(MKID('OBIM'), ptr, 0);
|
|
|
|
} else {
|
|
|
|
warning("drawEnqueuedObject: invalid");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr = findResource(MKID('IM01'), ptr, 0);
|
|
|
|
bomp = findResource(MKID('BOMP'), ptr, 0);
|
|
|
|
|
|
|
|
width = READ_LE_UINT16(&((BompHeader*)bomp)->width);
|
|
|
|
height = READ_LE_UINT16(&((BompHeader*)bomp)->height);
|
|
|
|
|
|
|
|
outptr = getResourceAddress(rtBuffer, vs->number+1) + vs->xstart;
|
|
|
|
|
|
|
|
x = eo->x;
|
|
|
|
y = eo->y;
|
|
|
|
|
|
|
|
if (eo->a) {
|
|
|
|
dataptr = bomp + 18;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
updateDirtyRect(vs->number, x, x+width,y,y+height,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::removeEnqueuedObjects() {
|
|
|
|
EnqueuedObject *eo;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
eo = _enqueuedObjects;
|
|
|
|
for(i=0; i < _enqueuePos; i++,eo++) {
|
|
|
|
removeEnqueuedObject(eo);
|
|
|
|
}
|
|
|
|
|
|
|
|
clearEnqueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scumm::removeEnqueuedObject(EnqueuedObject *eo) {
|
|
|
|
restoreBG(eo->x, eo->y, eo->x + eo->width, eo->y + eo->height);
|
|
|
|
}
|
|
|
|
|