diff options
Diffstat (limited to 'object.cpp')
-rw-r--r-- | object.cpp | 312 |
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 |