aboutsummaryrefslogtreecommitdiff
path: root/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'object.cpp')
-rw-r--r--object.cpp312
1 files changed, 242 insertions, 70 deletions
diff --git a/object.cpp b/object.cpp
index e47b2239e2..79bea00fbb 100644
--- a/object.cpp
+++ b/object.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/09 18:35:02 strigeus
* fixed object parent bug
* fixed some signed/unsigned comparisons
@@ -32,7 +35,7 @@
#include "scumm.h"
bool Scumm::getClass(int obj, int cls) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getClass");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
cls &= 0x7F;
checkRange(32,1,cls,"Class %d out of range in getClass");
@@ -41,7 +44,7 @@ bool Scumm::getClass(int obj, int cls) {
}
void Scumm::putClass(int obj, int cls, bool set) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getClass");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
cls &= 0x7F;
checkRange(32,1,cls,"Class %d out of range in getClass");
@@ -53,23 +56,23 @@ void Scumm::putClass(int obj, int cls, bool set) {
}
int Scumm::getOwner(int obj) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getOwner");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getOwner");
return _objectFlagTable[obj]&0xF;
}
void Scumm::putOwner(int act, int owner) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in putOwner");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putOwner");
checkRange(15, 0, owner, "Owner %d out of range in putOwner");
_objectFlagTable[act] = (_objectFlagTable[act]&0xF0) | owner;
}
int Scumm::getState(int act) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in getState");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in getState");
return _objectFlagTable[act]>>4;
}
void Scumm::putState(int act, int state) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in putState");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putState");
checkRange(15, 0, state, "State %d out of range in putState");
_objectFlagTable[act] = (_objectFlagTable[act]&0x0F) | (state<<4);
}
@@ -84,7 +87,7 @@ int Scumm::getObjectIndex(int object) {
return -1;
} else {
for (i=_numObjectsInRoom; i>0; i--) {
- if (objs[i].obj_nr==object)
+ if (_objs[i].obj_nr==object)
return i;
}
return -1;
@@ -102,8 +105,8 @@ int Scumm::whereIsObject(int object) {
}
for (i=_numObjectsInRoom; i>0; i--)
- if (objs[i].obj_nr == object) {
- if (objs[i].fl_object_index)
+ if (_objs[i].obj_nr == object) {
+ if (_objs[i].fl_object_index)
return 4;
return 1;
}
@@ -111,7 +114,7 @@ int Scumm::whereIsObject(int object) {
}
int Scumm::getObjectOrActorXY(int object) {
- if (object <= vm.vars[VAR_NUM_ACTOR]) {
+ if (object <= _vars[VAR_NUM_ACTOR]) {
return getActorXYPos(derefActorSafe(object, "getObjectOrActorXY"));
}
switch(whereIsObject(object)) {
@@ -124,24 +127,56 @@ int Scumm::getObjectOrActorXY(int object) {
return 0;
}
+#if defined(DOTT)
+void Scumm::getObjectXYPos(int object) {
+ ObjectData *od = &_objs[getObjectIndex(object)];
+ int state;
+ byte *ptr;
+ ImageHeader *imhd;
+ int x,y;
+ AdjustBoxResult abr;
+
+ state = getState(object)-1;
+ if (state<0)
+ state = 0;
+
+ if (od->fl_object_index) {
+ ptr = getResourceAddress(0xD, od->fl_object_index);
+ ptr = findResource(MKID('OBIM'), ptr);
+ } else {
+ ptr = getResourceAddress(1, _roomResource);
+ ptr += od->offs_obim_to_room;
+ }
+
+ imhd = (ImageHeader*)findResource2(MKID('IMHD'), ptr);
+ x = od->x_pos*8 + imhd->hotspot[state].x;
+ y = od->y_pos*8 + imhd->hotspot[state].y;
+
+ abr = adjustXYToBeInBox(0, x, y);
+ _xPos = abr.x;
+ _yPos = abr.y;
+ _dir = od->actordir&3;
+}
+#else
void Scumm::getObjectXYPos(int object) {
- ObjectData *od = &objs[getObjectIndex(object)];
+ ObjectData *od = &_objs[getObjectIndex(object)];
AdjustBoxResult abr;
abr = adjustXYToBeInBox(0, od->cdhd_10, od->cdhd_12);
_xPos = abr.x;
_yPos = abr.y;
_dir = od->actordir&3;
}
+#endif
int Scumm::getObjActToObjActDist(int a, int b) {
int x,y;
Actor *acta = NULL;
Actor *actb = NULL;
- if (a<=vm.vars[VAR_NUM_ACTOR])
+ if (a<=_vars[VAR_NUM_ACTOR])
acta = derefActorSafe(a, "getObjActToObjActDist");
- if (b<=vm.vars[VAR_NUM_ACTOR])
+ if (b<=_vars[VAR_NUM_ACTOR])
actb = derefActorSafe(b, "getObjActToObjActDist(2)");
if (acta && actb && acta->room==actb->room && acta->room &&
@@ -175,21 +210,21 @@ int Scumm::findObject(int x, int y) {
int i,a,b;
for (i=1; i<=_numObjectsInRoom; i++) {
- if (!objs[i].obj_nr || getClass(objs[i].obj_nr, 32))
+ if (!_objs[i].obj_nr || getClass(_objs[i].obj_nr, 32))
continue;
b = i;
do {
- a = objs[b].parentstate;
- b = objs[b].parent;
+ a = _objs[b].parentstate;
+ b = _objs[b].parent;
if (b==0) {
- 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;
+ 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;
break;
}
- } while ( (objs[b].ownerstate&0xF0) == a);
+ } while ( (_objs[b].ownerstate&0xF0) == a);
}
return 0;
}
@@ -203,7 +238,7 @@ void Scumm::drawRoomObjects(int arg) {
return;
do {
- od = &objs[num];
+ od = &_objs[num];
if (!od->obj_nr || !(od->ownerstate&0xF0))
continue;
@@ -213,7 +248,7 @@ void Scumm::drawRoomObjects(int arg) {
drawObject(num, arg);
break;
}
- od = &objs[od->parent];
+ od = &_objs[od->parent];
} while ((od->ownerstate & 0xF0)==a);
} while (--num);
@@ -249,7 +284,7 @@ void Scumm::drawObject(int obj, int arg) {
gdi.virtScreen = 0;
- od = &objs[obj];
+ od = &_objs[obj];
xpos = od->x_pos;
ypos = od->y_pos;
@@ -308,7 +343,7 @@ void Scumm::loadRoomObjects() {
CodeHeader *cdhd;
- checkHeap();
+ CHECK_HEAP
room = getResourceAddress(1, _roomResource);
roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room);
@@ -318,12 +353,12 @@ void Scumm::loadRoomObjects() {
if (_numObjectsInRoom == 0)
return;
- if (_numObjectsInRoom > 200)
- error("More than %d objects in room %d", 200, _roomResource);
+ if (_numObjectsInRoom > _numLocalObjects)
+ error("More than %d objects in room %d", _numLocalObjects, _roomResource);
tmp_room = room;
- od = &objs[1];
+ od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
ptr = findResource(MKID('OBCD'), tmp_room);
if (ptr==NULL)
@@ -353,40 +388,49 @@ void Scumm::loadRoomObjects() {
obim_id = READ_LE_UINT16(&imhd->obj_id);
for(j=1; j<=_numObjectsInRoom; j++) {
- if (objs[j].obj_nr==obim_id)
- objs[j].offs_obim_to_room = ptr - room;
+ if (_objs[j].obj_nr==obim_id)
+ _objs[j].offs_obim_to_room = ptr - room;
}
tmp_room = NULL;
}
- od = &objs[1];
+ od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
- ptr = room + objs[i].offs_obcd_to_room;
+ ptr = room + _objs[i].offs_obcd_to_room;
cdhd = (CodeHeader*)findResource2(MKID('CDHD'), ptr);
- objs[i].obj_nr = READ_LE_UINT16(&cdhd->obj_id);
- objs[i].numstrips = cdhd->w;
- objs[i].height = cdhd->h;
- objs[i].x_pos = cdhd->x;
- objs[i].y_pos = cdhd->y;
-
+ _objs[i].obj_nr = READ_LE_UINT16(&cdhd->obj_id);
+
+#if defined(DOTT)
+ _objs[i].numstrips = cdhd->w>>3;
+ _objs[i].height = cdhd->h>>3;
+ _objs[i].x_pos = cdhd->x>>3;
+ _objs[i].y_pos = cdhd->y>>3;
+#else
+ _objs[i].numstrips = cdhd->w;
+ _objs[i].height = cdhd->h;
+ _objs[i].x_pos = cdhd->x;
+ _objs[i].y_pos = cdhd->y;
+#endif
if (cdhd->flags == 0x80) {
- objs[i].parentstate = 1<<4;
+ _objs[i].parentstate = 1<<4;
} else {
- objs[i].parentstate = (cdhd->flags&0xF)<<4;
+ _objs[i].parentstate = (cdhd->flags&0xF)<<4;
}
- objs[i].parent = cdhd->unk1;
- objs[i].cdhd_10 = READ_LE_UINT16(&cdhd->unk2);
- objs[i].cdhd_12 = READ_LE_UINT16(&cdhd->unk3);
- objs[i].actordir = cdhd->unk4;
- objs[i].fl_object_index = 0;
+ _objs[i].parent = cdhd->parent;
+#if !defined(DOTT)
+ _objs[i].cdhd_10 = READ_LE_UINT16(&cdhd->unk2);
+ _objs[i].cdhd_12 = READ_LE_UINT16(&cdhd->unk3);
+#endif
+ _objs[i].actordir = cdhd->actordir;
+ _objs[i].fl_object_index = 0;
}
- checkHeap();
+ CHECK_HEAP
}
void Scumm::fixObjectFlags() {
int i;
- ObjectData *od = &objs[1];
+ ObjectData *od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
od->ownerstate = _objectFlagTable[od->obj_nr];
}
@@ -412,12 +456,12 @@ void Scumm::clearOwnerOf(int obj) {
if (getOwner(obj)==0xF) {
i = 0;
do {
- if (objs[i].obj_nr==obj) {
- if (!objs[i].fl_object_index)
+ if (_objs[i].obj_nr==obj) {
+ if (!_objs[i].fl_object_index)
return;
- nukeResource(0xD, objs[i].fl_object_index);
- objs[i].obj_nr = 0;
- objs[i].fl_object_index = 0;
+ nukeResource(0xD, _objs[i].fl_object_index);
+ _objs[i].obj_nr = 0;
+ _objs[i].fl_object_index = 0;
}
} while(++i <= _numObjectsInRoom);
return;
@@ -449,10 +493,10 @@ void Scumm::removeObjectFromRoom(int obj) {
uint16 *ptr;
for(i=1; i<=_numObjectsInRoom; i++) {
- if (objs[i].obj_nr==obj) {
- if (objs[i].numstrips != 0) {
- ptr = &actorDrawBits[objs[i].x_pos];
- cnt = objs[i].numstrips;
+ if (_objs[i].obj_nr==obj) {
+ if (_objs[i].numstrips != 0) {
+ ptr = &actorDrawBits[_objs[i].x_pos];
+ cnt = _objs[i].numstrips;
do {
*ptr++ |= 0x8000;
} while (--cnt);
@@ -476,7 +520,7 @@ void Scumm::clearDrawObjectQueue() {
byte *Scumm::getObjOrActorName(int obj) {
byte *objptr;
- if (obj <= vm.vars[VAR_NUM_ACTOR])
+ if (obj <= _vars[VAR_NUM_ACTOR])
return getActorName(derefActorSafe(obj, "getObjOrActorName"));
objptr = getObjectAddress(obj);
@@ -492,10 +536,10 @@ uint32 Scumm::getOBCDOffs(int object) {
if ((_objectFlagTable[object]&0xF)!=0xF)
return 0;
for (i=_numObjectsInRoom; i>0; i--) {
- if (objs[i].obj_nr == object) {
- if (objs[i].fl_object_index!=0)
+ if (_objs[i].obj_nr == object) {
+ if (_objs[i].fl_object_index!=0)
return 8;
- return objs[i].offs_obcd_to_room;
+ return _objs[i].offs_obcd_to_room;
}
}
return 0;
@@ -511,10 +555,10 @@ byte *Scumm::getObjectAddress(int obj) {
}
} else {
for(i=_numObjectsInRoom; i>0; --i) {
- if (objs[i].obj_nr==obj) {
- if (objs[i].fl_object_index)
- return getResourceAddress(0xD, objs[i].fl_object_index)+8;
- return getResourceAddress(1, _roomResource) + objs[i].offs_obcd_to_room;
+ if (_objs[i].obj_nr==obj) {
+ if (_objs[i].fl_object_index)
+ return getResourceAddress(0xD, _objs[i].fl_object_index)+8;
+ return getResourceAddress(1, _roomResource) + _objs[i].offs_obcd_to_room;
}
}
}
@@ -532,18 +576,18 @@ void Scumm::addObjectToInventory(int obj, int room) {
debug(1,"Adding object %d from room %d into inventory", obj, room);
- checkHeap();
+ CHECK_HEAP
if (whereIsObject(obj)==4) {
i = getObjectIndex(obj);
- ptr = getResourceAddress(0xD, objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64;
size = READ_BE_UINT32_UNALIGNED(ptr+4);
slot = getInventorySlot();
_inventory[slot] = obj;
createResource(5, slot, size);
- ptr = getResourceAddress(0xD, objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64;
memcpy(getResourceAddress(5, slot), ptr, size);
- checkHeap();
+ CHECK_HEAP
return;
}
ensureResourceLoaded(1, room);
@@ -569,7 +613,7 @@ void Scumm::addObjectToInventory(int obj, int room) {
createResource(5, slot, size);
obcdptr = getResourceAddress(1, room) + cdoffs;
memcpy(getResourceAddress(5,slot),obcdptr,size);
- checkHeap();
+ CHECK_HEAP
return;
}
tmp_roomptr = NULL;
@@ -587,3 +631,131 @@ int Scumm::getInventorySlot() {
error("Inventory full, %d max items", _maxInventoryItems);
}
+void Scumm::setOwnerOf(int obj, int owner) {
+ ScriptSlot *ss;
+ if (owner==0) {
+ clearOwnerOf(obj);
+ ss = &vm.slot[_currentScript];
+ if (ss->type==0 && _inventory[ss->number]==obj) {
+ 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 {
+ if (whereIsObject(obj)==-1)
+ return -1;
+ getObjectOrActorXY(obj);
+ return _xPos;
+ }
+}
+
+int Scumm::getObjY(int obj) {
+ if (obj <= _vars[VAR_NUM_ACTOR]) {
+ return derefActorSafe(obj,"getObjY")->y;
+ } else {
+ if (whereIsObject(obj)==-1)
+ 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;
+}
+
+#if defined(DOTT)
+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;
+ _objs[i].x_pos = y;
+ }
+
+ 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);
+}
+#endif \ No newline at end of file