--- Original object.cpp Mon Nov 26 14:54:00 2001 +++ object.cpp Mon Nov 26 14:57:25 2001 @@ -753,10 +753,10 @@ 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); + obcd = getObjectAddress(img); + obim = obcd + READ_BE_UINT32(&((ImageHeader*)obcd)->size); + cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcd, 0); + imhd = (ImageHeader*)findResource(MKID('IMHD'), obim, 0); } else { ensureResourceLoaded(1, room); roomptr = getResourceAddress(1, room); --- Original scumm.h Thu Nov 15 07:09:39 2001 +++ scumm.h Mon Nov 26 11:35:56 2001 @@ -55,6 +55,10 @@ uint16 scale; } GCC_PACK; +struct FlObjectHeader { + uint32 tag, size; +} GCC_PACK; + struct ResHeader { uint32 size; } GCC_PACK; @@ -1495,6 +1499,7 @@ void unlock(int type, int i); void heapClear(int mode); void unkHeapProc2(int a, int b); + int getFlObjectSlot(); void loadFlObject(int a, int b); void setPalColor(int index, int r, int g, int b); void darkenPalette(int a, int b, int c, int d, int e); --- Original resource.cpp Thu Nov 15 07:09:39 2001 +++ resource.cpp Mon Nov 26 18:57:05 2001 @@ -817,8 +817,116 @@ warning("unkHeapProc2: not implemented"); } -void Scumm::loadFlObject(int a, int b) { - warning("loadFlObject(%d,%d):not implemented", a, b); +int Scumm::getFlObjectSlot() { + int i; + for (i=1; i<_maxFLObject; i++) { + if (_baseFLObject[i] == NULL) { + return i; + } + } + error("Flobject table full, %d max items", _maxFLObject); +} + + + +void Scumm::loadFlObject(int object, int room) { + byte *ptr; + int index; + CodeHeader *cdhd; + ImageHeader *imhd; + int w,h; + byte *roomptr,*obcd,*obim,*dataptr,*bomp, *flobptr, *codeptr, *curptr, *imptr; + RoomHeader *rmhd; + int i,numobj; + uint32 size; + int slot; + int cdoffs, imoffs, cursize; + FlObjectHeader *flobhd; + CodeHeader* codehdr; + + debug(1,"Loading FlObject %d from room %d", object, room); + + ensureResourceLoaded(rtRoom, room); + roomptr = getResourceAddress(rtRoom, room); + rmhd = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0); + + numobj = READ_LE_UINT16(&rmhd->numObjects); + for(i=0; ;i++) { + if (i>=numobj) + error("loadFlobject: object %d code not found in room %d", object, room); + + obcd = findResource(MKID('OBCD'), roomptr, i); + if (obcd==NULL) + error("loadFlobject: not enough code blocks in room %d", room); + cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcd, 0); + if (READ_LE_UINT16(&cdhd->obj_id) == object) { + cdoffs = obcd - roomptr; + cursize = READ_BE_UINT32_UNALIGNED(obcd+4); + break; + } + } + + for(i=0; ;i++) { + if (i>=numobj) + error("loadFlobject: object %d image not found in room %d", object, room); + obim = findResource(MKID('OBIM'), roomptr, i); + if (obim==NULL) + error("loadFlobject: not enough image blocks in room %d", room); + imhd = (ImageHeader*)findResource(MKID('IMHD'), obim, 0); + if (READ_LE_UINT16(&imhd->obj_id) == object) { + imoffs = obim - roomptr; + cursize += READ_BE_UINT32_UNALIGNED(obim+4); + break; + } + } + + ++_numObjectsInRoom; + if (_numObjectsInRoom >= _numLocalObjects) { + error("Too many objects in current room"); + } + + ObjectData *od = &_objs[_numObjectsInRoom]; + + slot = getFlObjectSlot(); + cursize += sizeof(FlObjectHeader); + + od->fl_object_index = slot; + od->unk_3 = room; + createResource(rtFlObject, slot, cursize); + + flobhd = (FlObjectHeader*)getResourceAddress(rtFlObject, slot); + flobhd->tag = MKID('FLOB'); + flobhd->size = TO_BE_32(cursize); //swapped + + codeptr = getResourceAddress(rtRoom, room) + cdoffs; + size = READ_BE_UINT32_UNALIGNED(codeptr+4); + + flobptr = getResourceAddress(rtFlObject, slot); + curptr = flobptr + sizeof(FlObjectHeader); + memcpy(curptr, codeptr, size); + curptr += size; + + imptr = getResourceAddress(rtRoom, room) + imoffs; + size = READ_BE_UINT32_UNALIGNED(imptr+4); + memcpy(curptr, imptr, size); + + codeptr = getResourceAddress(rtRoom, room) + cdoffs; + codehdr = (CodeHeader*)findResource(MKID('CDHD'), codeptr, 0); + + od->obj_nr = READ_LE_UINT16(&codehdr->obj_id); + od->numstrips = READ_LE_UINT16(&codehdr->v6.w)>>3; + od->height = READ_LE_UINT16(&codehdr->v6.h)>>3; + od->x_pos = ((int16)READ_LE_UINT16(&codehdr->v6.x))>>3; + od->y_pos = ((int16)READ_LE_UINT16(&codehdr->v6.y))>>3; + if (codehdr->v6.flags == 0x80) { + od->parentstate = 1<<4; + } else { + od->parentstate = (codehdr->v6.flags&0xF)<parent = codehdr->v6.parent; + od->actordir = codehdr->v6.actordir; + od->offs_obcd_to_room = 0; + od->offs_obim_to_room = 0; } void Scumm::readMAXS() {