New method of local object management. Buggy, segfaults on the Part 1 screen and I don't know why yet..

svn-id: r6416
This commit is contained in:
James Brown 2003-01-12 07:30:17 +00:00
parent 6bf93e41c5
commit ef9a8d0714
5 changed files with 76 additions and 33 deletions

View file

@ -110,6 +110,9 @@ int Scumm::getObjectIndex(int object)
{ {
int i; int i;
if (object < 1)
return -1;
/* OF_OWNER_ROOM should be 0xFF for full throttle, else 0xF */ /* OF_OWNER_ROOM should be 0xFF for full throttle, else 0xF */
if (_objectOwnerTable[object] != OF_OWNER_ROOM) { if (_objectOwnerTable[object] != OF_OWNER_ROOM) {
for (i = 0; i < _maxInventoryItems; i++) for (i = 0; i < _maxInventoryItems; i++)
@ -117,7 +120,7 @@ int Scumm::getObjectIndex(int object)
return i; return i;
return -1; return -1;
} else { } else {
for (i = _numObjectsInRoom; i > 0; i--) { for (i = _numLocalObjects; i > 0; i--) {
if (_objs[i].obj_nr == object) if (_objs[i].obj_nr == object)
return i; return i;
} }
@ -141,6 +144,9 @@ int Scumm::whereIsObject(int object)
if (object >= _numGlobalObjects) if (object >= _numGlobalObjects)
return WIO_NOT_FOUND; return WIO_NOT_FOUND;
if (object < 1)
return WIO_NOT_FOUND;
if (_objectOwnerTable[object] != OF_OWNER_ROOM) { if (_objectOwnerTable[object] != OF_OWNER_ROOM) {
for (i = 0; i < _maxInventoryItems; i++) for (i = 0; i < _maxInventoryItems; i++)
if (_inventory[i] == object) if (_inventory[i] == object)
@ -148,7 +154,7 @@ int Scumm::whereIsObject(int object)
return WIO_NOT_FOUND; return WIO_NOT_FOUND;
} }
for (i = _numObjectsInRoom; i > 0; i--) for (i = _numLocalObjects; i > 0; i--)
if (_objs[i].obj_nr == object) { if (_objs[i].obj_nr == object) {
if (_objs[i].fl_object_index) if (_objs[i].fl_object_index)
return WIO_FLOBJECT; return WIO_FLOBJECT;
@ -268,8 +274,8 @@ int Scumm::findObject(int x, int y)
int i, b; int i, b;
byte a; byte a;
for (i = 1; i <= _numObjectsInRoom; i++) { for (i = 1; i <= _numLocalObjects; i++) {
if (!_objs[i].obj_nr || getClass(_objs[i].obj_nr, 32)) if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, 32))
continue; continue;
b = i; b = i;
do { do {
@ -292,7 +298,7 @@ void Scumm::drawRoomObject(int i, int arg)
byte a; byte a;
od = &_objs[i]; od = &_objs[i];
if (!od->obj_nr || !od->state) if ((i < 1) || (od->obj_nr < 1) || !od->state)
return; return;
do { do {
@ -310,11 +316,13 @@ void Scumm::drawRoomObjects(int arg)
int i; int i;
if (_features & GF_DRAWOBJ_OTHER_ORDER) { if (_features & GF_DRAWOBJ_OTHER_ORDER) {
for (i = 1; i <= _numObjectsInRoom; i++) for (i = 1; i <= _numLocalObjects; i++)
drawRoomObject(i, arg); if (_objs[i].obj_nr > 0)
drawRoomObject(i, arg);
} else { } else {
for (i = _numObjectsInRoom; i != 0; i--) for (i = _numLocalObjects; i != 0; i--)
drawRoomObject(i, arg); if (_objs[i].obj_nr > 0)
drawRoomObject(i, arg);
} }
} }
@ -350,6 +358,9 @@ void Scumm::drawObject(int obj, int arg)
od = &_objs[obj]; od = &_objs[obj];
if (od->obj_nr == 0)
return;
xpos = od->x_pos >> 3; xpos = od->x_pos >> 3;
ypos = od->y_pos; ypos = od->y_pos;
@ -439,14 +450,22 @@ void Scumm::loadRoomObjects()
if (_numObjectsInRoom > _numLocalObjects) if (_numObjectsInRoom > _numLocalObjects)
error("More than %d objects in room %d", _numLocalObjects, _roomResource); error("More than %d objects in room %d", _numLocalObjects, _roomResource);
od = &_objs[1];
if (_features & GF_AFTER_V8) if (_features & GF_AFTER_V8)
searchptr = rootptr = getResourceAddress(rtRoomScripts, _roomResource); searchptr = rootptr = getResourceAddress(rtRoomScripts, _roomResource);
else else
searchptr = rootptr = room; searchptr = rootptr = room;
assert(searchptr); assert(searchptr);
for (i = 0; i < _numObjectsInRoom; i++, od++) { // Clear out old room objects (FIXME: Locking/FlObjects stuff?)
for (i = 0; i <= _numLocalObjects; i++) {
_objs[i].obj_nr = 0;
_objs[i].fl_object_index = 0;
}
// Load in new room objects
for (i = 0; i < _numObjectsInRoom; i++) {
od = &_objs[findLocalObjectSlot()];
ptr = findResource(MKID('OBCD'), searchptr); ptr = findResource(MKID('OBCD'), searchptr);
if (ptr == NULL) if (ptr == NULL)
error("Room %d missing object code block(s)", _roomResource); error("Room %d missing object code block(s)", _roomResource);
@ -489,15 +508,17 @@ void Scumm::loadRoomObjects()
else else
obim_id = READ_LE_UINT16(&imhd->old.obj_id); obim_id = READ_LE_UINT16(&imhd->old.obj_id);
for (j = 1; j <= _numObjectsInRoom; j++) { for (j = 1; j <= _numLocalObjects; j++) {
if (_objs[j].obj_nr == obim_id) if (_objs[j].obj_nr == obim_id)
_objs[j].OBIMoffset = ptr - room; _objs[j].OBIMoffset = ptr - room;
} }
searchptr = NULL; searchptr = NULL;
} }
for (i = 1; i <= _numObjectsInRoom; i++) { // ENDERFIXME: Switch this one over to numLocals also
setupRoomObject(&_objs[i], room); for (i = 1; i <= _numLocalObjects; i++) {
if (_objs[i].obj_nr)
setupRoomObject(&_objs[i], room);
} }
CHECK_HEAP CHECK_HEAP
@ -524,9 +545,10 @@ void Scumm::loadRoomObjectsSmall()
if (_numObjectsInRoom > _numLocalObjects) if (_numObjectsInRoom > _numLocalObjects)
error("More than %d objects in room %d", _numLocalObjects, _roomResource); error("More than %d objects in room %d", _numLocalObjects, _roomResource);
od = &_objs[1];
searchptr = room; searchptr = room;
for (i = 0; i < _numObjectsInRoom; i++, od++) { for (i = 0; i < _numObjectsInRoom; i++) {
od = &_objs[findLocalObjectSlot()];
ptr = findResourceSmall(MKID('OBCD'), searchptr); ptr = findResourceSmall(MKID('OBCD'), searchptr);
if (ptr == NULL) if (ptr == NULL)
error("Room %d missing object code block(s)", _roomResource); error("Room %d missing object code block(s)", _roomResource);
@ -551,15 +573,17 @@ void Scumm::loadRoomObjectsSmall()
obim_id = READ_LE_UINT16(ptr + 6); obim_id = READ_LE_UINT16(ptr + 6);
for (j = 1; j <= _numObjectsInRoom; j++) { for (j = 1; j <= _numLocalObjects; j++) {
if (_objs[j].obj_nr == obim_id) if (_objs[j].obj_nr == obim_id)
_objs[j].OBIMoffset = ptr - room; _objs[j].OBIMoffset = ptr - room;
} }
searchptr = NULL; searchptr = NULL;
} }
for (i = 1; i <= _numObjectsInRoom; i++) { // ENDERFIXME: Switch to numLocals
setupRoomObject(&_objs[i], room); for (i = 1; i <= _numLocalObjects; i++) {
if (_objs[i].obj_nr)
setupRoomObject(&_objs[i], room);
} }
CHECK_HEAP CHECK_HEAP
@ -676,8 +700,9 @@ void Scumm::fixObjectFlags()
{ {
int i; int i;
ObjectData *od = &_objs[1]; ObjectData *od = &_objs[1];
for (i = 1; i <= _numObjectsInRoom; i++, od++) { for (i = 1; i <= _numLocalObjects; i++, od++) {
od->state = _objectStateTable[od->obj_nr]; if (od->obj_nr > 0)
od->state = _objectStateTable[od->obj_nr];
} }
} }
@ -709,7 +734,7 @@ void Scumm::clearOwnerOf(int obj)
_objs[i].obj_nr = 0; _objs[i].obj_nr = 0;
_objs[i].fl_object_index = 0; _objs[i].fl_object_index = 0;
} }
} while (++i <= _numObjectsInRoom); } while (++i <= _numLocalObjects);
return; return;
} }
@ -739,7 +764,7 @@ void Scumm::removeObjectFromRoom(int obj)
int i, cnt; int i, cnt;
uint32 *ptr; uint32 *ptr;
for (i = 1; i <= _numObjectsInRoom; i++) { for (i = 1; i <= _numLocalObjects; i++) {
if (_objs[i].obj_nr == (uint16)obj) { if (_objs[i].obj_nr == (uint16)obj) {
if (_objs[i].width != 0) { if (_objs[i].width != 0) {
ptr = &gfxUsageBits[_objs[i].x_pos >> 3]; ptr = &gfxUsageBits[_objs[i].x_pos >> 3];
@ -806,7 +831,7 @@ uint32 Scumm::getOBCDOffs(int object)
if (_objectOwnerTable[object] != OF_OWNER_ROOM) if (_objectOwnerTable[object] != OF_OWNER_ROOM)
return 0; return 0;
for (i = _numObjectsInRoom; i > 0; i--) { for (i = _numLocalObjects; i > 0; i--) {
if (_objs[i].obj_nr == object) { if (_objs[i].obj_nr == object) {
if (_objs[i].fl_object_index != 0) if (_objs[i].fl_object_index != 0)
return 8; return 8;
@ -826,7 +851,7 @@ byte *Scumm::getOBCDFromObject(int obj)
return getResourceAddress(rtInventory, i); return getResourceAddress(rtInventory, i);
} }
} else { } else {
for (i = _numObjectsInRoom; i > 0; --i) { for (i = _numLocalObjects; i > 0; --i) {
if (_objs[i].obj_nr == obj) { if (_objs[i].obj_nr == obj) {
if (_objs[i].fl_object_index) if (_objs[i].fl_object_index)
return getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8; return getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8;
@ -1234,7 +1259,7 @@ void Scumm::nukeFlObjects(int min, int max)
warning("nukeFlObjects(%d,%d)", min, max); warning("nukeFlObjects(%d,%d)", min, max);
for (i = _numObjectsInRoom, od = _objs; --i >= 0; od++) for (i = _numLocalObjects, od = _objs; --i >= 0; od++)
if (od->fl_object_index && od->obj_nr >= min && od->obj_nr <= max) { if (od->fl_object_index && od->obj_nr >= min && od->obj_nr <= max) {
nukeResource(rtFlObject, od->fl_object_index); nukeResource(rtFlObject, od->fl_object_index);
od->obj_nr = 0; od->obj_nr = 0;
@ -1596,6 +1621,20 @@ void Scumm::removeBlastObject(BlastObject *eo)
updateDirtyRect(0, left, right, top, bottom, 0x40000000); updateDirtyRect(0, left, right, top, bottom, 0x40000000);
} }
int Scumm::findLocalObjectSlot()
{
int i;
for (i = 1; i <= _numLocalObjects; i++) {
if (!_objs[i].obj_nr) {
printf("Returning slot %d\n", i);
return i;
}
}
return -1;
}
int Scumm::findFlObjectSlot() int Scumm::findFlObjectSlot()
{ {
int i; int i;
@ -1610,7 +1649,7 @@ int Scumm::findFlObjectSlot()
void Scumm::loadFlObject(uint object, uint room) void Scumm::loadFlObject(uint object, uint room)
{ {
FindObjectInRoom foir; FindObjectInRoom foir;
int slot; int slot, objslot;
ObjectData *od; ObjectData *od;
byte *flob, *roomptr; byte *flob, *roomptr;
uint32 obcd_size, obim_size, flob_size; uint32 obcd_size, obim_size, flob_size;
@ -1623,9 +1662,10 @@ void Scumm::loadFlObject(uint object, uint room)
findObjectInRoom(&foir, foImageHeader | foCodeHeader, object, room); findObjectInRoom(&foir, foImageHeader | foCodeHeader, object, room);
// Add an entry for the new floating object in the local object table // Add an entry for the new floating object in the local object table
if (++_numObjectsInRoom > _numLocalObjects) if (!(objslot = findLocalObjectSlot()))
error("loadFlObject: Local Object Table overflow"); error("loadFlObject: Local Object Table overflow");
od = &_objs[_numObjectsInRoom];
od = &_objs[objslot];
// Setup sizes // Setup sizes
obcd_size = READ_BE_UINT32_UNALIGNED(foir.obcd + 4); obcd_size = READ_BE_UINT32_UNALIGNED(foir.obcd + 4);

View file

@ -732,12 +732,14 @@ void Scumm::killScriptsAndResources()
} }
/* Nuke FL objects */ /* Nuke FL objects */
// ENDERFIXME
/*
i = 0; i = 0;
do { do {
if (_objs[i].fl_object_index) if (_objs[i].fl_object_index)
nukeResource(rtFlObject, _objs[i].fl_object_index); nukeResource(rtFlObject, _objs[i].fl_object_index);
} while (++i <= _numObjectsInRoom); } while (++i <= _numObjectsInRoom);
*/
/* Nuke local object names */ /* Nuke local object names */
if (_newNames) { if (_newNames) {
for (i = 0; i < _numNewNames; i++) { for (i = 0; i < _numNewNames; i++) {

View file

@ -805,9 +805,9 @@ void Scumm_v5::o5_drawObject()
w = od->width; w = od->width;
h = od->height; h = od->height;
i = _numObjectsInRoom; i = _numLocalObjects;
do { do {
if (_objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height == h) if (_objs[i].obj_nr && _objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height == h)
putState(_objs[i].obj_nr, 0); putState(_objs[i].obj_nr, 0);
} while (--i); } while (--i);

View file

@ -561,6 +561,7 @@ public:
void loadFlObject(uint object, uint room); void loadFlObject(uint object, uint room);
void nukeFlObjects(int min, int max); void nukeFlObjects(int min, int max);
int findFlObjectSlot(); int findFlObjectSlot();
int findLocalObjectSlot();
void addObjectToInventory(uint obj, uint room); void addObjectToInventory(uint obj, uint room);
void fixObjectFlags(); void fixObjectFlags();
bool getClass(int obj, int cls); bool getClass(int obj, int cls);

View file

@ -319,7 +319,7 @@ void Scumm::setVerbObject(uint room, uint object, uint verb)
error("Can't grab verb image from flobject"); error("Can't grab verb image from flobject");
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
for (i = _numObjectsInRoom; i > 0; i--) { for (i = _numLocalObjects; i > 0; i--) {
if (_objs[i].obj_nr == object) { if (_objs[i].obj_nr == object) {
findObjectInRoom(&foir, foImageHeader, object, room); findObjectInRoom(&foir, foImageHeader, object, room);
size = READ_LE_UINT32(foir.obim); size = READ_LE_UINT32(foir.obim);