diff options
author | Max Horn | 2003-06-26 00:47:39 +0000 |
---|---|---|
committer | Max Horn | 2003-06-26 00:47:39 +0000 |
commit | 3c296b36b7a2cbf9bd049e65810f1d5c43fe6573 (patch) | |
tree | 7ff5ab22bd2e6476d14156040505738dbc80f309 /scumm | |
parent | 7f3118f8d864f6d0beec385cb5776979581d6e2a (diff) | |
download | scummvm-rg350-3c296b36b7a2cbf9bd049e65810f1d5c43fe6573.tar.gz scummvm-rg350-3c296b36b7a2cbf9bd049e65810f1d5c43fe6573.tar.bz2 scummvm-rg350-3c296b36b7a2cbf9bd049e65810f1d5c43fe6573.zip |
added ResourceIterator, replacing two of the old findResource/findResourceSmall function - contraty to those, this approach is thread safe
svn-id: r8650
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/object.cpp | 41 | ||||
-rw-r--r-- | scumm/resource.cpp | 114 | ||||
-rw-r--r-- | scumm/resource.h | 13 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 9 |
4 files changed, 80 insertions, 97 deletions
diff --git a/scumm/object.cpp b/scumm/object.cpp index 4ae64274b0..2c285b12e7 100644 --- a/scumm/object.cpp +++ b/scumm/object.cpp @@ -533,10 +533,11 @@ void Scumm::loadRoomObjects() { assert(searchptr); // Load in new room objects + ResourceIterator obcds(searchptr, false); for (i = 0; i < _numObjectsInRoom; i++) { od = &_objs[findLocalObjectSlot()]; - ptr = findResource(MKID('OBCD'), searchptr); + ptr = obcds.findNext(MKID('OBCD')); if (ptr == NULL) error("Room %d missing object code block(s)", _roomResource); @@ -553,16 +554,16 @@ void Scumm::loadRoomObjects() { if (_dumpScripts) { char buf[32]; sprintf(buf, "roomobj-%d-", _roomResource); - ptr = findResource(MKID('VERB'), ptr, 0); + ptr = findResource(MKID('VERB'), ptr); dumpResource(buf, od->obj_nr, ptr); } - searchptr = NULL; } searchptr = room; + ResourceIterator obims(room, false); for (i = 0; i < _numObjectsInRoom; i++) { - ptr = findResource(MKID('OBIM'), searchptr); + ptr = obims.findNext(MKID('OBIM')); if (ptr == NULL) error("Room %d missing image blocks(s)", _roomResource); @@ -580,7 +581,6 @@ void Scumm::loadRoomObjects() { if (_objs[j].obj_nr == obim_id) _objs[j].OBIMoffset = ptr - room; } - searchptr = NULL; } for (i = 1; i < _numLocalObjects; i++) { @@ -636,7 +636,7 @@ void Scumm::loadRoomObjectsSmall() { ObjectData *od; const byte *ptr; uint16 obim_id; - const byte *room, *searchptr; + const byte *room; const RoomHeader *roomhdr; CHECK_HEAP @@ -651,11 +651,11 @@ void Scumm::loadRoomObjectsSmall() { if (_numObjectsInRoom > _numLocalObjects) error("More than %d objects in room %d", _numLocalObjects, _roomResource); - searchptr = room; + ResourceIterator obcds(room, true); for (i = 0; i < _numObjectsInRoom; i++) { od = &_objs[findLocalObjectSlot()]; - ptr = findResourceSmall(MKID('OBCD'), searchptr); + ptr = obcds.findNext(MKID('OBCD')); if (ptr == NULL) error("Room %d missing object code block(s)", _roomResource); @@ -666,13 +666,11 @@ void Scumm::loadRoomObjectsSmall() { sprintf(buf, "roomobj-%d-", _roomResource); dumpResource(buf, od->obj_nr, ptr); } - - searchptr = NULL; } - searchptr = room; + ResourceIterator obims(room, true); for (i = 0; i < _numObjectsInRoom; i++) { - ptr = findResourceSmall(MKID('OBIM'), searchptr); + ptr = obims.findNext(MKID('OBIM')); if (ptr == NULL) error("Room %d missing image blocks(s)", _roomResource); @@ -682,7 +680,6 @@ void Scumm::loadRoomObjectsSmall() { if (_objs[j].obj_nr == obim_id) _objs[j].OBIMoffset = ptr - room; } - searchptr = NULL; } for (i = 1; i < _numLocalObjects; i++) { @@ -1090,11 +1087,9 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint else searchptr = roomptr; assert(searchptr); + ResourceIterator obcds(searchptr, _features & GF_SMALL_HEADER); for (i = 0;;) { - if (_features & GF_SMALL_HEADER) - obcdptr = findResourceSmall(MKID('OBCD'), searchptr); - else - obcdptr = findResource(MKID('OBCD'), searchptr); + obcdptr = obcds.findNext(MKID('OBCD')); if (obcdptr == NULL) error("findObjectInRoom: Not enough code blocks in room %d", room); cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), obcdptr); @@ -1115,19 +1110,14 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint } if (++i == numobj) error("findObjectInRoom: Object %d not found in room %d", id, room); - searchptr = NULL; } } roomptr = fo->roomptr; if (findWhat & foImageHeader) { - searchptr = roomptr; - assert(searchptr); + ResourceIterator obims(roomptr, _features & GF_SMALL_HEADER); for (i = 0;;) { - if (_features & GF_SMALL_HEADER) - obimptr = findResourceSmall(MKID('OBIM'), searchptr); - else - obimptr = findResource(MKID('OBIM'), searchptr); + obimptr = obims.findNext(MKID('OBIM')); if (obimptr == NULL) error("findObjectInRoom: Not enough image blocks in room %d", room); imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obimptr); @@ -1149,7 +1139,6 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint } if (++i == numobj) error("findObjectInRoom: Object %d image not found in room %d", id, room); - searchptr = NULL; } } } @@ -1640,7 +1629,7 @@ void Scumm::loadFlObject(uint object, uint room) { char buf[32]; const byte *ptr = foir.obcd; sprintf(buf, "roomobj-%d-", room); - ptr = findResource(MKID('VERB'), ptr, 0); + ptr = findResource(MKID('VERB'), ptr); dumpResource(buf, object, ptr); } diff --git a/scumm/resource.cpp b/scumm/resource.cpp index 8cd61c5166..3e3ed7b522 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -1349,9 +1349,9 @@ const byte *Scumm::findResourceData(uint32 tag, const byte *ptr) { if (_features & GF_OLD_BUNDLE) error("findResourceData must not be used in GF_OLD_BUNDLE games"); else if (_features & GF_SMALL_HEADER) - ptr = findResourceSmall(tag, ptr, 0); + ptr = findResourceSmall(tag, ptr); else - ptr = findResource(tag, ptr, 0); + ptr = findResource(tag, ptr); if (ptr == NULL) return NULL; @@ -1370,72 +1370,58 @@ int Scumm::getResourceDataSize(const byte *ptr) const { return READ_BE_UINT32(ptr - 4) - 8; } -struct FindResourceState { - uint32 size, pos; - const byte *ptr; -}; - -/* just O(N) complexity when iterating with this function */ -const byte *findResource(uint32 tag, const byte *searchin) { - uint32 size; - static FindResourceState frs; - FindResourceState *f = &frs; /* easier to make it thread safe like this */ - - if (searchin) { - f->size = READ_BE_UINT32(searchin + 4); - f->pos = 8; - f->ptr = searchin + 8; - goto StartScan; +ResourceIterator::ResourceIterator(const byte *searchin, bool smallHeader) + : _ptr(searchin), _smallHeader(smallHeader) { + assert(searchin); + if (_smallHeader) { + _size = READ_LE_UINT32(searchin); + _pos = 6; + _ptr = searchin + 6; + } else { + _size = READ_BE_UINT32(searchin + 4); + _pos = 8; + _ptr = searchin + 8; } - - do { - size = READ_BE_UINT32(f->ptr + 4); - if ((int32)size <= 0) - return NULL; - - f->pos += size; - f->ptr += size; - - StartScan: - if (f->pos >= f->size) - return NULL; - } while (READ_UINT32(f->ptr) != tag); - - return f->ptr; + } -const byte *findResourceSmall(uint32 tag, const byte *searchin) { - uint32 size; - static FindResourceState frs; - FindResourceState *f = &frs; /* easier to make it thread safe like this */ - uint16 smallTag; - - smallTag = newTag2Old(tag); - - if (searchin) { - f->size = READ_LE_UINT32(searchin); - f->pos = 6; - f->ptr = searchin + 6; - goto StartScan; +const byte *ResourceIterator::findNext(uint32 tag) { + uint32 size = 0; + const byte *result = 0; + + if (_smallHeader) { + uint16 smallTag = newTag2Old(tag); + do { + if (_pos >= _size) + return 0; + + result = _ptr; + size = READ_LE_UINT32(result); + if ((int32)size <= 0) + return 0; // Avoid endless loop + + _pos += size; + _ptr += size; + } while (READ_LE_UINT16(result + 4) != smallTag); + } else { + do { + if (_pos >= _size) + return 0; + + result = _ptr; + size = READ_BE_UINT32(result + 4); + if ((int32)size <= 0) + return 0; // Avoid endless loop + + _pos += size; + _ptr += size; + } while (READ_UINT32(result) != tag); } - do { - size = READ_LE_UINT32(f->ptr); - if ((int32)size <= 0) - return NULL; - - f->pos += size; - f->ptr += size; - - StartScan: - if (f->pos >= f->size) - return NULL; - } while (READ_LE_UINT16(f->ptr + 4) != smallTag); - - return f->ptr; + return result; } -const byte *findResource(uint32 tag, const byte *searchin, int idx) { +const byte *findResource(uint32 tag, const byte *searchin) { uint32 curpos, totalsize, size; assert(searchin); @@ -1446,7 +1432,7 @@ const byte *findResource(uint32 tag, const byte *searchin, int idx) { searchin += 4; while (curpos < totalsize) { - if (READ_UINT32(searchin) == tag && !idx--) + if (READ_UINT32(searchin) == tag) return searchin; size = READ_BE_UINT32(searchin + 4); @@ -1463,7 +1449,7 @@ const byte *findResource(uint32 tag, const byte *searchin, int idx) { return NULL; } -const byte *findResourceSmall(uint32 tag, const byte *searchin, int idx) { +const byte *findResourceSmall(uint32 tag, const byte *searchin) { uint32 curpos, totalsize, size; uint16 smallTag; @@ -1478,7 +1464,7 @@ const byte *findResourceSmall(uint32 tag, const byte *searchin, int idx) { while (curpos < totalsize) { size = READ_LE_UINT32(searchin); - if (READ_LE_UINT16(searchin + 4) == smallTag && !idx--) + if (READ_LE_UINT16(searchin + 4) == smallTag) return searchin; if ((int32)size <= 0) { diff --git a/scumm/resource.h b/scumm/resource.h index a3be6a74a3..d89c5266cf 100644 --- a/scumm/resource.h +++ b/scumm/resource.h @@ -50,9 +50,18 @@ enum { }; -const byte *findResource(uint32 tag, const byte *searchin, int index); -const byte *findResourceSmall(uint32 tag, const byte *searchin, int index); const byte *findResource(uint32 tag, const byte *searchin); const byte *findResourceSmall(uint32 tag, const byte *searchin); +class ResourceIterator { + uint32 _size; + uint32 _pos; + const byte *_ptr; + bool _smallHeader; +public: + ResourceIterator(const byte *searchin, bool smallHeader); + const byte *findNext(uint32 tag); +}; + + #endif diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index d25cb0f24f..d5d1a9746f 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -1662,7 +1662,8 @@ void Scumm::initRoomSubBlocks() { } } } else if (_features & GF_SMALL_HEADER) { - while ((ptr = findResourceSmall(MKID('LSCR'), searchptr)) != NULL) { + ResourceIterator localScriptIterator(searchptr, true); + while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ id = ptr[0]; @@ -1674,10 +1675,10 @@ void Scumm::initRoomSubBlocks() { } _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr; - searchptr = NULL; } } else { - while ((ptr = findResource(MKID('LSCR'), searchptr)) != NULL) { + ResourceIterator localScriptIterator(searchptr, false); + while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ @@ -1700,8 +1701,6 @@ void Scumm::initRoomSubBlocks() { sprintf(buf, "room-%d-", _roomResource); dumpResource(buf, id, ptr - _resourceHeaderSize); } - - searchptr = NULL; } } |