Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

void Scumm::ScummEngine::setupRoomSubBlocks (  )  [protected, virtual, inherited]

Init some static room data after a room has been loaded. E.g. the room dimension, the offset to the graphics data, the room scripts, the offset to the room palette and other things which won't be changed late on. So it is possible to call this after loading a savegame.

Reimplemented in Scumm::ScummEngine_v3old.

Definition at line 241 of file room.cpp.

References Scumm::ScummEngine::_gdi, Scumm::GameSettings::features, Scumm::GameSettings::heversion, Scumm::GameSettings::id, and Scumm::GameSettings::version.

Referenced by Scumm::ScummEngine::startScene().

                                     {
      int i;
      const byte *ptr;
      byte *roomptr, *searchptr, *roomResPtr = 0;
      const RoomHeader *rmhd;

      _ENCD_offs = 0;
      _EXCD_offs = 0;
      _EPAL_offs = 0;
      _CLUT_offs = 0;
      _PALS_offs = 0;

      // Determine the room and room script base address
      roomResPtr = roomptr = getResourceAddress(rtRoom, _roomResource);
      if (_game.version == 8)
            roomResPtr = getResourceAddress(rtRoomScripts, _roomResource);
      if (!roomptr || !roomResPtr)
            error("Room %d: data not found (" __FILE__  ":%d)", _roomResource, __LINE__);

      //
      // Determine the room dimensions (width/height)
      //
      rmhd = (const RoomHeader *)findResourceData(MKID_BE('RMHD'), roomptr);

      if (_game.version == 8) {
            _roomWidth = READ_LE_UINT32(&(rmhd->v8.width));
            _roomHeight = READ_LE_UINT32(&(rmhd->v8.height));
            _numObjectsInRoom = (byte)READ_LE_UINT32(&(rmhd->v8.numObjects));
      } else if (_game.version == 7) {
            _roomWidth = READ_LE_UINT16(&(rmhd->v7.width));
            _roomHeight = READ_LE_UINT16(&(rmhd->v7.height));
            _numObjectsInRoom = (byte)READ_LE_UINT16(&(rmhd->v7.numObjects));
      } else {
            _roomWidth = READ_LE_UINT16(&(rmhd->old.width));
            _roomHeight = READ_LE_UINT16(&(rmhd->old.height));
            _numObjectsInRoom = (byte)READ_LE_UINT16(&(rmhd->old.numObjects));
      }

      //
      // Find the room image data
      //
      if (_game.version == 8) {
            _IM00_offs = getObjectImage(roomptr, 1) - roomptr;
      } else if (_game.features & GF_SMALL_HEADER) {
            _IM00_offs = findResourceData(MKID_BE('IM00'), roomptr) - roomptr;
      } else if (_game.heversion >= 70) {
            byte *roomImagePtr = getResourceAddress(rtRoomImage, _roomResource);
            _IM00_offs = findResource(MKID_BE('IM00'), roomImagePtr) - roomImagePtr;
      } else {
            _IM00_offs = findResource(MKID_BE('IM00'), findResource(MKID_BE('RMIM'), roomptr)) - roomptr;
      }

      //
      // Look for an exit script
      //
      ptr = findResourceData(MKID_BE('EXCD'), roomResPtr);
      if (ptr)
            _EXCD_offs = ptr - roomResPtr;
      if (_dumpScripts && _EXCD_offs)
            dumpResource("exit-", _roomResource, roomResPtr + _EXCD_offs - _resourceHeaderSize, -1);

      //
      // Look for an entry script
      //
      ptr = findResourceData(MKID_BE('ENCD'), roomResPtr);
      if (ptr)
            _ENCD_offs = ptr - roomResPtr;
      if (_dumpScripts && _ENCD_offs)
            dumpResource("entry-", _roomResource, roomResPtr + _ENCD_offs - _resourceHeaderSize, -1);

      //
      // Setup local scripts
      //

      // Determine the room script base address
      roomResPtr = roomptr = getResourceAddress(rtRoom, _roomResource);
      if (_game.version == 8)
            roomResPtr = getResourceAddress(rtRoomScripts, _roomResource);
      searchptr = roomResPtr;

      memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets));

      if (_game.features & GF_SMALL_HEADER) {
            ResourceIterator localScriptIterator(searchptr, true);
            while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
                  int id = 0;
                  ptr += _resourceHeaderSize;   /* skip tag & size */
                  id = ptr[0];

                  if (_dumpScripts) {
                        char buf[32];
                        sprintf(buf, "room-%d-", _roomResource);
                        dumpResource(buf, id, ptr - _resourceHeaderSize);
                  }

                  _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomptr;
            }
      } else if (_game.heversion >= 90) {
            ResourceIterator localScriptIterator2(searchptr, false);
            while ((ptr = localScriptIterator2.findNext(MKID_BE('LSC2'))) != NULL) {
                  int id = 0;

                  ptr += _resourceHeaderSize;   /* skip tag & size */

                  id = READ_LE_UINT32(ptr);

                  assertRange(_numGlobalScripts, id, _numLocalScripts + _numGlobalScripts, "local script");
                  _localScriptOffsets[id - _numGlobalScripts] = ptr + 4 - roomResPtr;

                  if (_dumpScripts) {
                        char buf[32];
                        sprintf(buf, "room-%d-", _roomResource);
                        dumpResource(buf, id, ptr - _resourceHeaderSize);
                  }
            }

            ResourceIterator localScriptIterator(searchptr, false);
            while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
                  int id = 0;

                  ptr += _resourceHeaderSize;   /* skip tag & size */

                  id = ptr[0];
                  _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomResPtr;

                  if (_dumpScripts) {
                        char buf[32];
                        sprintf(buf, "room-%d-", _roomResource);
                        dumpResource(buf, id, ptr - _resourceHeaderSize);
                  }
            }

      } else {
            ResourceIterator localScriptIterator(searchptr, false);
            while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
                  int id = 0;

                  ptr += _resourceHeaderSize;   /* skip tag & size */

                  if (_game.version == 8) {
                        id = READ_LE_UINT32(ptr);
                        assertRange(_numGlobalScripts, id, _numLocalScripts + _numGlobalScripts, "local script");
                        _localScriptOffsets[id - _numGlobalScripts] = ptr + 4 - roomResPtr;
                  } else if (_game.version == 7) {
                        id = READ_LE_UINT16(ptr);
                        assertRange(_numGlobalScripts, id, _numLocalScripts + _numGlobalScripts, "local script");
                        _localScriptOffsets[id - _numGlobalScripts] = ptr + 2 - roomResPtr;
                  } else {
                        id = ptr[0];
                        _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomResPtr;
                  }

                  if (_dumpScripts) {
                        char buf[32];
                        sprintf(buf, "room-%d-", _roomResource);
                        dumpResource(buf, id, ptr - _resourceHeaderSize);
                  }
            }
      }

      // Locate the EGA palette (currently unused).
      ptr = findResourceData(MKID_BE('EPAL'), roomptr);
      if (ptr)
            _EPAL_offs = ptr - roomptr;

      // Locate the standard room palette (for V3-V5 games).
      ptr = findResourceData(MKID_BE('CLUT'), roomptr);
      if (ptr)
            _CLUT_offs = ptr - roomptr;

      // Locate the standard room palettes (for V6+ games).
      if (_game.version >= 6) {
            ptr = findResource(MKID_BE('PALS'), roomptr);
            if (ptr) {
                  _PALS_offs = ptr - roomptr;
            }
      }

      // Transparent color
      byte trans;
      if (_game.version == 8)
            trans = (byte)READ_LE_UINT32(&(rmhd->v8.transparency));
      else {
            ptr = findResourceData(MKID_BE('TRNS'), roomptr);
            if (ptr)
                  trans = ptr[0];
            else
                  trans = 255;
      }

      // Actor Palette in HE 70 games
      if (_game.heversion == 70) {
            ptr = findResourceData(MKID_BE('REMP'), roomptr);
            if (ptr) {
                  for (i = 0; i < 256; i++)
                        _HEV7ActorPalette[i] = *ptr++;
            } else {
                  for (i = 0; i < 256; i++)
                        _HEV7ActorPalette[i] = i;
            }
      }


      // WORKAROUND bug #1074444: The dreaded DOTT "Can't get teeth" bug
      // makes it impossible to go on playing w/o cheating in some way.
      // It's not quite clear what causes it, but the effect is that object
      // 182, the teeth, are still in class 32 (kObjectClassUntouchable),
      // when they shouldn't be. Luckily, bitvar69 is set to 1 if and only if
      // the teeth are trapped and have not yet been taken by the player. So
      // we can make use of that fact to fix the object class of obj 182.
      if (_game.id == GID_TENTACLE && _roomResource == 26 && readVar(0x8000 + 69)
                  && getClass(182, kObjectClassUntouchable)) {
            putClass(182, kObjectClassUntouchable, 0);
      }

      _gdi->roomChanged(roomptr);
      _gdi->setTransparentColor(trans);
}


Generated by  Doxygen 1.6.0   Back to index